Merging default.

--HG--
branch : gsoc2013-dfighter
hg/feature/gsoc2013-dfighter
dfighter1985 11 years ago
commit 2ca40f10eb

@ -146,7 +146,10 @@ external_stlport
.svn .svn
thumbs.db thumbs.db
Thumbs.db Thumbs.db
.Sync* *.tpl.php
.SyncID
.SyncIgnore
.SyncArchive
# build # build
code/nel/build/* code/nel/build/*
@ -157,6 +160,7 @@ code/build/*
code/build-2010/* code/build-2010/*
build/* build/*
install/* install/*
code/nel/tools/build_gamedata/configuration/buildsite.py
# Linux nel compile # Linux nel compile
code/nel/build/nel-config code/nel/build/nel-config
@ -199,6 +203,16 @@ code/nel/tools/pacs/build_rbank/build_rbank
code/ryzom/common/data_leveldesign/leveldesign/game_element/xp_table/skills.skill_tree code/ryzom/common/data_leveldesign/leveldesign/game_element/xp_table/skills.skill_tree
code/ryzom/common/data_leveldesign/leveldesign/game_element/xp_table/xptable.xp_table code/ryzom/common/data_leveldesign/leveldesign/game_element/xp_table/xptable.xp_table
code/ryzom/tools/server/sql/ryzom_admin_default_data.sql code/ryzom/tools/server/sql/ryzom_admin_default_data.sql
code/ryzom/tools/server/ryzom_ams/drupal
code/ryzom/tools/server/ryzom_ams/drupal_module/ryzommanage/ams_lib/autoload
code/ryzom/tools/server/ryzom_ams/drupal_module/ryzommanage/ams_lib/configs
code/ryzom/tools/server/ryzom_ams/drupal_module/ryzommanage/ams_lib/cron
code/ryzom/tools/server/ryzom_ams/drupal_module/ryzommanage/ams_lib/img
code/ryzom/tools/server/ryzom_ams/drupal_module/ryzommanage/ams_lib/plugins
code/ryzom/tools/server/ryzom_ams/drupal_module/ryzommanage/ams_lib/smarty
code/ryzom/tools/server/ryzom_ams/drupal_module/ryzommanage/ams_lib/translations
code/ryzom/tools/server/ryzom_ams/drupal_module/ryzommanage/ams_lib/libinclude.php
code/ryzom/tools/server/ryzom_ams/www/html/templates_c
# Linux server compile # Linux server compile
code/ryzom/server/src/entities_game_service/entities_game_service code/ryzom/server/src/entities_game_service/entities_game_service
@ -212,3 +226,22 @@ code/ryzom/server/src/ryzom_welcome_service/ryzom_welcome_service
code/ryzom/server/src/tick_service/tick_service code/ryzom/server/src/tick_service/tick_service
# WebTT temp dir # WebTT temp dir
code/ryzom/tools/server/www/webtt/app/tmp code/ryzom/tools/server/www/webtt/app/tmp
code\ryzom\tools\server\ryzom_ams\old
# AMS ignore
code/ryzom/tools/server/ryzom_ams/www/config.php
code/ryzom/tools/server/ryzom_ams/www/is_installed
#tools and external dir's
external
external_stlport
nel_tools*
ryzom_tools*
#Dumps
*.dmp
code/nel/tools/build_gamedata/processes/ai_wmap/ai_build_wmap.cfg
code/nel/tools/build_gamedata/processes/sheets/sheets_packer.cfg
code/nel/tools/build_gamedata/processes/rbank/build_rbank.cfg
code/nel/tools/build_gamedata/processes/zone/debug_zone_dependencies.cfg

@ -41,10 +41,8 @@ INCLUDE(${CMAKE_ROOT}/Modules/Documentation.cmake OPTIONAL)
# Force out of source builds. # Force out of source builds.
CHECK_OUT_OF_SOURCE() CHECK_OUT_OF_SOURCE()
# Specify Mac OS X deployment target before including Darwin.cmake # To be able to specify a different deployment target on Mac OS X :
IF(NOT CMAKE_OSX_DEPLOYMENT_TARGET) # export MACOSX_DEPLOYMENT_TARGET=10.6
SET(CMAKE_OSX_DEPLOYMENT_TARGET "10.6")
ENDIF(NOT CMAKE_OSX_DEPLOYMENT_TARGET)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6) CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(RyzomCore CXX C) PROJECT(RyzomCore CXX C)

@ -8,14 +8,11 @@ IF(CustomMFC_FIND_REQUIRED)
SET(MFC_FIND_REQUIRED TRUE) SET(MFC_FIND_REQUIRED TRUE)
ENDIF(CustomMFC_FIND_REQUIRED) ENDIF(CustomMFC_FIND_REQUIRED)
# Try to find MFC using official module, MFC_FOUND is set
FIND_PACKAGE(MFC)
IF(NOT MFC_DIR) IF(NOT MFC_DIR)
# If MFC have been found, remember their directory # If MFC have been found, remember their directory
IF(MFC_FOUND AND VC_DIR) IF(VC_DIR)
SET(MFC_STANDARD_DIR "${VC_DIR}/atlmfc") SET(MFC_STANDARD_DIR "${VC_DIR}/atlmfc")
ENDIF(MFC_FOUND AND VC_DIR) ENDIF(VC_DIR)
FIND_PATH(MFC_DIR FIND_PATH(MFC_DIR
include/afxwin.h include/afxwin.h
@ -45,6 +42,9 @@ IF(MFC_FOUND)
# Set definitions for using MFC in DLL # Set definitions for using MFC in DLL
SET(MFC_DEFINITIONS -D_AFXDLL) SET(MFC_DEFINITIONS -D_AFXDLL)
# Set CMake flag to use MFC DLL
SET(CMAKE_MFC_FLAG 2)
ENDIF(MFC_FOUND) ENDIF(MFC_FOUND)
# TODO: create a macro which set MFC_DEFINITIONS, MFC_LIBRARY_DIR and MFC_INCLUDE_DIR for a project # TODO: create a macro which set MFC_DEFINITIONS, MFC_LIBRARY_DIR and MFC_INCLUDE_DIR for a project

@ -19,9 +19,13 @@ FIND_PATH(FREETYPE_INCLUDE_DIRS
/opt/local/include /opt/local/include
/opt/csw/include /opt/csw/include
/opt/include /opt/include
PATH_SUFFIXES freetype freetype2 PATH_SUFFIXES freetype2
) )
IF(NOT FREETYPE_INCLUDE_DIRS)
SET(FREETYPE_INCLUDE_DIRS "")
ENDIF(NOT FREETYPE_INCLUDE_DIRS)
# ft2build.h does not reside in the freetype include dir # ft2build.h does not reside in the freetype include dir
FIND_PATH(FREETYPE_ADDITIONAL_INCLUDE_DIR FIND_PATH(FREETYPE_ADDITIONAL_INCLUDE_DIR
ft2build.h ft2build.h
@ -32,6 +36,7 @@ FIND_PATH(FREETYPE_ADDITIONAL_INCLUDE_DIR
/opt/local/include /opt/local/include
/opt/csw/include /opt/csw/include
/opt/include /opt/include
PATH_SUFFIXES freetype2
) )
# combine both include directories into one variable # combine both include directories into one variable

@ -49,7 +49,11 @@
FIND_PROGRAM(Mercurial_HG_EXECUTABLE hg FIND_PROGRAM(Mercurial_HG_EXECUTABLE hg
DOC "mercurial command line client" DOC "mercurial command line client"
HINTS /opt/local/bin) PATHS
/opt/local/bin
"C:/Program Files/TortoiseHg"
"C:/Program Files (x86)/TortoiseHg"
)
MARK_AS_ADVANCED(Mercurial_HG_EXECUTABLE) MARK_AS_ADVANCED(Mercurial_HG_EXECUTABLE)
IF(Mercurial_HG_EXECUTABLE) IF(Mercurial_HG_EXECUTABLE)

@ -71,11 +71,14 @@ SET(WINSDKENV_DIR $ENV{WINSDK_DIR})
MACRO(FIND_WINSDK_VERSION_HEADERS) MACRO(FIND_WINSDK_VERSION_HEADERS)
IF(WINSDK_DIR AND NOT WINSDK_VERSION) IF(WINSDK_DIR AND NOT WINSDK_VERSION)
# Search version in headers # Search version in headers
IF(EXISTS ${WINSDK_DIR}/include/Msi.h) FIND_FILE(_MSI_FILE Msi.h
SET(_MSI_FILE ${WINSDK_DIR}/include/Msi.h) PATHS
ENDIF(EXISTS ${WINSDK_DIR}/include/Msi.h) ${WINSDK_DIR}/Include/um
${WINSDK_DIR}/Include
)
IF(_MSI_FILE) IF(_MSI_FILE)
# Look for Windows SDK 8.0 # Look for Windows SDK 8.0
FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WIN8") FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WIN8")
@ -88,11 +91,11 @@ MACRO(FIND_WINSDK_VERSION_HEADERS)
FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WIN7") FILE(STRINGS ${_MSI_FILE} _CONTENT REGEX "^#ifndef NTDDI_WIN7")
IF(_CONTENT) IF(_CONTENT)
IF(EXISTS ${WINSDK_DIR}/include/winsdkver.h) FIND_FILE(_WINSDKVER_FILE winsdkver.h WinSDKVer.h
SET(_WINSDKVER_FILE ${WINSDK_DIR}/include/winsdkver.h) PATHS
ELSEIF(EXISTS ${WINSDK_DIR}/include/WinSDKVer.h) ${WINSDK_DIR}/Include/um
SET(_WINSDKVER_FILE ${WINSDK_DIR}/include/WinSDKVer.h) ${WINSDK_DIR}/Include
ENDIF(EXISTS ${WINSDK_DIR}/include/winsdkver.h) )
IF(_WINSDKVER_FILE) IF(_WINSDKVER_FILE)
# Load WinSDKVer.h content # Load WinSDKVer.h content
@ -162,9 +165,13 @@ MACRO(USE_CURRENT_WINSDK)
SET(WINSDK_VERSION_FULL "") SET(WINSDK_VERSION_FULL "")
# Use WINSDK environment variable # Use WINSDK environment variable
IF(WINSDKENV_DIR AND EXISTS ${WINSDKENV_DIR}/include/Windows.h) IF(WINSDKENV_DIR)
SET(WINSDK_DIR ${WINSDKENV_DIR}) FIND_PATH(WINSDK_DIR Windows.h
ENDIF(WINSDKENV_DIR AND EXISTS ${WINSDKENV_DIR}/include/Windows.h) HINTS
${WINSDKENV_DIR}/Include/um
${WINSDKENV_DIR}/Include
)
ENDIF(WINSDKENV_DIR)
# Use INCLUDE environment variable # Use INCLUDE environment variable
IF(NOT WINSDK_DIR AND WINSDKCURRENT_VERSION_INCLUDE) IF(NOT WINSDK_DIR AND WINSDKCURRENT_VERSION_INCLUDE)
@ -173,8 +180,8 @@ MACRO(USE_CURRENT_WINSDK)
# Look for Windows.h because there are several paths # Look for Windows.h because there are several paths
IF(EXISTS ${_INCLUDE}/Windows.h) IF(EXISTS ${_INCLUDE}/Windows.h)
STRING(REGEX REPLACE "/(include|INCLUDE|Include)" "" WINSDK_DIR ${_INCLUDE}) STRING(REGEX REPLACE "/(include|INCLUDE|Include)(.*)" "" WINSDK_DIR ${_INCLUDE})
MESSAGE(STATUS "Found Windows SDK environment variable in ${WINSDK_DIR}") MESSAGE(STATUS "Found Windows SDK from include environment variable in ${WINSDK_DIR}")
BREAK() BREAK()
ENDIF(EXISTS ${_INCLUDE}/Windows.h) ENDIF(EXISTS ${_INCLUDE}/Windows.h)
ENDFOREACH(_INCLUDE) ENDFOREACH(_INCLUDE)

@ -244,6 +244,8 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS)
OPTION(WITH_COVERAGE "With Code Coverage Support" OFF) OPTION(WITH_COVERAGE "With Code Coverage Support" OFF)
OPTION(WITH_PCH "With Precompiled Headers" ON ) OPTION(WITH_PCH "With Precompiled Headers" ON )
OPTION(FINAL_VERSION "Build in Final Version mode" ON ) OPTION(FINAL_VERSION "Build in Final Version mode" ON )
OPTION(WITH_PERFHUD "Build with NVIDIA PerfHUD support" OFF )
OPTION(WITH_PATCH_SUPPORT "Build with in-game Patch Support" OFF )
# Default to static building on Windows. # Default to static building on Windows.
IF(WIN32) IF(WIN32)
@ -604,7 +606,7 @@ MACRO(NL_SETUP_BUILD)
SET(NL_DEBUG_CFLAGS "/Zi /MDd /RTC1 /D_DEBUG ${DEBUG_CFLAGS} ${NL_DEBUG_CFLAGS}") SET(NL_DEBUG_CFLAGS "/Zi /MDd /RTC1 /D_DEBUG ${DEBUG_CFLAGS} ${NL_DEBUG_CFLAGS}")
SET(NL_RELEASE_CFLAGS "/MD /DNDEBUG ${RELEASE_CFLAGS} ${NL_RELEASE_CFLAGS}") SET(NL_RELEASE_CFLAGS "/MD /DNDEBUG ${RELEASE_CFLAGS} ${NL_RELEASE_CFLAGS}")
SET(NL_DEBUG_LINKFLAGS "/DEBUG /OPT:NOREF /OPT:NOICF /NODEFAULTLIB:msvcrt /INCREMENTAL:YES ${NL_DEBUG_LINKFLAGS}") SET(NL_DEBUG_LINKFLAGS "/DEBUG /OPT:NOREF /OPT:NOICF /NODEFAULTLIB:msvcrt ${MSVC_INCREMENTAL_YES_FLAG} ${NL_DEBUG_LINKFLAGS}")
SET(NL_RELEASE_LINKFLAGS "/OPT:REF /OPT:ICF /INCREMENTAL:NO ${NL_RELEASE_LINKFLAGS}") SET(NL_RELEASE_LINKFLAGS "/OPT:REF /OPT:ICF /INCREMENTAL:NO ${NL_RELEASE_LINKFLAGS}")
IF(WITH_WARNINGS) IF(WITH_WARNINGS)
@ -795,16 +797,15 @@ MACRO(NL_SETUP_BUILD)
ADD_PLATFORM_FLAGS("${XARCH}-isysroot${CMAKE_IOS_SIMULATOR_SYSROOT}") ADD_PLATFORM_FLAGS("${XARCH}-isysroot${CMAKE_IOS_SIMULATOR_SYSROOT}")
ADD_PLATFORM_FLAGS("${XARCH}-mios-simulator-version-min=${IOS_VERSION}") ADD_PLATFORM_FLAGS("${XARCH}-mios-simulator-version-min=${IOS_VERSION}")
IF(CMAKE_OSX_DEPLOYMENT_TARGET)
SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} ${XARCH}-Wl,-macosx_version_min,${CMAKE_OSX_DEPLOYMENT_TARGET}") SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} ${XARCH}-Wl,-macosx_version_min,${CMAKE_OSX_DEPLOYMENT_TARGET}")
ENDIF(CMAKE_OSX_DEPLOYMENT_TARGET)
ENDIF(CMAKE_IOS_SIMULATOR_SYSROOT AND TARGET_X86) ENDIF(CMAKE_IOS_SIMULATOR_SYSROOT AND TARGET_X86)
ELSE(IOS) ELSE(IOS)
IF(CMAKE_OSX_SYSROOT)
ADD_PLATFORM_FLAGS("-isysroot ${CMAKE_OSX_SYSROOT}")
ENDIF(CMAKE_OSX_SYSROOT)
# Always force -mmacosx-version-min to override environement variable # Always force -mmacosx-version-min to override environement variable
ADD_PLATFORM_FLAGS("-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") IF(CMAKE_OSX_DEPLOYMENT_TARGET)
SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Wl,-macosx_version_min,${CMAKE_OSX_DEPLOYMENT_TARGET}") SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Wl,-macosx_version_min,${CMAKE_OSX_DEPLOYMENT_TARGET}")
ENDIF(CMAKE_OSX_DEPLOYMENT_TARGET)
ENDIF(IOS) ENDIF(IOS)
SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Wl,-headerpad_max_install_names") SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Wl,-headerpad_max_install_names")

@ -12,7 +12,7 @@ each other so you can use only the parts you really need in your project.
If you want know more about the library content and functionalities, you If you want know more about the library content and functionalities, you
should take a look on the documents present in the doc directory. should take a look on the documents present in the doc directory.
Ryzom Core is currently developped and tested under GNU/Linux and Windows Ryzom Core is currently developed and tested under GNU/Linux and Windows
environments. environments.
@ -29,4 +29,7 @@ file for for more details on license terms and other legal issues.
Installation Installation
------------ ------------
Please visit http://dev.ryzom.com for more information. Please visit https://ryzomcore.atlassian.net/wiki/display/RC/Ryzom+Core+Home for more information.
In particular the Getting Started section on the right side of the webpage includes build
instructions for Windows, Linux and Mac.

@ -128,7 +128,7 @@ inline uint32 CPSAttribMakerBinOp<uint32>::getMinValue(void) const
{ {
uint32 lhs = _Arg[0]->getMinValue(); uint32 lhs = _Arg[0]->getMinValue();
uint32 rhs = _Arg[1]->getMaxValue(); uint32 rhs = _Arg[1]->getMaxValue();
return lhs > rhs ? 0 : lhs - rhs; return rhs > lhs ? 0 : lhs - rhs;
} }
break; break;
default: default:
@ -153,7 +153,7 @@ inline uint32 CPSAttribMakerBinOp<uint32>::getMaxValue(void) const
{ {
uint32 lhs = _Arg[0]->getMaxValue(); uint32 lhs = _Arg[0]->getMaxValue();
uint32 rhs = _Arg[1]->getMinValue(); uint32 rhs = _Arg[1]->getMinValue();
return lhs > rhs ? 0 : lhs - rhs; return rhs > lhs ? 0 : lhs - rhs;
} }
break; break;
default: default:

@ -77,6 +77,7 @@ public:
std::string Manufacturer; std::string Manufacturer;
std::string ProductName; std::string ProductName;
std::string Serial; // A unique device identifier std::string Serial; // A unique device identifier
bool AllowAuto; // Allow this device to be automatically selected when no device is configured
}; };
/** /**

@ -466,6 +466,7 @@ private:
uint _NumberOfPatchComputed; uint _NumberOfPatchComputed;
uint _ProcessCount; uint _ProcessCount;
uint64 _CPUMask; uint64 _CPUMask;
NLMISC::CMutex _ProcessExitedMutex;
volatile uint _ProcessExited; volatile uint _ProcessExited;
// *** Bitmap sharing // *** Bitmap sharing

@ -44,7 +44,7 @@ public:
UFormElm& getRootNode (); UFormElm& getRootNode ();
const UFormElm& getRootNode () const; const UFormElm& getRootNode () const;
const std::string &getComment () const; const std::string &getComment () const;
void write (class NLMISC::IStream &stream, bool georges4CVS); void write (class NLMISC::IStream &stream);
void getDependencies (std::set<std::string> &dependencies) const; void getDependencies (std::set<std::string> &dependencies) const;
uint getNumParent () const; uint getNumParent () const;
UForm *getParentForm (uint parent) const; UForm *getParentForm (uint parent) const;
@ -73,7 +73,7 @@ public:
// ** IO functions // ** IO functions
// Set the filename before saving the form // Set the filename before saving the form
void write (xmlDocPtr doc, const char *filename, bool georges4CVS); void write (xmlDocPtr doc, const char *filename);
// ** Parent access // ** Parent access

@ -161,7 +161,7 @@ public:
}; };
// ** IO functions // ** IO functions
void write (xmlDocPtr root, const char *filename, bool georges4CVS); void write (xmlDocPtr root, const char *filename);
// Count parent DFN // Count parent DFN
uint countParentDfn (uint32 round=0) const; uint countParentDfn (uint32 round=0) const;

@ -54,9 +54,6 @@ public:
/// State of the form /// State of the form
TState State; TState State;
/// CVS Revision string
std::string Revision;
/// Comments of the form /// Comments of the form
std::string Comments; std::string Comments;
@ -65,7 +62,7 @@ public:
/// ** IO functions /// ** IO functions
void read (xmlNodePtr root); void read (xmlNodePtr root);
void write (xmlNodePtr node, bool georges4CVS) const; void write (xmlNodePtr node) const;
// Get state string // Get state string
static const char *getStateString (TState state); static const char *getStateString (TState state);

@ -55,7 +55,7 @@ public:
static bool uiCompatible (TType type, TUI ui); static bool uiCompatible (TType type, TUI ui);
// ** IO functions // ** IO functions
void write (xmlDocPtr doc, bool georges4CVS) const; void write (xmlDocPtr doc) const;
// Header // Header
CFileHeader Header; CFileHeader Header;

@ -53,9 +53,8 @@ public:
/** Write the form in a stream. /** Write the form in a stream.
* *
* \param stream is the stream used to write the form * \param stream is the stream used to write the form
* \param georges4CVS should be true if you use Georges with CVS false else
*/ */
virtual void write (NLMISC::IStream &stream, bool georges4CVS) = 0; virtual void write (NLMISC::IStream &stream) = 0;
/** /**
* Access form parents * Access form parents

@ -74,7 +74,7 @@ namespace NLGUI
REFLECT_SINT32("rollover_container_alpha", getRolloverAlphaContainerAsSInt32, setRolloverAlphaContainer); REFLECT_SINT32("rollover_container_alpha", getRolloverAlphaContainerAsSInt32, setRolloverAlphaContainer);
REFLECT_BOOL("use_global_alpha_settings", isUsingGlobalAlpha, setUseGlobalAlpha); REFLECT_BOOL("use_global_alpha_settings", isUsingGlobalAlpha, setUseGlobalAlpha);
REFLECT_STRING("on_alpha_settings_changed", getAHOnAlphaSettingsChanged, setAHOnAlphaSettingsChanged); REFLECT_STRING("on_alpha_settings_changed", getAHOnAlphaSettingsChanged, setAHOnAlphaSettingsChanged);
REFLECT_STRING("on_alpha_settings_changed_aparams", getAHOnAlphaSettingsChangedParams, setAHOnAlphaSettingsChangedParams); REFLECT_STRING("on_alpha_settings_changed_params", getAHOnAlphaSettingsChangedParams, setAHOnAlphaSettingsChangedParams);
REFLECT_EXPORT_END REFLECT_EXPORT_END
virtual bool isMoving() const{ return false; } virtual bool isMoving() const{ return false; }

@ -586,7 +586,7 @@ template<class T, class U> inline T type_cast(U o)
#ifdef NL_ISO_CPP0X_AVAILABLE #ifdef NL_ISO_CPP0X_AVAILABLE
# define nlctassert(cond) static_assert(cond, "Compile time assert in "#cond) # define nlctassert(cond) static_assert(cond, "Compile time assert in "#cond)
#else #else
# define nlctassert(cond) sizeof(uint[(cond) ? 1 : 0]) # define nlctassert(cond) (void)sizeof(uint[(cond) ? 1 : 0])
#endif #endif
/** /**

@ -90,6 +90,7 @@
# if defined(_HAS_TR1) && (_HAS_TR1 + 0) // VC9 TR1 feature pack or later # if defined(_HAS_TR1) && (_HAS_TR1 + 0) // VC9 TR1 feature pack or later
# define NL_ISO_STDTR1_AVAILABLE # define NL_ISO_STDTR1_AVAILABLE
# define NL_ISO_STDTR1_HEADER(header) <header> # define NL_ISO_STDTR1_HEADER(header) <header>
# define NL_ISO_STDTR1_NAMESPACE std::tr1
# endif # endif
# ifdef _DEBUG # ifdef _DEBUG
# define NL_DEBUG # define NL_DEBUG
@ -153,8 +154,16 @@
#ifdef NL_COMP_GCC #ifdef NL_COMP_GCC
# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) # define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
# if GCC_VERSION > 40100 # if GCC_VERSION > 40100
// new libc++ bundled with clang under Mac OS X 10.9+ doesn't define __GLIBCXX__
# ifdef __GLIBCXX__
# define NL_ISO_STDTR1_AVAILABLE # define NL_ISO_STDTR1_AVAILABLE
# define NL_ISO_STDTR1_HEADER(header) <tr1/header> # define NL_ISO_STDTR1_HEADER(header) <tr1/header>
# define NL_ISO_STDTR1_NAMESPACE std::tr1
# else
# define NL_ISO_STDTR1_AVAILABLE
# define NL_ISO_STDTR1_HEADER(header) <header>
# define NL_ISO_STDTR1_NAMESPACE std
# endif
# endif # endif
#endif #endif
@ -331,9 +340,9 @@ typedef unsigned int uint; // at least 32bits (depend of processor)
#elif defined(NL_ISO_STDTR1_AVAILABLE) // use std::tr1 for CHash* classes, if available (gcc 4.1+ and VC9 with TR1 feature pack) #elif defined(NL_ISO_STDTR1_AVAILABLE) // use std::tr1 for CHash* classes, if available (gcc 4.1+ and VC9 with TR1 feature pack)
# include NL_ISO_STDTR1_HEADER(unordered_map) # include NL_ISO_STDTR1_HEADER(unordered_map)
# include NL_ISO_STDTR1_HEADER(unordered_set) # include NL_ISO_STDTR1_HEADER(unordered_set)
# define CHashMap std::tr1::unordered_map # define CHashMap NL_ISO_STDTR1_NAMESPACE::unordered_map
# define CHashSet std::tr1::unordered_set # define CHashSet NL_ISO_STDTR1_NAMESPACE::unordered_set
# define CHashMultiMap std::tr1::unordered_multimap # define CHashMultiMap NL_ISO_STDTR1_NAMESPACE::unordered_multimap
#elif defined(NL_COMP_VC) && (NL_COMP_VC_VERSION >= 70 && NL_COMP_VC_VERSION <= 90) // VC7 through 9 #elif defined(NL_COMP_VC) && (NL_COMP_VC_VERSION >= 70 && NL_COMP_VC_VERSION <= 90) // VC7 through 9
# include <hash_map> # include <hash_map>
# include <hash_set> # include <hash_set>

@ -316,14 +316,14 @@ public:
// output the oldest part of the buffer first // output the oldest part of the buffer first
for (uint i=_Mean.getCurrentFrame(); i<_Mean.getNumFrame(); ++i) for (uint i=_Mean.getCurrentFrame(); i<_Mean.getNumFrame(); ++i)
{ {
str << _Mean.getLastFrames()[i]; str << (T)_Mean.getLastFrames()[i];
if (i < _Mean.getNumFrame()-1 || _Mean.getCurrentFrame() != 0) if (i < _Mean.getNumFrame()-1 || _Mean.getCurrentFrame() != 0)
str << ","; str << ",";
} }
// then output the newest part // then output the newest part
for (uint i = 0; i < _Mean.getCurrentFrame(); i++) for (uint i = 0; i < _Mean.getCurrentFrame(); i++)
{ {
str << _Mean.getLastFrames()[i]; str << (T)_Mean.getLastFrames()[i];
if (i < _Mean.getCurrentFrame()-1) if (i < _Mean.getCurrentFrame()-1)
str << ","; str << ",";
} }

@ -289,7 +289,7 @@ int main(void)
// and finally save the form out in case we made changes. // and finally save the form out in case we made changes.
// if you're accessing a form read-only (not using set*) you can skip this. // if you're accessing a form read-only (not using set*) you can skip this.
NLMISC::COFile saveSample(sampleConfigFile); NLMISC::COFile saveSample(sampleConfigFile);
form->write(saveSample, false); form->write(saveSample);
nlinfo("Saved sample config file."); nlinfo("Saved sample config file.");
} else { } else {
// CPath didn't find the file, just print an error and exit. // CPath didn't find the file, just print an error and exit.

@ -1464,6 +1464,24 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r
return false; return false;
} }
#if WITH_PERFHUD
// Look for 'NVIDIA PerfHUD' adapter
// If it is present, override default settings
for (UINT gAdapter=0;gAdapter<_D3D->GetAdapterCount();gAdapter++)
{
D3DADAPTER_IDENTIFIER9 Identifier;
HRESULT Res;
Res = _D3D->GetAdapterIdentifier(gAdapter,0,&Identifier);
if (strstr(Identifier.Description,"PerfHUD") != 0)
{
nlinfo ("Setting up with PerfHUD");
adapter=gAdapter;
_Rasterizer=D3DDEVTYPE_REF;
break;
}
}
#endif WITH_PERFHUD
// Create the D3D device // Create the D3D device
HRESULT result = _D3D->CreateDevice (adapter, _Rasterizer, _HWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE, &parameters, &_DeviceInterface); HRESULT result = _D3D->CreateDevice (adapter, _Rasterizer, _HWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE, &parameters, &_DeviceInterface);
if (result != D3D_OK) if (result != D3D_OK)
@ -1487,6 +1505,8 @@ bool CDriverD3D::setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool r
} }
} }
// _D3D->CreateDevice (adapter, _Rasterizer, _HWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &parameters, &_DeviceInterface); // _D3D->CreateDevice (adapter, _Rasterizer, _HWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &parameters, &_DeviceInterface);
// Check some caps // Check some caps
@ -2635,6 +2655,7 @@ bool CDriverD3D::reset (const GfxMode& mode)
#ifndef NL_NO_ASM #ifndef NL_NO_ASM
CFpuRestorer fpuRestorer; // fpu control word is changed by "Reset" CFpuRestorer fpuRestorer; // fpu control word is changed by "Reset"
#endif #endif
if (_Rasterizer!=D3DDEVTYPE_REF) {
HRESULT hr = _DeviceInterface->Reset (&parameters); HRESULT hr = _DeviceInterface->Reset (&parameters);
if (hr != D3D_OK) if (hr != D3D_OK)
{ {
@ -2644,6 +2665,7 @@ bool CDriverD3D::reset (const GfxMode& mode)
return false; return false;
} }
} }
}
_Lost = false; _Lost = false;
// BeginScene now // BeginScene now

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -2191,6 +2191,7 @@ void CDriverGL::setSwapVBLInterval(uint interval)
res = nwglSwapIntervalEXT(_Interval) == TRUE; res = nwglSwapIntervalEXT(_Interval) == TRUE;
} }
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
[_ctx setValues:(GLint*)&interval forParameter:NSOpenGLCPSwapInterval];
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
if (_win && _Extensions.GLXEXTSwapControl) if (_win && _Extensions.GLXEXTSwapControl)
{ {
@ -2251,6 +2252,8 @@ void CDriverGL::enablePolygonSmoothing(bool smooth)
{ {
H_AUTO_OGL(CDriverGL_enablePolygonSmoothing); H_AUTO_OGL(CDriverGL_enablePolygonSmoothing);
if (_PolygonSmooth == smooth) return;
#ifndef USE_OPENGLES #ifndef USE_OPENGLES
if(smooth) if(smooth)
glEnable(GL_POLYGON_SMOOTH); glEnable(GL_POLYGON_SMOOTH);

@ -488,9 +488,9 @@ void CDriverGL::setUniformParams(TProgram program, CGPUProgramParams &params)
if (index == ~0) if (index == ~0)
{ {
const std::string &name = params.getNameByOffset(offset); const std::string &name = params.getNameByOffset(offset);
nlassert(!name.empty() /* missing both parameter name and index, code error /); nlassert(!name.empty()); // missing both parameter name and index, code error
uint index = prog->getUniformIndex(name.c_str()); uint index = prog->getUniformIndex(name.c_str());
nlassert(index != ~0 /* invalid parameter name /); nlassert(index != ~0); // invalid parameter name
params.map(index, name); params.map(index, name);
} }

@ -29,7 +29,8 @@ using namespace std;
#ifndef NL_DONT_USE_EXTERNAL_CODE #ifndef NL_DONT_USE_EXTERNAL_CODE
#include <freetype/freetype.h> #include <ft2build.h>
#include FT_FREETYPE_H
// for freetype 2.0 // for freetype 2.0
#ifdef FTERRORS_H #ifdef FTERRORS_H
@ -51,7 +52,7 @@ int err_code;
const char* err_msg; const char* err_msg;
} ft_errors[] = } ft_errors[] =
#include <freetype/fterrors.h> #include FT_ERRORS_H
using namespace NLMISC; using namespace NLMISC;

@ -791,17 +791,20 @@ void CMeshMultiLod::compileCoarseMeshes()
{ {
slotRef.CoarseTriangles.resize(slotRef.CoarseNumTris * 3); slotRef.CoarseTriangles.resize(slotRef.CoarseNumTris * 3);
TCoarseMeshIndexType *dstPtr= &slotRef.CoarseTriangles[0]; TCoarseMeshIndexType *dstPtr= &slotRef.CoarseTriangles[0];
uint totalTris = 0;
for(uint i=0;i<meshGeom->getNbRdrPass(0);i++) for(uint i=0;i<meshGeom->getNbRdrPass(0);i++)
{ {
const CIndexBuffer &pb= meshGeom->getRdrPassPrimitiveBlock(0, i); const CIndexBuffer &pb= meshGeom->getRdrPassPrimitiveBlock(0, i);
CIndexBufferRead ibaRead; CIndexBufferRead ibaRead;
pb.lock (ibaRead); pb.lock (ibaRead);
uint numTris= pb.getNumIndexes()/3; uint numTris= pb.getNumIndexes()/3;
totalTris += numTris;
if (pb.getFormat() == CIndexBuffer::Indices16) if (pb.getFormat() == CIndexBuffer::Indices16)
{ {
if (sizeof(TCoarseMeshIndexType) == sizeof(uint16)) if (sizeof(TCoarseMeshIndexType) == sizeof(uint16))
{ {
memcpy(dstPtr, (uint16 *) ibaRead.getPtr(), numTris*3*sizeof(uint16)); memcpy(dstPtr, (uint16 *) ibaRead.getPtr(), numTris*3*sizeof(uint16));
dstPtr+= numTris*3;
} }
else else
{ {
@ -820,6 +823,7 @@ void CMeshMultiLod::compileCoarseMeshes()
if (sizeof(TCoarseMeshIndexType) == sizeof(uint32)) if (sizeof(TCoarseMeshIndexType) == sizeof(uint32))
{ {
memcpy(dstPtr, (uint32 *) ibaRead.getPtr(), numTris*3*sizeof(uint32)); memcpy(dstPtr, (uint32 *) ibaRead.getPtr(), numTris*3*sizeof(uint32));
dstPtr+= numTris*3;
} }
else else
{ {
@ -836,8 +840,8 @@ void CMeshMultiLod::compileCoarseMeshes()
} }
} }
} }
dstPtr+= numTris*3;
} }
nlassert(totalTris == slotRef.CoarseNumTris);
} }
} }
} }

@ -453,6 +453,7 @@ void CStereoDebugger::listDevices(std::vector<CStereoDeviceInfo> &devicesOut)
devInfo.Manufacturer = "NeL"; devInfo.Manufacturer = "NeL";
devInfo.ProductName = "Stereo Debugger"; devInfo.ProductName = "Stereo Debugger";
devInfo.Serial = "NL-3D-DEBUG"; devInfo.Serial = "NL-3D-DEBUG";
devInfo.AllowAuto = false;
devicesOut.push_back(devInfo); devicesOut.push_back(devInfo);
} }

@ -612,6 +612,7 @@ void CStereoLibVR::listDevices(std::vector<CStereoDeviceInfo> &devicesOut)
deviceInfoOut.Factory = static_cast<IStereoDeviceFactory *>(handle); deviceInfoOut.Factory = static_cast<IStereoDeviceFactory *>(handle);
deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD;
deviceInfoOut.Library = CStereoDeviceInfo::LibVR; deviceInfoOut.Library = CStereoDeviceInfo::LibVR;
deviceInfoOut.AllowAuto = true;
//TODO: manufacturer, produc name //TODO: manufacturer, produc name
//TODO: serial //TODO: serial
devicesOut.push_back(deviceInfoOut); devicesOut.push_back(deviceInfoOut);

@ -816,6 +816,7 @@ void CStereoOVR::listDevices(std::vector<CStereoDeviceInfo> &devicesOut)
deviceInfoOut.Library = CStereoDeviceInfo::OVR; // "Oculus SDK"; deviceInfoOut.Library = CStereoDeviceInfo::OVR; // "Oculus SDK";
deviceInfoOut.Manufacturer = deviceInfo.Manufacturer; deviceInfoOut.Manufacturer = deviceInfo.Manufacturer;
deviceInfoOut.ProductName = deviceInfo.ProductName; deviceInfoOut.ProductName = deviceInfo.ProductName;
deviceInfoOut.AllowAuto = true;
stringstream ser; stringstream ser;
ser << id; ser << id;
deviceInfoOut.Serial = ser.str(); // can't get the real serial from the sdk... deviceInfoOut.Serial = ser.str(); // can't get the real serial from the sdk...

@ -885,7 +885,7 @@ bool CVPParser::parseInstruction(CVPInstruction &instr, std::string &errorOutput
} }
// it is not allowed to write to an adress register except for ARL // it is not allowed to write to an adress register except for ARL
if (instrStr != NELID("ARL")) if (instrStr != NELID("ARL "))
{ {
if (instr.Dest.Type == CVPOperand::AddressRegister) if (instr.Dest.Type == CVPOperand::AddressRegister)
{ {

@ -373,7 +373,9 @@ public:
setCPUMask (Thread, _Process); setCPUMask (Thread, _Process);
_ZoneLighter->processCalc (_Process, *_Description); _ZoneLighter->processCalc (_Process, *_Description);
_ZoneLighter->_ProcessExitedMutex.enter();
_ZoneLighter->_ProcessExited++; _ZoneLighter->_ProcessExited++;
_ZoneLighter->_ProcessExitedMutex.leave();
} }
}; };
@ -649,7 +651,9 @@ void NL3D::CRenderZBuffer::run()
} }
// Exit // Exit
_ZoneLighter->_ProcessExitedMutex.enter();
_ZoneLighter->_ProcessExited++; _ZoneLighter->_ProcessExited++;
_ZoneLighter->_ProcessExitedMutex.leave();
} }
// *************************************************************************** // ***************************************************************************
@ -676,7 +680,9 @@ public:
void run() void run()
{ {
_ZoneLighter->processLightableShapeCalc(_Process, _ShapesToLit, _FirstShape, _LastShape, *_Description); _ZoneLighter->processLightableShapeCalc(_Process, _ShapesToLit, _FirstShape, _LastShape, *_Description);
_ZoneLighter->_ProcessExitedMutex.enter();
_ZoneLighter->_ProcessExited++; _ZoneLighter->_ProcessExited++;
_ZoneLighter->_ProcessExitedMutex.leave();
} }
private: private:
CZoneLighter *_ZoneLighter; CZoneLighter *_ZoneLighter;

@ -104,7 +104,7 @@ CForm::~CForm ()
// *************************************************************************** // ***************************************************************************
void CForm::write (xmlDocPtr doc, const char *filename, bool georges4CVS) void CForm::write (xmlDocPtr doc, const char *filename)
{ {
// Save the filename // Save the filename
if (filename) if (filename)
@ -137,7 +137,7 @@ void CForm::write (xmlDocPtr doc, const char *filename, bool georges4CVS)
} }
// Header // Header
Header.write (node, georges4CVS); Header.write (node);
} }
// *************************************************************************** // ***************************************************************************
@ -259,14 +259,14 @@ const std::string &CForm::getComment () const
// *************************************************************************** // ***************************************************************************
void CForm::write (class NLMISC::IStream &stream, bool georges4CVS) void CForm::write (class NLMISC::IStream &stream)
{ {
// Xml stream // Xml stream
COXml xmlStream; COXml xmlStream;
xmlStream.init (&stream); xmlStream.init (&stream);
// Write the file // Write the file
write (xmlStream.getDocument (), NULL, georges4CVS); write (xmlStream.getDocument (), NULL);
} }
// *************************************************************************** // ***************************************************************************

@ -41,7 +41,7 @@ void warning (bool exception, const char *format, ... );
// *************************************************************************** // ***************************************************************************
void CFormDfn::write (xmlDocPtr doc, const char *filename, bool georges4CVS) void CFormDfn::write (xmlDocPtr doc, const char *filename)
{ {
// Save filename // Save filename
_Filename = CFile::getFilename (filename); _Filename = CFile::getFilename (filename);
@ -101,7 +101,7 @@ void CFormDfn::write (xmlDocPtr doc, const char *filename, bool georges4CVS)
} }
// Header // Header
Header.write (node, georges4CVS); Header.write (node);
} }
// *************************************************************************** // ***************************************************************************

@ -38,27 +38,16 @@ CFileHeader::CFileHeader ()
MajorVersion = 0; MajorVersion = 0;
MinorVersion = 0; MinorVersion = 0;
State = Modified; State = Modified;
Revision = "$R";
Revision += "evision$";
} }
// *************************************************************************** // ***************************************************************************
void CFileHeader::write (xmlNodePtr node, bool georges4CVS) const void CFileHeader::write (xmlNodePtr node) const
{ {
// Version for CVS ?
if (georges4CVS)
{
// Georges version system
xmlSetProp (node, (const xmlChar*)"Revision", (const xmlChar*)Revision.c_str ());
}
else
{
// Georges version system // Georges version system
char tmp[512]; char tmp[512];
smprintf (tmp, 512, "%d.%d", MajorVersion, MinorVersion); smprintf (tmp, 512, "%d.%d", MajorVersion, MinorVersion);
xmlSetProp (node, (const xmlChar*)"Version", (const xmlChar*)tmp); xmlSetProp (node, (const xmlChar*)"Version", (const xmlChar*)tmp);
}
// State // State
if (State == Modified) if (State == Modified)
@ -137,23 +126,6 @@ void CFileHeader::read (xmlNodePtr root)
MinorVersion = 0; MinorVersion = 0;
} }
// Get the revision
value = (const char*)xmlGetProp (root, (xmlChar*)"Revision");
if (value)
{
// Set the value
Revision = value;
// Delete the value
xmlFree ((void*)value);
}
else
{
// Set default
Revision = "$R";
Revision += "evision$";
}
// Get the version // Get the version
value = (const char*)xmlGetProp (root, (xmlChar*)"State"); value = (const char*)xmlGetProp (root, (xmlChar*)"State");
if (value) if (value)

@ -54,7 +54,7 @@ CType::~CType ()
// *************************************************************************** // ***************************************************************************
void CType::write (xmlDocPtr doc, bool georges4CVS) const void CType::write (xmlDocPtr doc) const
{ {
// Create the first node // Create the first node
xmlNodePtr node = xmlNewDocNode (doc, NULL, (const xmlChar*)"TYPE", NULL); xmlNodePtr node = xmlNewDocNode (doc, NULL, (const xmlChar*)"TYPE", NULL);
@ -98,7 +98,7 @@ void CType::write (xmlDocPtr doc, bool georges4CVS) const
} }
// Header // Header
Header.write (node, georges4CVS); Header.write (node);
} }
// *************************************************************************** // ***************************************************************************
@ -350,7 +350,7 @@ public:
{ {
i++; i++;
// Set the result // Set the result
result = atof (filename.c_str () + i); NLMISC::fromString(filename.substr(i), result);
} }
else else
{ {

@ -202,24 +202,21 @@ namespace NLGUI
prop = (char*) xmlGetProp( cur, (xmlChar*)"tx_normal" ); prop = (char*) xmlGetProp( cur, (xmlChar*)"tx_normal" );
if (prop) if (prop)
{ {
string TxName = (const char *) prop; string TxName = NLMISC::toLower((const char *) prop);
TxName = strlwr(TxName);
_TextureIdNormal.setTexture(TxName.c_str()); _TextureIdNormal.setTexture(TxName.c_str());
} }
prop = (char*) xmlGetProp( cur, (xmlChar*)"tx_pushed" ); prop = (char*) xmlGetProp( cur, (xmlChar*)"tx_pushed" );
if (prop) if (prop)
{ {
string TxName = (const char *) prop; string TxName = NLMISC::toLower((const char *) prop);
TxName = strlwr(TxName);
_TextureIdPushed.setTexture(TxName.c_str()); _TextureIdPushed.setTexture(TxName.c_str());
} }
prop = (char*) xmlGetProp( cur, (xmlChar*)"tx_over" ); prop = (char*) xmlGetProp( cur, (xmlChar*)"tx_over" );
if (prop) if (prop)
{ {
string TxName = (const char *) prop; string TxName = NLMISC::toLower((const char *) prop);
TxName = strlwr(TxName);
_TextureIdOver.setTexture(TxName.c_str()); _TextureIdOver.setTexture(TxName.c_str());
} }

@ -3857,6 +3857,7 @@ namespace NLGUI
else else
{ {
/* Add our own request terminate handler. Nb: pass as param a UID, not the ptr */ /* Add our own request terminate handler. Nb: pass as param a UID, not the ptr */
/* FIX ME - every connection is appending a new callback to the list, and its never removed (Vinicius Arroyo)*/
HTNet_addAfter(requestTerminater, NULL, (void*)(size_t)_GroupHtmlUID, HT_ALL, HT_FILTER_LAST); HTNet_addAfter(requestTerminater, NULL, (void*)(size_t)_GroupHtmlUID, HT_ALL, HT_FILTER_LAST);
/* Set the timeout for long we are going to wait for a response */ /* Set the timeout for long we are going to wait for a response */
@ -4003,6 +4004,7 @@ namespace NLGUI
else else
{ {
/* Add our own request terminate handler. Nb: pass as param a UID, not the ptr */ /* Add our own request terminate handler. Nb: pass as param a UID, not the ptr */
/* FIX ME - every connection is appending a new callback to the list, and its never removed (Vinicius Arroyo)*/
HTNet_addAfter(requestTerminater, NULL, (void*)(size_t)_GroupHtmlUID, HT_ALL, HT_FILTER_LAST); HTNet_addAfter(requestTerminater, NULL, (void*)(size_t)_GroupHtmlUID, HT_ALL, HT_FILTER_LAST);
/* Start the first request */ /* Start the first request */
@ -4089,8 +4091,10 @@ namespace NLGUI
// *************************************************************************** // ***************************************************************************
void CGroupHTML::requestTerminated(HTRequest * /* request */) void CGroupHTML::requestTerminated(HTRequest * request )
{ {
// this callback is being called for every request terminated
if( request == _LibWWW->Request ){
// set the browser as complete // set the browser as complete
_Browsing = false; _Browsing = false;
updateRefreshButton(); updateRefreshButton();
@ -4101,6 +4105,7 @@ namespace NLGUI
setTitle(_TitlePrefix); setTitle(_TitlePrefix);
} }
} }
}
// *************************************************************************** // ***************************************************************************

@ -876,38 +876,32 @@ namespace NLGUI
{ {
case Hotspot_TL: case Hotspot_TL:
return "TL"; return "TL";
break;
case Hotspot_TM: case Hotspot_TM:
return "TM"; return "TM";
break;
case Hotspot_TR: case Hotspot_TR:
return "TR"; return "TR";
break;
case Hotspot_ML: case Hotspot_ML:
return "ML"; return "ML";
break;
case Hotspot_MM: case Hotspot_MM:
return "MM"; return "MM";
break;
case Hotspot_MR: case Hotspot_MR:
return "MR"; return "MR";
break;
case Hotspot_BL: case Hotspot_BL:
return "BL"; return "BL";
break;
case Hotspot_BM: case Hotspot_BM:
return "BM"; return "BM";
break;
case Hotspot_BR: case Hotspot_BR:
return "BR"; return "BR";
default:
break; break;
} }

@ -2051,10 +2051,10 @@ namespace NLGUI
// Clear all structures used only for init // Clear all structures used only for init
//NLMISC::contReset (_ParentPositionsMap); NLMISC::contReset (_ParentPositionsMap);
//NLMISC::contReset (_ParentSizesMap); NLMISC::contReset (_ParentSizesMap);
//NLMISC::contReset (_ParentSizesMaxMap); NLMISC::contReset (_ParentSizesMaxMap);
//NLMISC::contReset (_LuaClassAssociation); NLMISC::contReset (_LuaClassAssociation);
return true; return true;
} }

@ -703,6 +703,11 @@ namespace NLGUI
// HTHost_setActiveTimeout (30000); // HTHost_setActiveTimeout (30000);
// HTHost_setPersistTimeout (30000); // HTHost_setPersistTimeout (30000);
// libwww default value is 2000ms for POST/PUT requests on the first and 3000 on the second, smallest allowed value is 21ms
// too small values may create timeout problems but we want it low as possible
// second value is the timeout for the second try to we set that high
HTTP_setBodyWriteDelay(250, 3000);
// Initialized // Initialized
initialized = true; initialized = true;
} }

@ -408,7 +408,6 @@ namespace NLGUI
splitString(tooltipInfos, "@", tooltipInfosList); splitString(tooltipInfos, "@", tooltipInfosList);
texName = tooltipInfosList[0]; texName = tooltipInfosList[0];
tooltip = tooltipInfosList[1]; tooltip = tooltipInfosList[1];
nlinfo(tooltip.c_str());
setString(ucstring(tooltip)); setString(ucstring(tooltip));
CViewRenderer &rVR = *CViewRenderer::getInstance(); CViewRenderer &rVR = *CViewRenderer::getInstance();
sint32 texId = rVR.getTextureIdFromName (texName); sint32 texId = rVR.getTextureIdFromName (texName);

@ -1094,7 +1094,10 @@ namespace NLGUI
bool updateCoordCalled= false; bool updateCoordCalled= false;
// updateCoords the window only if the master group is his parent and if need it // updateCoords the window only if the master group is his parent and if need it
// do it until updateCoords() no more invalidate coordinates!! // do it until updateCoords() no more invalidate coordinates!!
while (pIG->getParent()==rMG.Group && (pIG->getInvalidCoords()>0))
// add deadlock counter to prevent endless loop (Issue #73: web browser long scroll lockup)
int deadlock = 10;
while (--deadlock > 0 && pIG->getParent()==rMG.Group && (pIG->getInvalidCoords()>0))
{ {
bRecomputeCtrlUnderPtr = true; bRecomputeCtrlUnderPtr = true;
// Update as many pass wanted (3 time for complex resizing, 1 for scroll for example) // Update as many pass wanted (3 time for complex resizing, 1 for scroll for example)
@ -2880,7 +2883,7 @@ namespace NLGUI
bool CWidgetManager::serializeTreeData( xmlNodePtr parentNode ) const bool CWidgetManager::serializeTreeData( xmlNodePtr parentNode ) const
{ {
if( parentNode == NULL ) if( parentNode == NULL )
return NULL; return false;
std::vector< SMasterGroup >::size_type i; std::vector< SMasterGroup >::size_type i;
for( i = 0; i < _MasterGroups.size(); i++ ) for( i = 0; i < _MasterGroups.size(); i++ )
@ -3184,7 +3187,6 @@ namespace NLGUI
CWidgetManager::CWidgetManager() CWidgetManager::CWidgetManager()
{ {
LinkHack(); LinkHack();
CStringShared::createStringMapper(); CStringShared::createStringMapper();
CReflectableRegister::registerClasses(); CReflectableRegister::registerClasses();

@ -139,7 +139,7 @@ bool ReadFloat (const char *propName, float &result, const char *filename, xmlNo
string value; string value;
if (GetPropertyString (value, filename, xmlNode, propName)) if (GetPropertyString (value, filename, xmlNode, propName))
{ {
result = (float)atof (value.c_str ()); NLMISC::fromString(value, result);
return true; return true;
} }
return false; return false;

@ -38,7 +38,7 @@ bool ReadFloat (const char *propName, float &result, xmlNodePtr xmlNode)
string value; string value;
if (CIXml::getPropertyString (value, xmlNode, propName)) if (CIXml::getPropertyString (value, xmlNode, propName))
{ {
result = (float)atof (value.c_str ()); NLMISC::fromString(value, result);
return true; return true;
} }
return false; return false;

@ -19,14 +19,15 @@
#include "nel/ligo/zone_bank.h" #include "nel/ligo/zone_bank.h"
#ifdef NL_OS_WINDOWS
#include "nel/misc/debug.h" #include "nel/misc/debug.h"
#include "nel/misc/file.h" #include "nel/misc/file.h"
#include "nel/misc/i_xml.h" #include "nel/misc/i_xml.h"
#include "nel/misc/o_xml.h" #include "nel/misc/o_xml.h"
#ifdef NL_OS_WINDOWS
#define NOMINMAX #define NOMINMAX
#include <windows.h> #include <windows.h>
#endif // NL_OS_WINDOWS
using namespace std; using namespace std;
using namespace NLMISC; using namespace NLMISC;
@ -496,8 +497,9 @@ void CZoneBank::reset ()
_Selection.clear (); _Selection.clear ();
} }
#ifdef NL_OS_WINDOWS
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
bool CZoneBank::initFromPath(const string &sPathName, std::string &error) bool CZoneBank::initFromPath(const std::string &sPathName, std::string &error)
{ {
char sDirBackup[512]; char sDirBackup[512];
GetCurrentDirectory (512, sDirBackup); GetCurrentDirectory (512, sDirBackup);
@ -520,6 +522,7 @@ bool CZoneBank::initFromPath(const string &sPathName, std::string &error)
SetCurrentDirectory (sDirBackup); SetCurrentDirectory (sDirBackup);
return true; return true;
} }
#endif // NL_OS_WINDOWS
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
bool CZoneBank::addElement (const std::string &elementName, std::string &error) bool CZoneBank::addElement (const std::string &elementName, std::string &error)
@ -695,5 +698,3 @@ void CZoneBank::getSelection (std::vector<CZoneBankElement*> &SelectedElements)
// *************************************************************************** // ***************************************************************************
} // namespace NLLIGO } // namespace NLLIGO
#endif // NL_OS_WINDOWS

@ -517,13 +517,6 @@ void CBufServer::receive( CMemStream& buffer, TSockId* phostid )
*phostid = *((TSockId*)&(buffer.buffer()[buffer.size()-sizeof(TSockId)-1])); *phostid = *((TSockId*)&(buffer.buffer()[buffer.size()-sizeof(TSockId)-1]));
nlassert( buffer.buffer()[buffer.size()-1] == CBufNetBase::User ); nlassert( buffer.buffer()[buffer.size()-1] == CBufNetBase::User );
// debug features, we number all packet to be sure that they are all sent and received
// \todo remove this debug feature when ok
#ifdef NL_BIG_ENDIAN
uint32 val = NLMISC_BSWAP32(*(uint32*)buffer.buffer());
#else
uint32 val = *(uint32*)buffer.buffer();
#endif
buffer.resize( buffer.size()-sizeof(TSockId)-1 ); buffer.resize( buffer.size()-sizeof(TSockId)-1 );
// TODO OPTIM remove the nldebug for speed // TODO OPTIM remove the nldebug for speed

@ -242,11 +242,15 @@ void CSourceXAudio2::updateState()
if (!_AdpcmUtility->getSourceData()) if (!_AdpcmUtility->getSourceData())
{ {
_SoundDriver->getXAudio2()->CommitChanges(_OperationSet); _SoundDriver->getXAudio2()->CommitChanges(_OperationSet);
if (!_BufferStreaming)
{
// nldebug(NLSOUND_XAUDIO2_PREFIX "Stop");
if (FAILED(_SourceVoice->Stop(0))) if (FAILED(_SourceVoice->Stop(0)))
nlwarning(NLSOUND_XAUDIO2_PREFIX "FAILED Stop"); nlwarning(NLSOUND_XAUDIO2_PREFIX "FAILED Stop");
_IsPlaying = false; _IsPlaying = false;
} }
} }
}
else else
{ {
XAUDIO2_VOICE_STATE voice_state; XAUDIO2_VOICE_STATE voice_state;
@ -254,17 +258,23 @@ void CSourceXAudio2::updateState()
if (!voice_state.BuffersQueued) if (!voice_state.BuffersQueued)
{ {
_SoundDriver->getXAudio2()->CommitChanges(_OperationSet); _SoundDriver->getXAudio2()->CommitChanges(_OperationSet);
if (!_BufferStreaming)
{
// nldebug(NLSOUND_XAUDIO2_PREFIX "Stop");
if (FAILED(_SourceVoice->Stop(0))) if (FAILED(_SourceVoice->Stop(0)))
nlwarning(NLSOUND_XAUDIO2_PREFIX "FAILED Stop"); nlwarning(NLSOUND_XAUDIO2_PREFIX "FAILED Stop");
_IsPlaying = false; _IsPlaying = false;
} }
} }
} }
}
} }
/// (Internal) Submit a buffer to the XAudio2 source voice. /// (Internal) Submit a buffer to the XAudio2 source voice.
void CSourceXAudio2::submitBuffer(CBufferXAudio2 *ibuffer) void CSourceXAudio2::submitBuffer(CBufferXAudio2 *ibuffer)
{ {
// nldebug(NLSOUND_XAUDIO2_PREFIX "submitBuffer %u", (uint32)(void *)this);
nlassert(_SourceVoice); nlassert(_SourceVoice);
nlassert(ibuffer->getFormat() == _Format nlassert(ibuffer->getFormat() == _Format
&& ibuffer->getChannels() == _Channels && ibuffer->getChannels() == _Channels
@ -278,9 +288,9 @@ void CSourceXAudio2::submitBuffer(CBufferXAudio2 *ibuffer)
{ {
XAUDIO2_BUFFER buffer; XAUDIO2_BUFFER buffer;
buffer.AudioBytes = ibuffer->getSize(); buffer.AudioBytes = ibuffer->getSize();
buffer.Flags = _IsLooping || _BufferStreaming ? 0 : XAUDIO2_END_OF_STREAM; buffer.Flags = (_IsLooping || _BufferStreaming) ? 0 : XAUDIO2_END_OF_STREAM;
buffer.LoopBegin = 0; buffer.LoopBegin = 0;
buffer.LoopCount = _IsLooping ? XAUDIO2_LOOP_INFINITE : 0; buffer.LoopCount = (_IsLooping && !_BufferStreaming) ? XAUDIO2_LOOP_INFINITE : 0;
buffer.LoopLength = 0; buffer.LoopLength = 0;
buffer.pAudioData = const_cast<BYTE *>(ibuffer->getData()); buffer.pAudioData = const_cast<BYTE *>(ibuffer->getData());
buffer.pContext = ibuffer; buffer.pContext = ibuffer;
@ -336,7 +346,25 @@ void CSourceXAudio2::setupVoiceSends()
void CSourceXAudio2::setStreaming(bool streaming) void CSourceXAudio2::setStreaming(bool streaming)
{ {
nlassert(!_IsPlaying); nlassert(!_IsPlaying);
// nldebug(NLSOUND_XAUDIO2_PREFIX "setStreaming %i", (uint32)streaming);
if (_SourceVoice)
{
XAUDIO2_VOICE_STATE voice_state;
_SourceVoice->GetState(&voice_state);
if (!voice_state.BuffersQueued)
{
nlwarning(NLSOUND_XAUDIO2_PREFIX "Switched streaming mode while buffer still queued!?! Flush");
_SoundDriver->getXAudio2()->CommitChanges(_OperationSet);
if (FAILED(_SourceVoice->FlushSourceBuffers()))
nlwarning(NLSOUND_XAUDIO2_PREFIX "FAILED FlushSourceBuffers");
}
}
_BufferStreaming = streaming; _BufferStreaming = streaming;
// nldebug(NLSOUND_XAUDIO2_PREFIX "setStreaming done %i", (uint32)streaming);
} }
/// Set the buffer that will be played (no streaming) /// Set the buffer that will be played (no streaming)
@ -344,6 +372,8 @@ void CSourceXAudio2::setStaticBuffer(IBuffer *buffer)
{ {
nlassert(!_BufferStreaming); nlassert(!_BufferStreaming);
// nldebug(NLSOUND_XAUDIO2_PREFIX "setStaticBuffer");
// if (buffer) // nldebug(NLSOUND_XAUDIO2_PREFIX "setStaticBuffer %s", _SoundDriver->getStringMapper()->unmap(buffer->getName()).c_str()); // if (buffer) // nldebug(NLSOUND_XAUDIO2_PREFIX "setStaticBuffer %s", _SoundDriver->getStringMapper()->unmap(buffer->getName()).c_str());
// else // nldebug(NLSOUND_XAUDIO2_PREFIX "setStaticBuffer NULL"); // else // nldebug(NLSOUND_XAUDIO2_PREFIX "setStaticBuffer NULL");
@ -364,32 +394,20 @@ IBuffer *CSourceXAudio2::getStaticBuffer()
/// Should be called by a thread which checks countStreamingBuffers every 100ms. /// Should be called by a thread which checks countStreamingBuffers every 100ms.
void CSourceXAudio2::submitStreamingBuffer(IBuffer *buffer) void CSourceXAudio2::submitStreamingBuffer(IBuffer *buffer)
{ {
// nldebug(NLSOUND_XAUDIO2_PREFIX "submitStreamingBuffer");
nlassert(_BufferStreaming); nlassert(_BufferStreaming);
// allow to change the format if not playing
if (!_IsPlaying)
{
IBuffer::TBufferFormat bufferFormat; IBuffer::TBufferFormat bufferFormat;
uint8 channels; uint8 channels;
uint8 bitsPerSample; uint8 bitsPerSample;
uint32 frequency; uint32 frequency;
buffer->getFormat(bufferFormat, channels, bitsPerSample, frequency); buffer->getFormat(bufferFormat, channels, bitsPerSample, frequency);
// allow to change the format if not playing
if (!_IsPlaying)
{
if (!_SourceVoice)
{
// if no source yet, prepare the format
preparePlay(bufferFormat, channels, bitsPerSample, frequency); preparePlay(bufferFormat, channels, bitsPerSample, frequency);
} }
else
{
XAUDIO2_VOICE_STATE voice_state;
_SourceVoice->GetState(&voice_state);
// if no buffers queued, prepare the format
if (!voice_state.BuffersQueued)
{
preparePlay(bufferFormat, channels, bitsPerSample, frequency);
}
}
}
submitBuffer(static_cast<CBufferXAudio2 *>(buffer)); submitBuffer(static_cast<CBufferXAudio2 *>(buffer));
} }
@ -414,9 +432,10 @@ uint CSourceXAudio2::countStreamingBuffers() const
/// Set looping on/off for future playbacks (default: off) /// Set looping on/off for future playbacks (default: off)
void CSourceXAudio2::setLooping(bool l) void CSourceXAudio2::setLooping(bool l)
{ {
// nldebug(NLSOUND_XAUDIO2_PREFIX "setLooping %u", (uint32)l);
nlassert(!_BufferStreaming); nlassert(!_BufferStreaming);
// nldebug(NLSOUND_XAUDIO2_PREFIX "setLooping %u", (uint32)l);
if (_IsLooping != l) if (_IsLooping != l)
{ {
_IsLooping = l; _IsLooping = l;
@ -455,7 +474,7 @@ void CSourceXAudio2::setLooping(bool l)
_SourceVoice->GetState(&voice_state); _SourceVoice->GetState(&voice_state);
if (voice_state.BuffersQueued) if (voice_state.BuffersQueued)
{ {
nlwarning(NLSOUND_XAUDIO2_PREFIX "not playing but buffer already queued???"); nlwarning(NLSOUND_XAUDIO2_PREFIX "Not playing but buffer already queued while switching loop mode!?! Flush and requeue");
if (FAILED(_SourceVoice->FlushSourceBuffers())) if (FAILED(_SourceVoice->FlushSourceBuffers()))
nlwarning(NLSOUND_XAUDIO2_PREFIX "FAILED FlushSourceBuffers"); nlwarning(NLSOUND_XAUDIO2_PREFIX "FAILED FlushSourceBuffers");
// queue buffer with correct looping parameters // queue buffer with correct looping parameters
@ -603,6 +622,7 @@ bool CSourceXAudio2::play()
// preparePlay already called, // preparePlay already called,
// stop already called before going into buffer streaming // stop already called before going into buffer streaming
nlassert(!_IsPlaying); nlassert(!_IsPlaying);
nlassert(_SourceVoice);
_PlayStart = CTime::getLocalTime(); _PlayStart = CTime::getLocalTime();
if (SUCCEEDED(_SourceVoice->Start(0))) _IsPlaying = true; if (SUCCEEDED(_SourceVoice->Start(0))) _IsPlaying = true;
else nlwarning(NLSOUND_XAUDIO2_PREFIX "FAILED Play (_BufferStreaming)"); else nlwarning(NLSOUND_XAUDIO2_PREFIX "FAILED Play (_BufferStreaming)");

@ -6,6 +6,7 @@ IF(WITH_NEL_TOOLS)
build_far_bank build_far_bank
build_smallbank build_smallbank
ig_lighter ig_lighter
ig_elevation
zone_dependencies zone_dependencies
zone_ig_lighter zone_ig_lighter
zone_lighter zone_lighter
@ -45,9 +46,7 @@ IF(WIN32)
ENDIF(WIN32) ENDIF(WIN32)
IF(WITH_NEL_TOOLS) IF(WITH_NEL_TOOLS)
IF(WIN32) IF(WIN32)
ADD_SUBDIRECTORY(ig_elevation)
ADD_SUBDIRECTORY(lightmap_optimizer) ADD_SUBDIRECTORY(lightmap_optimizer)
IF(MFC_FOUND) IF(MFC_FOUND)
ADD_SUBDIRECTORY(object_viewer_exe) ADD_SUBDIRECTORY(object_viewer_exe)

@ -35,7 +35,14 @@
#include "nel/3d/scene_group.h" #include "nel/3d/scene_group.h"
#include <windows.h> #ifdef NL_OS_WINDOWS
#include <windows.h>
#else
#include <dirent.h> /* for directories functions */
#include <sys/types.h>
#include <unistd.h> /* getcwd, chdir -- replacement for getCurDiretory & setCurDirectory on windows */
#endif
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -126,6 +133,7 @@ struct CZoneLimits
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
#ifdef NL_OS_WINDOWS // win32 code
void dir (const string &sFilter, vector<string> &sAllFiles, bool bFullPath) void dir (const string &sFilter, vector<string> &sAllFiles, bool bFullPath)
{ {
WIN32_FIND_DATA findData; WIN32_FIND_DATA findData;
@ -133,7 +141,7 @@ void dir (const string &sFilter, vector<string> &sAllFiles, bool bFullPath)
char sCurDir[MAX_PATH]; char sCurDir[MAX_PATH];
sAllFiles.clear (); sAllFiles.clear ();
GetCurrentDirectory (MAX_PATH, sCurDir); GetCurrentDirectory (MAX_PATH, sCurDir);
hFind = FindFirstFile (sFilter.c_str(), &findData); hFind = FindFirstFile (("*"+sFilter).c_str(), &findData);
while (hFind != INVALID_HANDLE_VALUE) while (hFind != INVALID_HANDLE_VALUE)
{ {
DWORD res = GetFileAttributes(findData.cFileName); DWORD res = GetFileAttributes(findData.cFileName);
@ -150,6 +158,48 @@ void dir (const string &sFilter, vector<string> &sAllFiles, bool bFullPath)
FindClose (hFind); FindClose (hFind);
} }
void getcwd (char *dir, int length)
{
GetCurrentDirectoryA (length, dir);
}
void chdir(const char *path)
{
SetCurrentDirectoryA (path);
}
#else // posix version of the void dir(...) function.
void dir (const string &sFilter, vector<string> &sAllFiles, bool bFullPath)
{
char sCurDir[MAX_PATH];
DIR* dp = NULL;
struct dirent *dirp= NULL;
getcwd ( sCurDir, MAX_PATH ) ;
sAllFiles.clear ();
if ( (dp = opendir( sCurDir )) == NULL)
{
string sTmp = string("ERROR : Can't open the dir : \"")+string(sCurDir)+string("\"") ;
outString ( sTmp ) ;
return ;
}
while ( (dirp = readdir(dp)) != NULL)
{
std:string sFileName = std::string(dirp->d_name) ;
if (sFileName.substr((sFileName.length()-sFilter.length()),sFilter.length()).find(sFilter)!= std::string::npos )
{
if (bFullPath)
sAllFiles.push_back(string(sCurDir) + "/" + sFileName);
else
sAllFiles.push_back(sFileName);
}
}
closedir(dp);
}
#endif
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
CZoneRegion *loadLand (const string &filename) CZoneRegion *loadLand (const string &filename)
@ -222,12 +272,14 @@ void SaveInstanceGroup (const char* sFilename, CInstanceGroup *pIG)
} }
catch (const Exception &e) catch (const Exception &e)
{ {
outString(string(e.what())); string stTmp = string(e.what()) ;
outString( stTmp );
} }
} }
else else
{ {
outString(string("Couldn't create ") + sFilename); string stTemp = string("Couldn't create ") + string(sFilename) ;
outString( stTemp );
} }
} }
@ -274,7 +326,7 @@ int main(int nNbArg, char**ppArgs)
NL3D_BlockMemoryAssertOnPurge = false; NL3D_BlockMemoryAssertOnPurge = false;
char sCurDir[MAX_PATH]; char sCurDir[MAX_PATH];
GetCurrentDirectory (MAX_PATH, sCurDir); getcwd (sCurDir, MAX_PATH);
if (nNbArg != 2) if (nNbArg != 2)
{ {
@ -322,7 +374,7 @@ int main(int nNbArg, char**ppArgs)
// Load the 2 height maps // Load the 2 height maps
CBitmap *HeightMap1 = NULL; CBitmap *HeightMap1 = NULL;
if (options.HeightMapFile1 != "") if (!options.HeightMapFile1.empty())
{ {
HeightMap1 = new CBitmap; HeightMap1 = new CBitmap;
try try
@ -334,7 +386,9 @@ int main(int nNbArg, char**ppArgs)
} }
else else
{ {
outString(string("Couldn't not open " + options.HeightMapFile1 + " : heightmap 1 map ignored")); string sTmp = string("Couldn't not open ")+string(options.HeightMapFile1)
+string(" : heightmap 1 map ignored");
outString(sTmp);
delete HeightMap1; delete HeightMap1;
HeightMap1 = NULL; HeightMap1 = NULL;
} }
@ -348,7 +402,7 @@ int main(int nNbArg, char**ppArgs)
} }
} }
CBitmap *HeightMap2 = NULL; CBitmap *HeightMap2 = NULL;
if (options.HeightMapFile2 != "") if (!options.HeightMapFile2.empty())
{ {
HeightMap2 = new CBitmap; HeightMap2 = new CBitmap;
try try
@ -360,7 +414,9 @@ int main(int nNbArg, char**ppArgs)
} }
else else
{ {
outString(string("Couldn't not open " + options.HeightMapFile2 + " : heightmap 2 map ignored\n")); string sTmp = string("Couldn't not open ")+string(options.HeightMapFile2)
+string(" : heightmap 2 map ignored\n");
outString(sTmp);
delete HeightMap2; delete HeightMap2;
HeightMap2 = NULL; HeightMap2 = NULL;
} }
@ -376,15 +432,15 @@ int main(int nNbArg, char**ppArgs)
// Get all files // Get all files
vector<string> vAllFiles; vector<string> vAllFiles;
SetCurrentDirectory (options.InputIGDir.c_str()); chdir (options.InputIGDir.c_str());
dir ("*.ig", vAllFiles, false); dir (".ig", vAllFiles, false);
SetCurrentDirectory (sCurDir); chdir (sCurDir);
for (uint32 i = 0; i < vAllFiles.size(); ++i) for (uint32 i = 0; i < vAllFiles.size(); ++i)
{ {
SetCurrentDirectory (options.InputIGDir.c_str()); chdir (options.InputIGDir.c_str());
CInstanceGroup *pIG = LoadInstanceGroup (vAllFiles[i].c_str()); CInstanceGroup *pIG = LoadInstanceGroup (vAllFiles[i].c_str());
SetCurrentDirectory (sCurDir); chdir (sCurDir);
if (pIG != NULL) if (pIG != NULL)
{ {
bool realTimeSunContribution = pIG->getRealTimeSunContribution(); bool realTimeSunContribution = pIG->getRealTimeSunContribution();
@ -401,8 +457,6 @@ int main(int nNbArg, char**ppArgs)
uint k; uint k;
// elevate instance // elevate instance
for(k = 0; k < IA.size(); ++k) for(k = 0; k < IA.size(); ++k)
{ {
@ -417,7 +471,6 @@ int main(int nNbArg, char**ppArgs)
PLN[k].setPosition( PLN[k].getPosition() + getHeightMapZ(lightPos.x, lightPos.y, zl, options, HeightMap1, HeightMap2) * CVector::K); PLN[k].setPosition( PLN[k].getPosition() + getHeightMapZ(lightPos.x, lightPos.y, zl, options, HeightMap1, HeightMap2) * CVector::K);
} }
// portals // portals
std::vector<CVector> portal; std::vector<CVector> portal;
for(k = 0; k < Portals.size(); ++k) for(k = 0; k < Portals.size(); ++k)
@ -459,9 +512,9 @@ int main(int nNbArg, char**ppArgs)
pIGout->enableRealTimeSunContribution(realTimeSunContribution); pIGout->enableRealTimeSunContribution(realTimeSunContribution);
SetCurrentDirectory (options.OutputIGDir.c_str()); chdir (options.OutputIGDir.c_str());
SaveInstanceGroup (vAllFiles[i].c_str(), pIGout); SaveInstanceGroup (vAllFiles[i].c_str(), pIGout);
SetCurrentDirectory (sCurDir); chdir (sCurDir);
delete pIG; delete pIG;
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

@ -101,6 +101,13 @@
#include <QtGui/QToolButton> #include <QtGui/QToolButton>
#include <QtGui/QColorDialog> #include <QtGui/QColorDialog>
#include <QtGui/QFontDialog> #include <QtGui/QFontDialog>
#include <QtGui/QDialog>
#include <QtGui/QPlainTextEdit>
#include <QtGui/QTextEdit>
#include <QCompleter>
#include <QColumnView>
#include <QStandardItemModel>
#include <QtGui/QDialogButtonBox>
#include <QtGui/QSpacerItem> #include <QtGui/QSpacerItem>
#include <QtCore/QMap> #include <QtCore/QMap>
@ -652,6 +659,7 @@ class QtCheckBoxFactoryPrivate : public EditorFactoryPrivate<QtBoolEdit>
public: public:
void slotPropertyChanged(QtProperty *property, bool value); void slotPropertyChanged(QtProperty *property, bool value);
void slotSetValue(bool value); void slotSetValue(bool value);
void slotResetProperty();
}; };
void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool value) void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool value)
@ -662,6 +670,7 @@ void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool va
QListIterator<QtBoolEdit *> itEditor(m_createdEditors[property]); QListIterator<QtBoolEdit *> itEditor(m_createdEditors[property]);
while (itEditor.hasNext()) { while (itEditor.hasNext()) {
QtBoolEdit *editor = itEditor.next(); QtBoolEdit *editor = itEditor.next();
editor->setStateResetButton(property->isModified());
editor->blockCheckBoxSignals(true); editor->blockCheckBoxSignals(true);
editor->setChecked(value); editor->setChecked(value);
editor->blockCheckBoxSignals(false); editor->blockCheckBoxSignals(false);
@ -684,6 +693,22 @@ void QtCheckBoxFactoryPrivate::slotSetValue(bool value)
} }
} }
void QtCheckBoxFactoryPrivate::slotResetProperty()
{
QObject *object = q_ptr->sender();
const QMap<QtBoolEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
for (QMap<QtBoolEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
if (itEditor.key() == object) {
QtProperty *property = itEditor.value();
QtBoolPropertyManager *manager = q_ptr->propertyManager(property);
if (!manager)
return;
manager->emitResetProperty(property);
return;
}
}
/*! /*!
\class QtCheckBoxFactory \class QtCheckBoxFactory
@ -733,8 +758,10 @@ QWidget *QtCheckBoxFactory::createEditor(QtBoolPropertyManager *manager, QtPrope
QWidget *parent) QWidget *parent)
{ {
QtBoolEdit *editor = d_ptr->createEditor(property, parent); QtBoolEdit *editor = d_ptr->createEditor(property, parent);
editor->setStateResetButton(property->isModified());
editor->setChecked(manager->value(property)); editor->setChecked(manager->value(property));
connect(editor, SIGNAL(resetProperty()), this, SLOT(slotResetProperty()));
connect(editor, SIGNAL(toggled(bool)), this, SLOT(slotSetValue(bool))); connect(editor, SIGNAL(toggled(bool)), this, SLOT(slotSetValue(bool)));
connect(editor, SIGNAL(destroyed(QObject *)), connect(editor, SIGNAL(destroyed(QObject *)),
this, SLOT(slotEditorDestroyed(QObject *))); this, SLOT(slotEditorDestroyed(QObject *)));
@ -1853,9 +1880,87 @@ void QtCharEditorFactory::disconnectPropertyManager(QtCharPropertyManager *manag
this, SLOT(slotPropertyChanged(QtProperty *, const QChar &))); this, SLOT(slotPropertyChanged(QtProperty *, const QChar &)));
} }
class QtEnumEditWidget : public QWidget {
Q_OBJECT
public:
QtEnumEditWidget(QWidget *parent);
bool blockComboBoxSignals(bool block);
void addItems(const QStringList &texts);
void clearComboBox();
void setItemIcon(int index, const QIcon &icon);
public Q_SLOTS:
void setValue(int value);
void setStateResetButton(bool enabled);
Q_SIGNALS:
void valueChanged(int value);
void resetProperty();
private:
QComboBox *m_comboBox;
QToolButton *m_defaultButton;
};
QtEnumEditWidget::QtEnumEditWidget(QWidget *parent) :
QWidget(parent),
m_comboBox(new QComboBox),
m_defaultButton(new QToolButton)
{
m_comboBox->view()->setTextElideMode(Qt::ElideRight);
QHBoxLayout *lt = new QHBoxLayout(this);
lt->setContentsMargins(0, 0, 0, 0);
lt->setSpacing(0);
lt->addWidget(m_comboBox);
m_defaultButton->setIcon(QIcon(":/trolltech/qtpropertybrowser/images/resetproperty.png"));
m_defaultButton->setMaximumWidth(16);
connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(valueChanged(int)));
connect(m_defaultButton, SIGNAL(clicked()), this, SIGNAL(resetProperty()));
lt->addWidget(m_defaultButton);
m_defaultButton->setEnabled(false);
setFocusProxy(m_comboBox);
}
void QtEnumEditWidget::setValue(int value)
{
if (m_comboBox->currentIndex() != value)
m_comboBox->setCurrentIndex(value);
}
void QtEnumEditWidget::setStateResetButton(bool enabled)
{
m_defaultButton->setEnabled(enabled);
}
bool QtEnumEditWidget::blockComboBoxSignals(bool block)
{
return m_comboBox->blockSignals(block);
}
void QtEnumEditWidget::addItems(const QStringList &texts)
{
m_comboBox->addItems(texts);
}
void QtEnumEditWidget::clearComboBox()
{
m_comboBox->clear();
}
void QtEnumEditWidget::setItemIcon(int index, const QIcon &icon)
{
m_comboBox->setItemIcon(index, icon);
}
// QtEnumEditorFactory // QtEnumEditorFactory
class QtEnumEditorFactoryPrivate : public EditorFactoryPrivate<QComboBox> class QtEnumEditorFactoryPrivate : public EditorFactoryPrivate<QtEnumEditWidget>
{ {
QtEnumEditorFactory *q_ptr; QtEnumEditorFactory *q_ptr;
Q_DECLARE_PUBLIC(QtEnumEditorFactory) Q_DECLARE_PUBLIC(QtEnumEditorFactory)
@ -1865,19 +1970,36 @@ public:
void slotEnumNamesChanged(QtProperty *property, const QStringList &); void slotEnumNamesChanged(QtProperty *property, const QStringList &);
void slotEnumIconsChanged(QtProperty *property, const QMap<int, QIcon> &); void slotEnumIconsChanged(QtProperty *property, const QMap<int, QIcon> &);
void slotSetValue(int value); void slotSetValue(int value);
void slotResetProperty();
}; };
void QtEnumEditorFactoryPrivate::slotResetProperty()
{
QObject *object = q_ptr->sender();
const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd();
for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
if (itEditor.key() == object) {
QtProperty *property = itEditor.value();
QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
if (!manager)
return;
manager->emitResetProperty(property);
return;
}
}
void QtEnumEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, int value) void QtEnumEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
{ {
if (!m_createdEditors.contains(property)) if (!m_createdEditors.contains(property))
return; return;
QListIterator<QComboBox *> itEditor(m_createdEditors[property]); QListIterator<QtEnumEditWidget *> itEditor(m_createdEditors[property]);
while (itEditor.hasNext()) { while (itEditor.hasNext()) {
QComboBox *editor = itEditor.next(); QtEnumEditWidget *editor = itEditor.next();
editor->blockSignals(true); editor->setStateResetButton(property->isModified());
editor->setCurrentIndex(value); editor->blockComboBoxSignals(true);
editor->blockSignals(false); editor->setValue(value);
editor->blockComboBoxSignals(false);
} }
} }
@ -1893,17 +2015,17 @@ void QtEnumEditorFactoryPrivate::slotEnumNamesChanged(QtProperty *property,
QMap<int, QIcon> enumIcons = manager->enumIcons(property); QMap<int, QIcon> enumIcons = manager->enumIcons(property);
QListIterator<QComboBox *> itEditor(m_createdEditors[property]); QListIterator<QtEnumEditWidget *> itEditor(m_createdEditors[property]);
while (itEditor.hasNext()) { while (itEditor.hasNext()) {
QComboBox *editor = itEditor.next(); QtEnumEditWidget *editor = itEditor.next();
editor->blockSignals(true); editor->blockComboBoxSignals(true);
editor->clear(); editor->clearComboBox();
editor->addItems(enumNames); editor->addItems(enumNames);
const int nameCount = enumNames.count(); const int nameCount = enumNames.count();
for (int i = 0; i < nameCount; i++) for (int i = 0; i < nameCount; i++)
editor->setItemIcon(i, enumIcons.value(i)); editor->setItemIcon(i, enumIcons.value(i));
editor->setCurrentIndex(manager->value(property)); editor->setValue(manager->value(property));
editor->blockSignals(false); editor->blockComboBoxSignals(false);
} }
} }
@ -1918,23 +2040,23 @@ void QtEnumEditorFactoryPrivate::slotEnumIconsChanged(QtProperty *property,
return; return;
const QStringList enumNames = manager->enumNames(property); const QStringList enumNames = manager->enumNames(property);
QListIterator<QComboBox *> itEditor(m_createdEditors[property]); QListIterator<QtEnumEditWidget *> itEditor(m_createdEditors[property]);
while (itEditor.hasNext()) { while (itEditor.hasNext()) {
QComboBox *editor = itEditor.next(); QtEnumEditWidget *editor = itEditor.next();
editor->blockSignals(true); editor->blockComboBoxSignals(true);
const int nameCount = enumNames.count(); const int nameCount = enumNames.count();
for (int i = 0; i < nameCount; i++) for (int i = 0; i < nameCount; i++)
editor->setItemIcon(i, enumIcons.value(i)); editor->setItemIcon(i, enumIcons.value(i));
editor->setCurrentIndex(manager->value(property)); editor->setValue(manager->value(property));
editor->blockSignals(false); editor->blockComboBoxSignals(false);
} }
} }
void QtEnumEditorFactoryPrivate::slotSetValue(int value) void QtEnumEditorFactoryPrivate::slotSetValue(int value)
{ {
QObject *object = q_ptr->sender(); QObject *object = q_ptr->sender();
const QMap<QComboBox *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd(); const QMap<QtEnumEditWidget *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
for (QMap<QComboBox *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) for (QMap<QtEnumEditWidget *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
if (itEditor.key() == object) { if (itEditor.key() == object) {
QtProperty *property = itEditor.value(); QtProperty *property = itEditor.value();
QtEnumPropertyManager *manager = q_ptr->propertyManager(property); QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
@ -1995,18 +2117,19 @@ void QtEnumEditorFactory::connectPropertyManager(QtEnumPropertyManager *manager)
QWidget *QtEnumEditorFactory::createEditor(QtEnumPropertyManager *manager, QtProperty *property, QWidget *QtEnumEditorFactory::createEditor(QtEnumPropertyManager *manager, QtProperty *property,
QWidget *parent) QWidget *parent)
{ {
QComboBox *editor = d_ptr->createEditor(property, parent); QtEnumEditWidget *editor = d_ptr->createEditor(property, parent);
editor->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); editor->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
editor->view()->setTextElideMode(Qt::ElideRight);
QStringList enumNames = manager->enumNames(property); QStringList enumNames = manager->enumNames(property);
editor->addItems(enumNames); editor->addItems(enumNames);
QMap<int, QIcon> enumIcons = manager->enumIcons(property); QMap<int, QIcon> enumIcons = manager->enumIcons(property);
const int enumNamesCount = enumNames.count(); const int enumNamesCount = enumNames.count();
for (int i = 0; i < enumNamesCount; i++) for (int i = 0; i < enumNamesCount; i++)
editor->setItemIcon(i, enumIcons.value(i)); editor->setItemIcon(i, enumIcons.value(i));
editor->setCurrentIndex(manager->value(property)); editor->setValue(manager->value(property));
editor->setStateResetButton(property->isModified());
connect(editor, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetValue(int))); connect(editor, SIGNAL(resetProperty()), this, SLOT(slotResetProperty()));
connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int)));
connect(editor, SIGNAL(destroyed(QObject *)), connect(editor, SIGNAL(destroyed(QObject *)),
this, SLOT(slotEditorDestroyed(QObject *))); this, SLOT(slotEditorDestroyed(QObject *)));
return editor; return editor;
@ -2601,6 +2724,267 @@ void QtFontEditorFactory::disconnectPropertyManager(QtFontPropertyManager *manag
disconnect(manager, SIGNAL(valueChanged(QtProperty*,QFont)), this, SLOT(slotPropertyChanged(QtProperty*,QFont))); disconnect(manager, SIGNAL(valueChanged(QtProperty*,QFont)), this, SLOT(slotPropertyChanged(QtProperty*,QFont)));
} }
class QtTextEditWidget : public QWidget {
Q_OBJECT
public:
QtTextEditWidget(QWidget *parent);
bool eventFilter(QObject *obj, QEvent *ev);
public Q_SLOTS:
void setValue(const QString &value);
void setStateResetButton(bool enabled);
private Q_SLOTS:
void buttonClicked();
Q_SIGNALS:
void valueChanged(const QString &value);
void resetProperty();
private:
QLineEdit *m_lineEdit;
QToolButton *m_defaultButton;
QToolButton *m_button;
};
QtTextEditWidget::QtTextEditWidget(QWidget *parent) :
QWidget(parent),
m_lineEdit(new QLineEdit),
m_defaultButton(new QToolButton),
m_button(new QToolButton)
{
QHBoxLayout *lt = new QHBoxLayout(this);
lt->setContentsMargins(0, 0, 0, 0);
lt->setSpacing(0);
lt->addWidget(m_lineEdit);
m_lineEdit->setReadOnly(true);
m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
m_button->setFixedWidth(20);
m_button->setText(tr("..."));
m_button->installEventFilter(this);
setFocusProxy(m_button);
setFocusPolicy(m_button->focusPolicy());
m_defaultButton->setIcon(QIcon(":/trolltech/qtpropertybrowser/images/resetproperty.png"));
m_defaultButton->setMaximumWidth(16);
connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
connect(m_defaultButton, SIGNAL(clicked()), this, SIGNAL(resetProperty()));
lt->addWidget(m_button);
lt->addWidget(m_defaultButton);
m_defaultButton->setEnabled(false);
}
void QtTextEditWidget::setValue(const QString &value)
{
if (m_lineEdit->text() != value)
m_lineEdit->setText(value);
}
void QtTextEditWidget::setStateResetButton(bool enabled)
{
m_defaultButton->setEnabled(enabled);
}
void QtTextEditWidget::buttonClicked()
{
QGridLayout *gridLayout;
QPlainTextEdit *plainTextEdit;
QDialogButtonBox *buttonBox;
QDialog *dialog;
dialog = new QDialog(this);
dialog->resize(400, 300);
gridLayout = new QGridLayout(dialog);
plainTextEdit = new QPlainTextEdit(dialog);
gridLayout->addWidget(plainTextEdit, 0, 0, 1, 1);
buttonBox = new QDialogButtonBox(dialog);
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
gridLayout->addWidget(buttonBox, 1, 0, 1, 1);
QObject::connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
QObject::connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
plainTextEdit->textCursor().insertText(m_lineEdit->text());
dialog->setModal(true);
dialog->show();
int result = dialog->exec();
if (result == QDialog::Accepted)
{
QString newText = plainTextEdit->document()->toPlainText();
setValue(newText);
if (plainTextEdit->document()->isModified())
Q_EMIT valueChanged(newText);
}
delete dialog;
}
bool QtTextEditWidget::eventFilter(QObject *obj, QEvent *ev)
{
if (obj == m_button) {
switch (ev->type()) {
case QEvent::KeyPress:
case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate
switch (static_cast<const QKeyEvent*>(ev)->key()) {
case Qt::Key_Escape:
case Qt::Key_Enter:
case Qt::Key_Return:
ev->ignore();
return true;
default:
break;
}
}
break;
default:
break;
}
}
return QWidget::eventFilter(obj, ev);
}
// QtLineEditFactory
class QtTextEditorFactoryPrivate : public EditorFactoryPrivate<QtTextEditWidget>
{
QtTextEditorFactory *q_ptr;
Q_DECLARE_PUBLIC(QtTextEditorFactory)
public:
void slotPropertyChanged(QtProperty *property, const QString &value);
void slotSetValue(const QString &value);
void slotResetProperty();
};
void QtTextEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
const QString &value)
{
const PropertyToEditorListMap::iterator it = m_createdEditors.find(property);
if (it == m_createdEditors.end())
return;
QListIterator<QtTextEditWidget *> itEditor(it.value());
while (itEditor.hasNext())
{
QtTextEditWidget *editor = itEditor.next();
editor->setValue(value);
editor->setStateResetButton(property->isModified());
}
}
void QtTextEditorFactoryPrivate::slotSetValue(const QString &value)
{
QObject *object = q_ptr->sender();
const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd();
for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
if (itEditor.key() == object) {
QtProperty *property = itEditor.value();
QtTextPropertyManager *manager = q_ptr->propertyManager(property);
if (!manager)
return;
manager->setValue(property, value);
return;
}
}
void QtTextEditorFactoryPrivate::slotResetProperty()
{
QObject *object = q_ptr->sender();
const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd();
for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
if (itEditor.key() == object) {
QtProperty *property = itEditor.value();
QtTextPropertyManager *manager = q_ptr->propertyManager(property);
if (!manager)
return;
manager->emitResetProperty(property);
return;
}
}
/*!
\class QtTextEditFactory
\brief The QtTextEditFactory class provides QTextEdit widgets for
properties created by QtStringPropertyManager objects.
\sa QtAbstractEditorFactory, QtStringPropertyManager
*/
/*!
Creates a factory with the given \a parent.
*/
QtTextEditorFactory::QtTextEditorFactory(QObject *parent)
: QtAbstractEditorFactory<QtTextPropertyManager>(parent)
{
d_ptr = new QtTextEditorFactoryPrivate();
d_ptr->q_ptr = this;
}
/*!
Destroys this factory, and all the widgets it has created.
*/
QtTextEditorFactory::~QtTextEditorFactory()
{
qDeleteAll(d_ptr->m_editorToProperty.keys());
delete d_ptr;
}
/*!
\internal
Reimplemented from the QtAbstractEditorFactory class.
*/
void QtTextEditorFactory::connectPropertyManager(QtTextPropertyManager *manager)
{
connect(manager, SIGNAL(valueChanged(QtProperty *, const QString &)),
this, SLOT(slotPropertyChanged(QtProperty *, const QString &)));
}
/*!
\internal
Reimplemented from the QtAbstractEditorFactory class.
*/
QWidget *QtTextEditorFactory::createEditor(QtTextPropertyManager *manager,
QtProperty *property, QWidget *parent)
{
QtTextEditWidget *editor = d_ptr->createEditor(property, parent);
editor->setValue(manager->value(property));
editor->setStateResetButton(property->isModified());
connect(editor, SIGNAL(resetProperty()), this, SLOT(slotResetProperty()));
connect(editor, SIGNAL(valueChanged(QString)), this, SLOT(slotSetValue(QString)));
connect(editor, SIGNAL(destroyed(QObject *)), this, SLOT(slotEditorDestroyed(QObject *)));
return editor;
}
/*!
\internal
Reimplemented from the QtAbstractEditorFactory class.
*/
void QtTextEditorFactory::disconnectPropertyManager(QtTextPropertyManager *manager)
{
disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QString &)),
this, SLOT(slotPropertyChanged(QtProperty *, const QString &)));
}
#if QT_VERSION >= 0x040400 #if QT_VERSION >= 0x040400
QT_END_NAMESPACE QT_END_NAMESPACE
#endif #endif

@ -186,6 +186,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, bool)) Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, bool))
Q_PRIVATE_SLOT(d_func(), void slotSetValue(bool)) Q_PRIVATE_SLOT(d_func(), void slotSetValue(bool))
Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
Q_PRIVATE_SLOT(d_func(), void slotResetProperty())
}; };
class QtDoubleSpinBoxFactoryPrivate; class QtDoubleSpinBoxFactoryPrivate;
@ -373,6 +374,7 @@ private:
const QMap<int, QIcon> &)) const QMap<int, QIcon> &))
Q_PRIVATE_SLOT(d_func(), void slotSetValue(int)) Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
Q_PRIVATE_SLOT(d_func(), void slotResetProperty())
}; };
class QtCursorEditorFactoryPrivate; class QtCursorEditorFactoryPrivate;
@ -441,6 +443,29 @@ private:
Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QFont &)) Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QFont &))
}; };
class QtTextEditorFactoryPrivate;
class QT_QTPROPERTYBROWSER_EXPORT QtTextEditorFactory : public QtAbstractEditorFactory<QtTextPropertyManager>
{
Q_OBJECT
public:
QtTextEditorFactory(QObject *parent = 0);
~QtTextEditorFactory();
protected:
void connectPropertyManager(QtTextPropertyManager *manager);
QWidget *createEditor(QtTextPropertyManager *manager, QtProperty *property,
QWidget *parent);
void disconnectPropertyManager(QtTextPropertyManager *manager);
private:
QtTextEditorFactoryPrivate *d_ptr;
Q_DECLARE_PRIVATE(QtTextEditorFactory)
Q_DISABLE_COPY(QtTextEditorFactory)
Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QString &))
Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QString &))
Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
Q_PRIVATE_SLOT(d_func(), void slotResetProperty())
};
#if QT_VERSION >= 0x040400 #if QT_VERSION >= 0x040400
QT_END_NAMESPACE QT_END_NAMESPACE
#endif #endif

@ -808,6 +808,11 @@ QtProperty *QtAbstractPropertyManager::addProperty(const QString &name)
return property; return property;
} }
void QtAbstractPropertyManager::emitResetProperty(QtProperty *property)
{
emit resetProperty(property);
}
/*! /*!
Creates a property. Creates a property.

@ -170,6 +170,7 @@ public:
void clear() const; void clear() const;
QtProperty *addProperty(const QString &name = QString()); QtProperty *addProperty(const QString &name = QString());
void emitResetProperty(QtProperty *property);
Q_SIGNALS: Q_SIGNALS:
void propertyInserted(QtProperty *property, void propertyInserted(QtProperty *property,
@ -177,6 +178,7 @@ Q_SIGNALS:
void propertyChanged(QtProperty *property); void propertyChanged(QtProperty *property);
void propertyRemoved(QtProperty *property, QtProperty *parent); void propertyRemoved(QtProperty *property, QtProperty *parent);
void propertyDestroyed(QtProperty *property); void propertyDestroyed(QtProperty *property);
void resetProperty(QtProperty *property);
protected: protected:
virtual bool hasValue(const QtProperty *property) const; virtual bool hasValue(const QtProperty *property) const;
virtual QIcon valueIcon(const QtProperty *property) const; virtual QIcon valueIcon(const QtProperty *property) const;

@ -18,6 +18,7 @@
<file>images/cursor-vsplit.png</file> <file>images/cursor-vsplit.png</file>
<file>images/cursor-wait.png</file> <file>images/cursor-wait.png</file>
<file>images/cursor-whatsthis.png</file> <file>images/cursor-whatsthis.png</file>
<file>images/resetproperty.png</file>
</qresource> </qresource>
</RCC> </RCC>

@ -91,6 +91,7 @@
#include <QtGui/QHBoxLayout> #include <QtGui/QHBoxLayout>
#include <QtGui/QMouseEvent> #include <QtGui/QMouseEvent>
#include <QtGui/QCheckBox> #include <QtGui/QCheckBox>
#include <QtGui/QToolButton>
#include <QtGui/QLineEdit> #include <QtGui/QLineEdit>
#include <QtGui/QMenu> #include <QtGui/QMenu>
@ -260,16 +261,25 @@ QString QtPropertyBrowserUtils::fontValueText(const QFont &f)
QtBoolEdit::QtBoolEdit(QWidget *parent) : QtBoolEdit::QtBoolEdit(QWidget *parent) :
QWidget(parent), QWidget(parent),
m_checkBox(new QCheckBox(this)), m_checkBox(new QCheckBox(this)),
m_defaultButton(new QToolButton(this)),
m_textVisible(true) m_textVisible(true)
{ {
m_defaultButton->setIcon(QIcon(":/trolltech/qtpropertybrowser/images/resetproperty.png"));
m_defaultButton->setMaximumWidth(16);
m_defaultButton->setEnabled(false);
QHBoxLayout *lt = new QHBoxLayout; QHBoxLayout *lt = new QHBoxLayout;
if (QApplication::layoutDirection() == Qt::LeftToRight) if (QApplication::layoutDirection() == Qt::LeftToRight)
lt->setContentsMargins(4, 0, 0, 0); lt->setContentsMargins(4, 0, 0, 0);
else else
lt->setContentsMargins(0, 0, 4, 0); lt->setContentsMargins(0, 0, 4, 0);
lt->addWidget(m_checkBox); lt->addWidget(m_checkBox);
lt->addWidget(m_defaultButton);
setLayout(lt); setLayout(lt);
connect(m_checkBox, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool))); connect(m_checkBox, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool)));
connect(m_defaultButton, SIGNAL(clicked()), this, SIGNAL(resetProperty()));
setFocusProxy(m_checkBox); setFocusProxy(m_checkBox);
m_checkBox->setText(QString()); m_checkBox->setText(QString());
} }
@ -293,6 +303,11 @@ void QtBoolEdit::setCheckState(Qt::CheckState state)
m_checkBox->setCheckState(state); m_checkBox->setCheckState(state);
} }
void QtBoolEdit::setStateResetButton(bool enabled)
{
m_defaultButton->setEnabled(enabled);
}
bool QtBoolEdit::isChecked() const bool QtBoolEdit::isChecked() const
{ {
return m_checkBox->isChecked(); return m_checkBox->isChecked();

@ -110,6 +110,7 @@ QT_BEGIN_NAMESPACE
class QMouseEvent; class QMouseEvent;
class QCheckBox; class QCheckBox;
class QToolButton;
class QLineEdit; class QLineEdit;
class QtCursorDatabase class QtCursorDatabase
@ -154,6 +155,7 @@ public:
Qt::CheckState checkState() const; Qt::CheckState checkState() const;
void setCheckState(Qt::CheckState state); void setCheckState(Qt::CheckState state);
void setStateResetButton(bool enabled);
bool isChecked() const; bool isChecked() const;
void setChecked(bool c); void setChecked(bool c);
@ -162,12 +164,14 @@ public:
Q_SIGNALS: Q_SIGNALS:
void toggled(bool); void toggled(bool);
void resetProperty();
protected: protected:
void mousePressEvent(QMouseEvent * event); void mousePressEvent(QMouseEvent * event);
private: private:
QCheckBox *m_checkBox; QCheckBox *m_checkBox;
QToolButton *m_defaultButton;
bool m_textVisible; bool m_textVisible;
}; };

@ -99,6 +99,7 @@
#include <QtGui/QApplication> #include <QtGui/QApplication>
#include <QtGui/QPainter> #include <QtGui/QPainter>
#include <QtGui/QLabel> #include <QtGui/QLabel>
#include <QStringRef>
#include <limits.h> #include <limits.h>
#include <float.h> #include <float.h>
@ -6457,6 +6458,20 @@ void QtCursorPropertyManager::uninitializeProperty(QtProperty *property)
d_ptr->m_values.remove(property); d_ptr->m_values.remove(property);
} }
QString QtTextPropertyManager::valueText(const QtProperty *property) const
{
QString text = QtStringPropertyManager::valueText(property);
for (int i = 0; i < text.size(); i++)
{
if (text.at(i) == '\n')
{
QStringRef ret(&text, 0, i);
return ret.toString() + " ...";
}
}
return text;
}
#if QT_VERSION >= 0x040400 #if QT_VERSION >= 0x040400
QT_END_NAMESPACE QT_END_NAMESPACE
#endif #endif

@ -160,8 +160,10 @@ public:
public Q_SLOTS: public Q_SLOTS:
void setValue(QtProperty *property, bool val); void setValue(QtProperty *property, bool val);
Q_SIGNALS: Q_SIGNALS:
void valueChanged(QtProperty *property, bool val); void valueChanged(QtProperty *property, bool val);
protected: protected:
QString valueText(const QtProperty *property) const; QString valueText(const QtProperty *property) const;
QIcon valueIcon(const QtProperty *property) const; QIcon valueIcon(const QtProperty *property) const;
@ -789,6 +791,16 @@ private:
Q_DISABLE_COPY(QtCursorPropertyManager) Q_DISABLE_COPY(QtCursorPropertyManager)
}; };
class QT_QTPROPERTYBROWSER_EXPORT QtTextPropertyManager : public QtStringPropertyManager
{
Q_OBJECT
public:
QtTextPropertyManager(QObject *parent = 0):QtStringPropertyManager(parent) {}
protected:
virtual QString valueText(const QtProperty *property) const;
};
#if QT_VERSION >= 0x040400 #if QT_VERSION >= 0x040400
QT_END_NAMESPACE QT_END_NAMESPACE
#endif #endif

@ -104,7 +104,11 @@ static inline QString msgCoreLoadFailure(const QString &why)
return QCoreApplication::translate("Application", "Failed to load Core plugin: %1").arg(why); return QCoreApplication::translate("Application", "Failed to load Core plugin: %1").arg(why);
} }
sint main(int argc, char **argv) #ifdef NL_OS_WINDOWS
int __stdcall WinMain(void *hInstance, void *hPrevInstance, void *lpCmdLine, int nShowCmd)
#else // NL_OS_WINDOWS
int main(int argc, char **argv)
#endif // NL_OS_WINDOWS
{ {
// go nel! // go nel!
new NLMISC::CApplicationContext; new NLMISC::CApplicationContext;
@ -129,7 +133,11 @@ sint main(int argc, char **argv)
nlinfo("Welcome to NeL Object Viewer Qt!"); nlinfo("Welcome to NeL Object Viewer Qt!");
} }
QApplication::setGraphicsSystem("raster"); QApplication::setGraphicsSystem("raster");
#ifdef NL_OS_WINDOWS
QApplication app(__argc, __argv);
#else // NL_OS_WINDOWS
QApplication app(argc, argv); QApplication app(argc, argv);
#endif // NL_OS_WINDOWS
QSplashScreen *splash = new QSplashScreen(); QSplashScreen *splash = new QSplashScreen();
splash->setPixmap(QPixmap(":/images/nel_ide_load.png")); splash->setPixmap(QPixmap(":/images/nel_ide_load.png"));
splash->show(); splash->show();

@ -8,6 +8,7 @@ ADD_SUBDIRECTORY(object_viewer)
ADD_SUBDIRECTORY(georges_editor) ADD_SUBDIRECTORY(georges_editor)
ADD_SUBDIRECTORY(material_editor) ADD_SUBDIRECTORY(material_editor)
ADD_SUBDIRECTORY(world_editor)
IF(WITH_GUI) IF(WITH_GUI)
ADD_SUBDIRECTORY(gui_editor) ADD_SUBDIRECTORY(gui_editor)
ENDIF(WITH_GUI) ENDIF(WITH_GUI)
@ -16,6 +17,7 @@ ADD_SUBDIRECTORY(translation_manager)
ADD_SUBDIRECTORY(bnp_manager) ADD_SUBDIRECTORY(bnp_manager)
# Note: Temporarily disabled until development continues. # Note: Temporarily disabled until development continues.
#ADD_SUBDIRECTORY(zone_painter) #ADD_SUBDIRECTORY(zone_painter)
# Ryzom Specific Plugins # Ryzom Specific Plugins
IF(WITH_RYZOM AND WITH_RYZOM_TOOLS) IF(WITH_RYZOM AND WITH_RYZOM_TOOLS)
ADD_SUBDIRECTORY(mission_compiler) ADD_SUBDIRECTORY(mission_compiler)

@ -57,15 +57,15 @@ ADD_DEFINITIONS(-DCORE_LIBRARY ${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${
IF(WIN32) IF(WIN32)
IF(WITH_INSTALL_LIBRARIES) IF(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_core LIBRARY DESTINATION ${NL_LIB_PREFIX} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d) INSTALL(TARGETS ovqt_plugin_core LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
ELSE(WITH_INSTALL_LIBRARIES) ELSE(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_core LIBRARY DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d) INSTALL(TARGETS ovqt_plugin_core LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
ENDIF(WITH_INSTALL_LIBRARIES) ENDIF(WITH_INSTALL_LIBRARIES)
ELSE(WIN32) ELSE(WIN32)
IF(WITH_INSTALL_LIBRARIES) IF(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_core LIBRARY DESTINATION ${NL_LIB_PREFIX} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d) INSTALL(TARGETS ovqt_plugin_core LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d)
ELSE(WITH_INSTALL_LIBRARIES) ELSE(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_core LIBRARY DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d) INSTALL(TARGETS ovqt_plugin_core LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d)
ENDIF(WITH_INSTALL_LIBRARIES) ENDIF(WITH_INSTALL_LIBRARIES)
ENDIF(WIN32) ENDIF(WIN32)

@ -40,6 +40,20 @@ NL_ADD_LIB_SUFFIX(ovqt_plugin_disp_sheet_id)
ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS}) ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS})
INSTALL(TARGETS ovqt_plugin_disp_sheet_id LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} ARCHIVE DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
IF(WIN32)
IF(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_disp_sheet_id LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
ELSE(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_disp_sheet_id LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
ENDIF(WITH_INSTALL_LIBRARIES)
ELSE(WIN32)
IF(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_disp_sheet_id LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d)
ELSE(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_disp_sheet_id LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d)
ENDIF(WITH_INSTALL_LIBRARIES)
ENDIF(WIN32)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ovqt_plugin_disp_sheet_id.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ovqt_plugin_disp_sheet_id.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d)

@ -38,6 +38,19 @@ NL_ADD_LIB_SUFFIX(ovqt_plugin_example)
ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS}) ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS})
INSTALL(TARGETS ovqt_plugin_example LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} ARCHIVE DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d) IF(WIN32)
IF(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_example LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
ELSE(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_example LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
ENDIF(WITH_INSTALL_LIBRARIES)
ELSE(WIN32)
IF(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_example LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d)
ELSE(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_example LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d)
ENDIF(WITH_INSTALL_LIBRARIES)
ENDIF(WIN32)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ovqt_plugin_example.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ovqt_plugin_example.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d)

@ -44,9 +44,24 @@ NL_ADD_LIB_SUFFIX(ovqt_plugin_georges_editor)
ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS}) ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS})
INSTALL(TARGETS ovqt_plugin_georges_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} ARCHIVE DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ovqt_plugin_georges_editor.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d)
IF(WITH_PCH) IF(WITH_PCH)
ADD_NATIVE_PRECOMPILED_HEADER(ovqt_plugin_georges_editor ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.h ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.cpp) ADD_NATIVE_PRECOMPILED_HEADER(ovqt_plugin_georges_editor ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.h ${CMAKE_CURRENT_SOURCE_DIR}/stdpch.cpp)
ENDIF(WITH_PCH) ENDIF(WITH_PCH)
IF(WIN32)
IF(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_georges_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
ELSE(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_georges_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
ENDIF(WITH_INSTALL_LIBRARIES)
ELSE(WIN32)
IF(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_georges_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d)
ELSE(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_georges_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d)
ENDIF(WITH_INSTALL_LIBRARIES)
ENDIF(WIN32)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ovqt_plugin_georges_editor.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d)

@ -364,7 +364,7 @@ namespace GeorgesQt
// ((CForm*)(UForm*)Form)->Header.MinorVersion++; // ((CForm*)(UForm*)Form)->Header.MinorVersion++;
// }*/ // }*/
// //((CForm*)(UForm*)Form)->write (xmlStream.getDocument (), lpszPathName, theApp.Georges4CVS); // //((CForm*)(UForm*)Form)->write (xmlStream.getDocument (), lpszPathName, theApp.Georges4CVS);
m_form->write(file, false); m_form->write(file);
setWindowTitle(windowTitle().remove("*")); setWindowTitle(windowTitle().remove("*"));
m_modified = false; m_modified = false;
// //if (strcmp (xmlStream.getErrorString (), "") != 0) // //if (strcmp (xmlStream.getErrorString (), "") != 0)

@ -82,4 +82,18 @@ NL_ADD_LIB_SUFFIX(ovqt_plugin_gui_editor)
ADD_DEFINITIONS(-DGUI_EDITOR_LIBRARY ${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS}) ADD_DEFINITIONS(-DGUI_EDITOR_LIBRARY ${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS})
INSTALL(TARGETS ovqt_plugin_gui_editor LIBRARY DESTINATION lib RUNTIME DESTINATION bin ARCHIVE DESTINATION lib COMPONENT tools3d) IF(WIN32)
IF(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_gui_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
ELSE(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_gui_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
ENDIF(WITH_INSTALL_LIBRARIES)
ELSE(WIN32)
IF(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_gui_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d)
ELSE(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_gui_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d)
ENDIF(WITH_INSTALL_LIBRARIES)
ENDIF(WIN32)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ovqt_plugin_gui_editor.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d)

@ -138,7 +138,7 @@ namespace GUIEditor
info.description = value.toUtf8().constData(); info.description = value.toUtf8().constData();
else else
if( key == "icon" ) if( key == "icon" )
info.icon == value.toUtf8().constData(); info.icon = value.toUtf8().constData();
else else
if( key == "abstract" ) if( key == "abstract" )
{ {

@ -11,9 +11,19 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.
SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR landscape_editor_plugin.h SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR landscape_editor_plugin.h
landscape_editor_window.h landscape_editor_window.h
landscape_scene_base.h
landscape_scene.h
list_zones_model.h
list_zones_widget.h
landscape_view.h
project_settings_dialog.h
snapshot_dialog.h
) )
SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS landscape_editor_window.ui SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS landscape_editor_window.ui
list_zones_widget.ui
project_settings_dialog.ui
shapshot_dialog.ui
) )
SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_RCS landscape_editor.qrc) SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_RCS landscape_editor.qrc)
@ -31,13 +41,13 @@ SOURCE_GROUP(QtGeneratedMocQrcSrc FILES ${OVQT_PLUGIN_LANDSCAPE_EDITOR_MOC_SRC}
SOURCE_GROUP("Landscape Editor Plugin" FILES ${SRC}) SOURCE_GROUP("Landscape Editor Plugin" FILES ${SRC})
SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC}) SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC})
ADD_LIBRARY(ovqt_plugin_landscape_editor MODULE ${SRC} ADD_LIBRARY(ovqt_plugin_landscape_editor SHARED ${SRC}
${OVQT_PLUGIN_LANDSCAPE_EDITOR_MOC_SRC} ${OVQT_PLUGIN_LANDSCAPE_EDITOR_MOC_SRC}
${OVQT_EXT_SYS_SRC} ${OVQT_EXT_SYS_SRC}
${OVQT_PLUGIN_LANDSCAPE_EDITOR_UI_HDRS} ${OVQT_PLUGIN_LANDSCAPE_EDITOR_UI_HDRS}
${OVQT_PLUGIN_LANDSCAPE_EDITOR_RC_SRCS}) ${OVQT_PLUGIN_LANDSCAPE_EDITOR_RC_SRCS})
TARGET_LINK_LIBRARIES(ovqt_plugin_landscape_editor ovqt_plugin_core nelmisc nel3d ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY}) TARGET_LINK_LIBRARIES(ovqt_plugin_landscape_editor ovqt_plugin_core nelmisc nel3d nelgeorges nelligo ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY})
NL_DEFAULT_PROPS(ovqt_plugin_landscape_editor "NeL, Tools, 3D: Object Viewer Qt Plugin: Landscape Editor") NL_DEFAULT_PROPS(ovqt_plugin_landscape_editor "NeL, Tools, 3D: Object Viewer Qt Plugin: Landscape Editor")
NL_ADD_RUNTIME_FLAGS(ovqt_plugin_landscape_editor) NL_ADD_RUNTIME_FLAGS(ovqt_plugin_landscape_editor)
@ -45,6 +55,20 @@ NL_ADD_LIB_SUFFIX(ovqt_plugin_landscape_editor)
ADD_DEFINITIONS(-DLANDSCAPE_EDITOR_LIBRARY ${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS}) ADD_DEFINITIONS(-DLANDSCAPE_EDITOR_LIBRARY ${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS})
INSTALL(TARGETS ovqt_plugin_landscape_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} ARCHIVE DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
#INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ovqt_plugin_landscape_editor.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d)
IF(WIN32)
IF(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_landscape_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
ELSE(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_landscape_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
ENDIF(WITH_INSTALL_LIBRARIES)
ELSE(WIN32)
IF(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_landscape_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d)
ELSE(WITH_INSTALL_LIBRARIES)
INSTALL(TARGETS ovqt_plugin_landscape_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT tools3d)
ENDIF(WITH_INSTALL_LIBRARIES)
ENDIF(WIN32)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ovqt_plugin_landscape_editor.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d)

@ -0,0 +1,540 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Project includes
#include "builder_zone.h"
#include "list_zones_widget.h"
#include "landscape_actions.h"
// NeL includes
#include <nel/misc/debug.h>
// Qt includes
#include <QtCore/QDir>
#include <QtGui/QMessageBox>
#include <QtGui/QProgressDialog>
namespace LandscapeEditor
{
int LandCounter = 0;
ZoneBuilder::ZoneBuilder(LandscapeScene *landscapeScene, ListZonesWidget *listZonesWidget, QUndoStack *undoStack)
: m_currentZoneRegion(-1),
m_pixmapDatabase(0),
m_listZonesWidget(listZonesWidget),
m_landscapeScene(landscapeScene),
m_undoStack(undoStack)
{
nlassert(m_landscapeScene);
m_pixmapDatabase = new PixmapDatabase();
m_lastPathName = "";
}
ZoneBuilder::~ZoneBuilder()
{
delete m_pixmapDatabase;
}
bool ZoneBuilder::init(const QString &pathName, bool displayProgress)
{
if (pathName.isEmpty())
return false;
if (pathName != m_lastPathName)
{
m_lastPathName = pathName;
QString zoneBankPath = pathName;
zoneBankPath += "/zoneligos/";
// Init the ZoneBank
m_zoneBank.reset();
if (!initZoneBank (zoneBankPath))
{
m_zoneBank.reset();
return false;
}
// Construct the DataBase from the ZoneBank
QString zoneBitmapPath = pathName;
zoneBitmapPath += "/zonebitmaps/";
m_pixmapDatabase->reset();
if (!m_pixmapDatabase->loadPixmaps(zoneBitmapPath, m_zoneBank, displayProgress))
{
m_zoneBank.reset();
return false;
}
}
return true;
}
void ZoneBuilder::actionLigoTile(const LigoData &data, const ZonePosition &zonePos)
{
if (m_undoStack == 0)
return;
checkBeginMacro();
// nlinfo(QString("%1 %2 %3 (%4 %5)").arg(data.zoneName.c_str()).arg(zonePos.x).arg(zonePos.y).arg(data.posX).arg(data.posY).toUtf8().constData());
m_zonePositionList.push_back(zonePos);
m_undoStack->push(new LigoTileCommand(data, zonePos, this, m_landscapeScene));
}
void ZoneBuilder::actionLigoMove(uint index, sint32 deltaX, sint32 deltaY)
{
if (m_undoStack == 0)
return;
checkBeginMacro();
//m_undoStack->push(new LigoMoveCommand(index, deltaX, deltaY, this));
}
void ZoneBuilder::actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY)
{
if (m_undoStack == 0)
return;
checkBeginMacro();
// nlinfo(QString("minX=%1 maxX=%2 minY=%3 maxY=%4").arg(newMinX).arg(newMaxX).arg(newMinY).arg(newMaxY).toUtf8().constData());
m_undoStack->push(new LigoResizeCommand(index, newMinX, newMaxX, newMinY, newMaxY, this));
}
void ZoneBuilder::addZone(sint32 posX, sint32 posY)
{
// Read-only mode
if ((m_listZonesWidget == 0) || (m_undoStack == 0))
return;
if (m_landscapeMap.empty())
return;
// Check zone name
std::string zoneName = m_listZonesWidget->currentZoneName().toUtf8().constData();
if (zoneName.empty())
return;
BuilderZoneRegion *builderZoneRegion = m_landscapeMap.value(m_currentZoneRegion).builderZoneRegion;
builderZoneRegion->init(this);
uint8 rot = uint8(m_listZonesWidget->currentRot());
uint8 flip = uint8(m_listZonesWidget->currentFlip());
NLLIGO::CZoneBankElement *zoneBankElement = getZoneBank().getElementByZoneName(zoneName);
m_titleAction = QString("Add zone %1,%2").arg(posX).arg(posY);
m_createdAction = false;
m_zonePositionList.clear();
if (m_listZonesWidget->isForce())
{
builderZoneRegion->addForce(posX, posY, rot, flip, zoneBankElement);
}
else
{
if (m_listZonesWidget->isNotPropogate())
builderZoneRegion->addNotPropagate(posX, posY, rot, flip, zoneBankElement);
else
builderZoneRegion->add(posX, posY, rot, flip, zoneBankElement);
}
checkEndMacro();
}
void ZoneBuilder::addTransition(const sint32 posX, const sint32 posY)
{
// Read-only mode
if ((m_listZonesWidget == 0) || (m_undoStack == 0))
return;
if (m_landscapeMap.empty())
return;
m_titleAction = QString("Transition zone %1,%2").arg(posX).arg(posY);
m_createdAction = false;
m_zonePositionList.clear();
nlinfo(QString("trans %1,%2").arg(posX).arg(posY).toUtf8().constData());
sint32 x = (sint32)floor(float(posX) / m_landscapeScene->cellSize());
sint32 y = (sint32)floor(float(posY) / m_landscapeScene->cellSize());
sint32 k;
// Detect if we are in a transition square to switch
BuilderZoneRegion *builderZoneRegion = m_landscapeMap.value(m_currentZoneRegion).builderZoneRegion;
builderZoneRegion->init(this);
const NLLIGO::CZoneRegion &zoneRegion = currentZoneRegion()->ligoZoneRegion();
bool bCutEdgeTouched = false;
for (uint8 transPos = 0; transPos < 4; ++transPos)
{
uint ce = zoneRegion.getCutEdge(x, y, transPos);
if ((ce > 0) && (ce < 3))
for (k = 0; k < 2; ++k)
{
float xTrans, yTrans;
if ((transPos == 0) || (transPos == 1))
{
if (ce == 1)
xTrans = m_landscapeScene->cellSize() / 3.0f;
else
xTrans = 2.0f * m_landscapeScene->cellSize() / 3.0f;
}
else
{
if (transPos == 2)
xTrans = 0;
else
xTrans = m_landscapeScene->cellSize();
}
xTrans += x * m_landscapeScene->cellSize();
if ((transPos == 2) || (transPos == 3))
{
if (ce == 1)
yTrans = m_landscapeScene->cellSize() / 3.0f;
else
yTrans = 2.0f * m_landscapeScene->cellSize() / 3.0f;
}
else
{
if (transPos == 1)
yTrans = 0;
else
yTrans = m_landscapeScene->cellSize();
}
yTrans += y * m_landscapeScene->cellSize();
if ((posX >= (xTrans - m_landscapeScene->cellSize() / 12.0f)) &&
(posX <= (xTrans + m_landscapeScene->cellSize() / 12.0f)) &&
(posY >= (yTrans - m_landscapeScene->cellSize() / 12.0f)) &&
(posY <= (yTrans + m_landscapeScene->cellSize() / 12.0f)))
{
builderZoneRegion->invertCutEdge (x, y, transPos);
bCutEdgeTouched = true;
}
ce = 3 - ce;
}
}
// If not clicked to change the cutEdge so the user want to change the transition
if (!bCutEdgeTouched)
{
builderZoneRegion->cycleTransition (x, y);
}
checkEndMacro();
}
void ZoneBuilder::delZone(const sint32 posX, const sint32 posY)
{
if ((m_listZonesWidget == 0) || (m_undoStack == 0))
return;
if (m_landscapeMap.empty())
return;
m_titleAction = QString("Del zone %1,%2").arg(posX).arg(posY);
m_createdAction = false;
BuilderZoneRegion *builderZoneRegion = m_landscapeMap.value(m_currentZoneRegion).builderZoneRegion;
builderZoneRegion->init(this);
builderZoneRegion->del(posX, posY);
checkEndMacro();
}
int ZoneBuilder::createZoneRegion()
{
LandscapeItem landItem;
landItem.zoneRegionObject = new ZoneRegionObject();
landItem.builderZoneRegion = new BuilderZoneRegion(LandCounter);
landItem.builderZoneRegion->init(this);
landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion());
m_landscapeMap.insert(LandCounter, landItem);
if (m_currentZoneRegion == -1)
setCurrentZoneRegion(LandCounter);
calcMask();
return LandCounter++;
}
int ZoneBuilder::createZoneRegion(const QString &fileName)
{
LandscapeItem landItem;
landItem.zoneRegionObject = new ZoneRegionObject();
landItem.zoneRegionObject->load(fileName.toUtf8().constData());
if (checkOverlaps(landItem.zoneRegionObject->ligoZoneRegion()))
{
delete landItem.zoneRegionObject;
return -1;
}
landItem.builderZoneRegion = new BuilderZoneRegion(LandCounter);
landItem.builderZoneRegion->init(this);
m_landscapeScene->addZoneRegion(landItem.zoneRegionObject->ligoZoneRegion());
landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion());
m_landscapeMap.insert(LandCounter, landItem);
if (m_currentZoneRegion == -1)
setCurrentZoneRegion(LandCounter);
calcMask();
return LandCounter++;
}
void ZoneBuilder::deleteZoneRegion(int id)
{
if (m_landscapeMap.contains(id))
{
if (m_landscapeMap.value(id).rectItem != 0)
delete m_landscapeMap.value(id).rectItem;
m_landscapeScene->delZoneRegion(m_landscapeMap.value(id).zoneRegionObject->ligoZoneRegion());
delete m_landscapeMap.value(id).zoneRegionObject;
delete m_landscapeMap.value(id).builderZoneRegion;
m_landscapeMap.remove(id);
calcMask();
}
else
nlwarning("Landscape (id %i) not found", id);
}
void ZoneBuilder::setCurrentZoneRegion(int id)
{
if (m_landscapeMap.contains(id))
{
if (currentIdZoneRegion() != -1)
{
NLLIGO::CZoneRegion &ligoRegion = m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject->ligoZoneRegion();
m_landscapeMap[m_currentZoneRegion].rectItem = m_landscapeScene->createLayerBlackout(ligoRegion);
}
delete m_landscapeMap.value(id).rectItem;
m_landscapeMap[id].rectItem = 0;
m_currentZoneRegion = id;
calcMask();
}
else
nlwarning("Landscape (id %i) not found", id);
}
int ZoneBuilder::currentIdZoneRegion() const
{
return m_currentZoneRegion;
}
ZoneRegionObject *ZoneBuilder::currentZoneRegion() const
{
ZoneRegionObject *result = 0;
if (m_landscapeMap.contains(m_currentZoneRegion))
result = m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject;
return result;
}
int ZoneBuilder::countZoneRegion() const
{
return m_landscapeMap.size();
}
ZoneRegionObject *ZoneBuilder::zoneRegion(int id) const
{
ZoneRegionObject *result = 0;
if (m_landscapeMap.contains(id))
result = m_landscapeMap.value(id).zoneRegionObject;
return result;
}
bool ZoneBuilder::ligoData(LigoData &data, const ZonePosition &zonePos)
{
if (m_landscapeMap.contains(zonePos.region))
{
m_landscapeMap.value(zonePos.region).zoneRegionObject->ligoData(data, zonePos.x, zonePos.y);
return true;
}
return false;
}
void ZoneBuilder::setLigoData(LigoData &data, const ZonePosition &zonePos)
{
if (m_landscapeMap.contains(zonePos.region))
m_landscapeMap.value(zonePos.region).zoneRegionObject->setLigoData(data, zonePos.x, zonePos.y);
}
bool ZoneBuilder::initZoneBank (const QString &pathName)
{
QDir *dir = new QDir(pathName);
QStringList filters;
filters << "*.ligozone";
// Find all ligozone files in dir
QStringList listFiles = dir->entryList(filters, QDir::Files);
std::string error;
Q_FOREACH(QString file, listFiles)
{
//nlinfo(file.toUtf8().constData());
if (!m_zoneBank.addElement((pathName + file).toUtf8().constData(), error))
QMessageBox::critical(0, QObject::tr("Landscape editor"), QString(error.c_str()), QMessageBox::Ok);
}
delete dir;
return true;
}
PixmapDatabase *ZoneBuilder::pixmapDatabase() const
{
return m_pixmapDatabase;
}
QString ZoneBuilder::dataPath() const
{
return m_lastPathName;
}
bool ZoneBuilder::getZoneMask(sint32 x, sint32 y)
{
if ((x < m_minX) || (x > m_maxX) ||
(y < m_minY) || (y > m_maxY))
return true;
else
return m_zoneMask[(x - m_minX) + (y - m_minY) * (1 + m_maxX - m_minX)];
}
void ZoneBuilder::calcMask()
{
sint32 x, y;
m_minY = m_minX = 1000000;
m_maxY = m_maxX = -1000000;
if (m_landscapeMap.size() == 0)
return;
QMapIterator<int, LandscapeItem> i(m_landscapeMap);
while (i.hasNext())
{
i.next();
const NLLIGO::CZoneRegion &region = i.value().zoneRegionObject->ligoZoneRegion();
if (m_minX > region.getMinX())
m_minX = region.getMinX();
if (m_minY > region.getMinY())
m_minY = region.getMinY();
if (m_maxX < region.getMaxX())
m_maxX = region.getMaxX();
if (m_maxY < region.getMaxY())
m_maxY = region.getMaxY();
}
m_zoneMask.resize ((1 + m_maxX - m_minX) * (1 + m_maxY - m_minY));
sint32 stride = (1 + m_maxX - m_minX);
for (y = m_minY; y <= m_maxY; ++y)
for (x = m_minX; x <= m_maxX; ++x)
{
m_zoneMask[x - m_minX + (y - m_minY) * stride] = true;
QMapIterator<int, LandscapeItem> it(m_landscapeMap);
while (it.hasNext())
{
it.next();
if (int(it.key()) != m_currentZoneRegion)
{
const NLLIGO::CZoneRegion &region = it.value().zoneRegionObject->ligoZoneRegion();
const std::string &rSZone = region.getName (x, y);
if ((rSZone != STRING_OUT_OF_BOUND) && (rSZone != STRING_UNUSED))
{
m_zoneMask[x - m_minX + (y - m_minY) * stride] = false;
}
}
}
}
}
bool ZoneBuilder::getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y)
{
QMapIterator<int, LandscapeItem> it(m_landscapeMap);
while (it.hasNext())
{
it.next();
const NLLIGO::CZoneRegion &region = it.value().zoneRegionObject->ligoZoneRegion();
if ((x < region.getMinX()) || (x > region.getMaxX()) ||
(y < region.getMinY()) || (y > region.getMaxY()))
continue;
if (region.getName(x, y) != STRING_UNUSED)
{
builderZoneRegionFrom = it.value().builderZoneRegion;
zonePos = ZonePosition(x, y, it.key());
return true;
}
}
// The zone is not present in other region so it is an empty or oob zone of the current region
const NLLIGO::CZoneRegion &region = zoneRegion(builderZoneRegionFrom->getRegionId())->ligoZoneRegion();
if ((x < region.getMinX()) || (x > region.getMaxX()) ||
(y < region.getMinY()) || (y > region.getMaxY()))
return false; // Out Of Bound
zonePos = ZonePosition(x, y, builderZoneRegionFrom->getRegionId());
return true;
}
void ZoneBuilder::checkBeginMacro()
{
if (!m_createdAction)
{
m_createdAction = true;
m_undoStack->beginMacro(m_titleAction);
m_undoScanRegionCommand = new UndoScanRegionCommand(true, this, m_landscapeScene);
m_undoStack->push(m_undoScanRegionCommand);
}
}
void ZoneBuilder::checkEndMacro()
{
if (m_createdAction)
{
UndoScanRegionCommand *redoScanRegionCommand = new UndoScanRegionCommand(false, this, m_landscapeScene);
// Sets list positions in which need apply changes
m_undoScanRegionCommand->setScanList(m_zonePositionList);
redoScanRegionCommand->setScanList(m_zonePositionList);
// Adds command in the stack
m_undoStack->push(redoScanRegionCommand);
m_undoStack->endMacro();
}
}
bool ZoneBuilder::checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion)
{
QMapIterator<int, LandscapeItem> it(m_landscapeMap);
while (it.hasNext())
{
it.next();
const NLLIGO::CZoneRegion &zoneRegion = it.value().zoneRegionObject->ligoZoneRegion();
for (sint32 y = zoneRegion.getMinY(); y <= zoneRegion.getMaxY(); ++y)
for (sint32 x = zoneRegion.getMinX(); x <= zoneRegion.getMaxX(); ++x)
{
const std::string &refZoneName = zoneRegion.getName(x, y);
if (refZoneName != STRING_UNUSED)
{
const std::string &zoneName = newZoneRegion.getName(x, y);
if ((zoneName != STRING_UNUSED) && (zoneName != STRING_OUT_OF_BOUND))
return true;
}
}
}
return false;
}
} /* namespace LandscapeEditor */

@ -0,0 +1,174 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef BUILDER_ZONE_H
#define BUILDER_ZONE_H
// Project includes
#include "builder_zone_base.h"
#include "builder_zone_region.h"
#include "zone_region_editor.h"
#include "pixmap_database.h"
// NeL includes
#include <nel/ligo/zone_bank.h>
#include <nel/ligo/zone_region.h>
// STL includes
#include <string>
#include <vector>
// Qt includes
#include <QtCore/QString>
#include <QtCore/QMap>
#include <QtCore/QList>
#include <QtCore/QString>
#include <QtGui/QPixmap>
#include <QtGui/QUndoStack>
#include <QtGui/QGraphicsRectItem>
namespace LandscapeEditor
{
class ListZonesWidget;
class LandscapeScene;
class UndoScanRegionCommand;
/**
@class ZoneBuilder
@brief ZoneBuilder contains all the shared data between the tools and the engine.
@details ZoneBank contains the macro zones that is composed of several zones plus a mask.
PixmapDatabase contains the graphics for the zones
*/
class ZoneBuilder
{
public:
ZoneBuilder(LandscapeScene *landscapeScene, ListZonesWidget *listZonesWidget = 0, QUndoStack *undoStack = 0);
~ZoneBuilder();
/// Inits zoneBank and init zone pixmap database
bool init(const QString &pathName, bool displayProgress = false);
void calcMask();
/// @return false if in point (x, y) placed zone brick, else true
bool getZoneMask (sint32 x, sint32 y);
bool getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y);
/// Ligo Actions
/// @{
/// Adds the LigoTileCommand in undo stack
void actionLigoTile(const LigoData &data, const ZonePosition &zonePos);
void actionLigoMove(uint index, sint32 deltaX, sint32 deltaY);
/// Adds the LigoResizeCommand in undo stack
void actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY);
/// @}
/// Zone Bricks
/// @{
void addZone(const sint32 posX, const sint32 posY);
void addTransition(const sint32 posX, const sint32 posY);
void delZone(const sint32 posX, const sint32 posY);
/// @}
/// Zone Region
/// @{
/// Creates empty zone region and adds in the workspace
/// @return id zone region
int createZoneRegion();
/// Loads zone region from file @fileName and adds in the workspace.
/// @return id zone region
int createZoneRegion(const QString &fileName);
/// Unloads zone region from the workspace
void deleteZoneRegion(int id);
/// Sets the current zone region with @id
void setCurrentZoneRegion(int id);
/// @return id the current zone region, if workspace is empty then returns (-1)
int currentIdZoneRegion() const;
ZoneRegionObject *currentZoneRegion() const;
int countZoneRegion() const;
ZoneRegionObject *zoneRegion(int id) const;
bool ligoData(LigoData &data, const ZonePosition &zonePos);
void setLigoData(LigoData &data, const ZonePosition &zonePos);
/// @}
// Accessors
NLLIGO::CZoneBank &getZoneBank()
{
return m_zoneBank;
}
PixmapDatabase *pixmapDatabase() const;
QString dataPath() const;
private:
/// Scans ./zoneligos dir and add all *.ligozone files to zoneBank
bool initZoneBank (const QString &path);
/// Checks enabled beginMacro mode for undo stack, if false, then enables mode
void checkBeginMacro();
/// Checks enabled on beginMacro mode for undo stack, if true, then adds UndoScanRegionCommand
/// in undo stack and disables beginMacro mode
void checkEndMacro();
/// Checks intersects between them zone regions
/// @return true if newZoneRegion intersects with loaded zone regions, else return false
bool checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion);
struct LandscapeItem
{
BuilderZoneRegion *builderZoneRegion;
ZoneRegionObject *zoneRegionObject;
QGraphicsRectItem *rectItem;
};
sint32 m_minX, m_maxX, m_minY, m_maxY;
std::vector<bool> m_zoneMask;
QString m_lastPathName;
int m_currentZoneRegion;
//std::vector<LandscapeItem> m_landscapeItems;
QMap<int, LandscapeItem> m_landscapeMap;
bool m_createdAction;
QString m_titleAction;
QList<ZonePosition> m_zonePositionList;
UndoScanRegionCommand *m_undoScanRegionCommand;
PixmapDatabase *m_pixmapDatabase;
NLLIGO::CZoneBank m_zoneBank;
ListZonesWidget *m_listZonesWidget;
LandscapeScene *m_landscapeScene;
QUndoStack *m_undoStack;
};
} /* namespace LandscapeEditor */
#endif // BUILDER_ZONE_H

@ -0,0 +1,206 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Project includes
#include "builder_zone_base.h"
#include "landscape_scene_base.h"
#include "zone_region_editor.h"
#include "pixmap_database.h"
// NeL includes
#include <nel/misc/debug.h>
// Qt includes
#include <QtCore/QDir>
#include <QtGui/QMessageBox>
#include <QtGui/QProgressDialog>
namespace LandscapeEditor
{
int NewLandId = 0;
ZoneBuilderBase::ZoneBuilderBase(LandscapeSceneBase *landscapeScene)
: m_pixmapDatabase(0),
m_landscapeSceneBase(landscapeScene)
{
nlassert(m_landscapeSceneBase);
m_pixmapDatabase = new PixmapDatabase();
m_lastPathName = "";
}
ZoneBuilderBase::~ZoneBuilderBase()
{
delete m_pixmapDatabase;
}
bool ZoneBuilderBase::init(const QString &pathName, bool displayProgress)
{
if (pathName.isEmpty())
return false;
if (pathName != m_lastPathName)
{
m_lastPathName = pathName;
QString zoneBankPath = pathName;
zoneBankPath += "/zoneligos/";
// Init the ZoneBank
m_zoneBank.reset();
if (!initZoneBank (zoneBankPath))
{
m_zoneBank.reset();
return false;
}
// Construct the DataBase from the ZoneBank
QString zoneBitmapPath = pathName;
zoneBitmapPath += "/zonebitmaps/";
m_pixmapDatabase->reset();
if (!m_pixmapDatabase->loadPixmaps(zoneBitmapPath, m_zoneBank, displayProgress))
{
m_zoneBank.reset();
return false;
}
}
return true;
}
int ZoneBuilderBase::loadZoneRegion(const QString &fileName, int defaultId)
{
LandscapeItem landItem;
landItem.zoneRegionObject = new ZoneRegionObject();
landItem.zoneRegionObject->load(fileName.toUtf8().constData());
if (!checkOverlaps(landItem.zoneRegionObject->ligoZoneRegion()))
{
delete landItem.zoneRegionObject;
return -1;
}
int id = defaultId;
if (id == -1)
id = NewLandId++;
// landItem.builderZoneRegion = new BuilderZoneRegion(LandCounter);
// landItem.builderZoneRegion->init(this);
m_landscapeSceneBase->addZoneRegion(landItem.zoneRegionObject->ligoZoneRegion());
// landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion());
m_landscapeMap.insert(id, landItem);
calcMask();
return id;
}
void ZoneBuilderBase::deleteZoneRegion(int id)
{
if (m_landscapeMap.contains(id))
{
m_landscapeSceneBase->delZoneRegion(m_landscapeMap.value(id).zoneRegionObject->ligoZoneRegion());
delete m_landscapeMap.value(id).zoneRegionObject;
// delete m_landscapeMap.value(id).builderZoneRegion;
m_landscapeMap.remove(id);
calcMask();
}
else
nlwarning("Landscape (id %i) not found", id);
}
int ZoneBuilderBase::countZoneRegion() const
{
return m_landscapeMap.size();
}
ZoneRegionObject *ZoneBuilderBase::zoneRegion(int id) const
{
return m_landscapeMap.value(id).zoneRegionObject;
}
bool ZoneBuilderBase::initZoneBank (const QString &pathName)
{
QDir *dir = new QDir(pathName);
QStringList filters;
filters << "*.ligozone";
// Find all ligozone files in dir
QStringList listFiles = dir->entryList(filters, QDir::Files);
std::string error;
Q_FOREACH(QString file, listFiles)
{
//nlinfo(file.toUtf8().constData());
if (!m_zoneBank.addElement((pathName + file).toUtf8().constData(), error))
QMessageBox::critical(0, QObject::tr("Landscape editor"), QString(error.c_str()), QMessageBox::Ok);
}
delete dir;
return true;
}
PixmapDatabase *ZoneBuilderBase::pixmapDatabase() const
{
return m_pixmapDatabase;
}
QString ZoneBuilderBase::dataPath() const
{
return m_lastPathName;
}
void ZoneBuilderBase::calcMask()
{
m_minY = m_minX = 1000000;
m_maxY = m_maxX = -1000000;
if (m_landscapeMap.size() == 0)
return;
QMapIterator<int, LandscapeItem> i(m_landscapeMap);
while (i.hasNext())
{
i.next();
const NLLIGO::CZoneRegion &region = i.value().zoneRegionObject->ligoZoneRegion();
if (m_minX > region.getMinX())
m_minX = region.getMinX();
if (m_minY > region.getMinY())
m_minY = region.getMinY();
if (m_maxX < region.getMaxX())
m_maxX = region.getMaxX();
if (m_maxY < region.getMaxY())
m_maxY = region.getMaxY();
}
}
bool ZoneBuilderBase::checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion)
{
QMapIterator<int, LandscapeItem> it(m_landscapeMap);
while (it.hasNext())
{
it.next();
const NLLIGO::CZoneRegion &zoneRegion = it.value().zoneRegionObject->ligoZoneRegion();
for (sint32 y = zoneRegion.getMinY(); y <= zoneRegion.getMaxY(); ++y)
for (sint32 x = zoneRegion.getMinX(); x <= zoneRegion.getMaxX(); ++x)
{
const std::string &refZoneName = zoneRegion.getName(x, y);
if (refZoneName != STRING_UNUSED)
{
const std::string &zoneName = newZoneRegion.getName(x, y);
if ((zoneName != STRING_UNUSED) && (zoneName != STRING_OUT_OF_BOUND))
return false;
}
}
}
return true;
}
} /* namespace LandscapeEditor */

@ -0,0 +1,129 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef BUILDER_ZONE_BASE_H
#define BUILDER_ZONE_BASE_H
// Project includes
#include "landscape_editor_global.h"
// NeL includes
#include <nel/ligo/zone_bank.h>
#include <nel/ligo/zone_region.h>
// STL includes
#include <string>
#include <vector>
// Qt includes
#include <QtCore/QString>
#include <QtCore/QMap>
#include <QtCore/QList>
#include <QtCore/QString>
#include <QtGui/QPixmap>
#include <QtGui/QGraphicsRectItem>
namespace LandscapeEditor
{
class LandscapeSceneBase;
class PixmapDatabase;
class ZoneRegionObject;
// Data
struct ZonePosition
{
// Absolute position
sint32 x;
sint32 y;
int region;
ZonePosition()
{
x = 0xffffffff;
y = 0xffffffff;
region = -1;
}
ZonePosition(const sint32 posX, const sint32 posY, const int id)
{
x = posX;
y = posY;
region = id;
}
};
/**
@class ZoneBuilderBase
@brief ZoneBuilderBase contains all the shared data between the tools and the engine.
@details ZoneBank contains the macro zones that is composed of several zones plus a mask.
PixmapDatabase contains the graphics for the zones
*/
class LANDSCAPE_EDITOR_EXPORT ZoneBuilderBase
{
public:
explicit ZoneBuilderBase(LandscapeSceneBase *landscapeScene);
virtual ~ZoneBuilderBase();
/// Init zoneBank and init zone pixmap database
bool init(const QString &pathName, bool displayProgress = false);
/// Zone Region
/// @{
int loadZoneRegion(const QString &fileName, int defaultId = -1);
void deleteZoneRegion(int id);
int countZoneRegion() const;
ZoneRegionObject *zoneRegion(int id) const;
/// @}
// Accessors
NLLIGO::CZoneBank &getZoneBank()
{
return m_zoneBank;
}
PixmapDatabase *pixmapDatabase() const;
QString dataPath() const;
private:
/// Scan ./zoneligos dir and add all *.ligozone files to zoneBank
bool initZoneBank (const QString &path);
void calcMask();
bool checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion);
struct LandscapeItem
{
ZoneRegionObject *zoneRegionObject;
};
sint32 m_minX, m_maxX, m_minY, m_maxY;
QString m_lastPathName;
QMap<int, LandscapeItem> m_landscapeMap;
PixmapDatabase *m_pixmapDatabase;
NLLIGO::CZoneBank m_zoneBank;
LandscapeSceneBase *m_landscapeSceneBase;
};
} /* namespace LandscapeEditor */
#endif // BUILDER_ZONE_BASE_H

@ -0,0 +1,107 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// 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 BUILDER_ZONE_REGION_H
#define BUILDER_ZONE_REGION_H
// Project includes
// NeL includes
#include <nel/ligo/zone_bank.h>
#include <nel/ligo/zone_region.h>
// STL includes
#include <string>
#include <vector>
#include <queue>
// Qt includes
namespace LandscapeEditor
{
class ZoneBuilder;
class ToUpdate;
// CZoneRegion contains informations about the zones painted.
// (Legacy class from old world editor. It needs to refactoring!)
class BuilderZoneRegion
{
public:
explicit BuilderZoneRegion(uint regionId);
// New interface
bool init(ZoneBuilder *zoneBuilder);
void add(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
void invertCutEdge(sint32 x, sint32 y, uint8 cePos);
void cycleTransition(sint32 x, sint32 y);
bool addNotPropagate(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
/// Brutal adding a zone over empty space do not propagate in any way -> can result
/// in inconsistency when trying the propagation mode
void addForce (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
void del(sint32 x, sint32 y, bool transition = false, ToUpdate *pUpdate = 0);
void move(sint32 x, sint32 y);
uint32 countZones();
void reduceMin();
uint getRegionId() const;
private:
// An element of the graph
struct SMatNode
{
std::string Name;
// Position in the tree (vector of nodes)
std::vector<uint32> Arcs;
};
void addTransition(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
void addToUpdateAndCreate(BuilderZoneRegion *builderZoneRegion, sint32 sharePos, sint32 x, sint32 y,
const std::string &newMat, ToUpdate *ptCreate, ToUpdate *ptUpdate);
void putTransitions(sint32 x, sint32 y, const NLLIGO::SPiece &mask, const std::string &matName, ToUpdate *ptUpdate);
void updateTrans(sint32 x, sint32 y, NLLIGO::CZoneBankElement *zoneBankElement = 0);
std::string getNextMatInTree(const std::string &matA, const std::string &matB);
/// Find the fastest way between posA and posB in the MatTree (Dijkstra)
void tryPath(uint32 posA, uint32 posB, std::vector<uint32> &path);
void set(sint32 x, sint32 y, sint32 posX, sint32 posY, const std::string &zoneName, bool transition = false);
void setRot(sint32 x, sint32 y, uint8 rot);
void setFlip(sint32 x, sint32 y, uint8 flip);
void resize(sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY);
void placePiece(sint32 x, sint32 y, uint8 rot, uint8 flip,
NLLIGO::SPiece &sMask, NLLIGO::SPiece &sPosX, NLLIGO::SPiece &sPosY,
const std::string &eltName);
uint m_regionId;
// To use the global mask
ZoneBuilder *m_zoneBuilder;
// The tree of transition between materials
std::vector<SMatNode> m_matTree;
bool m_firstInit;
};
} /* namespace LandscapeEditor */
#endif // BUILDER_ZONE_REGION_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

@ -0,0 +1,178 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Project includes
#include "landscape_actions.h"
#include "builder_zone.h"
// NeL includes
#include <nel/misc/debug.h>
// Qt includes
namespace LandscapeEditor
{
LigoTileCommand::LigoTileCommand(const LigoData &data, const ZonePosition &zonePos,
ZoneBuilder *zoneBuilder, LandscapeScene *scene,
QUndoCommand *parent)
: QUndoCommand(parent),
m_zoneBuilder(zoneBuilder),
m_scene(scene)
{
// Backup position
m_zonePos = zonePos;
// Backup new data
m_newLigoData = data;
// Backup old data
m_zoneBuilder->ligoData(m_oldLigoData, m_zonePos);
}
LigoTileCommand::~LigoTileCommand()
{
}
void LigoTileCommand::undo ()
{
m_zoneBuilder->setLigoData(m_oldLigoData, m_zonePos);
}
void LigoTileCommand::redo ()
{
m_zoneBuilder->setLigoData(m_newLigoData, m_zonePos);
}
UndoScanRegionCommand::UndoScanRegionCommand(bool direction, ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent)
: QUndoCommand(parent),
m_direction(direction),
m_zoneBuilder(zoneBuilder),
m_scene(scene)
{
}
UndoScanRegionCommand::~UndoScanRegionCommand()
{
m_zonePositionList.clear();
}
void UndoScanRegionCommand::setScanList(const QList<ZonePosition> &zonePositionList)
{
m_zonePositionList = zonePositionList;
}
void UndoScanRegionCommand::undo()
{
if (m_direction)
applyChanges();
}
void UndoScanRegionCommand::redo()
{
if (!m_direction)
applyChanges();
}
void UndoScanRegionCommand::applyChanges()
{
for (int i = 0; i < m_zonePositionList.size(); ++i)
m_scene->deleteItemZone(m_zonePositionList.at(i));
for (int i = 0; i < m_zonePositionList.size(); ++i)
{
LigoData data;
m_zoneBuilder->ligoData(data, m_zonePositionList.at(i));
m_scene->createItemZone(data, m_zonePositionList.at(i));
}
}
LigoResizeCommand::LigoResizeCommand(int index, sint32 newMinX, sint32 newMaxX,
sint32 newMinY, sint32 newMaxY, ZoneBuilder *zoneBuilder,
QUndoCommand *parent)
: QUndoCommand(parent),
m_zoneBuilder(zoneBuilder)
{
m_index = index;
m_newMinX = newMinX;
m_newMaxX = newMaxX;
m_newMinY = newMinY;
m_newMaxY = newMaxY;
// Backup old region zone
m_oldZoneRegion = m_zoneBuilder->zoneRegion(m_index)->ligoZoneRegion();
}
LigoResizeCommand::~LigoResizeCommand()
{
}
void LigoResizeCommand::undo ()
{
// Restore old region zone
m_zoneBuilder->zoneRegion(m_index)->setLigoZoneRegion(m_oldZoneRegion);
}
void LigoResizeCommand::redo ()
{
// Get the zone region
NLLIGO::CZoneRegion &region = m_zoneBuilder->zoneRegion(m_index)->ligoZoneRegion();
sint32 i, j;
std::vector<LigoData> newZones;
newZones.resize((1 + m_newMaxX - m_newMinX) * (1 + m_newMaxY - m_newMinY));
sint32 newStride = 1 + m_newMaxX - m_newMinX;
sint32 Stride = 1 + region.getMaxX() - region.getMinX();
for (j = m_newMinY; j <= m_newMaxY; ++j)
for (i = m_newMinX; i <= m_newMaxX; ++i)
{
// Ref on the new value
LigoData &data = newZones[(i - m_newMinX) + (j - m_newMinY) * newStride];
// In the old array ?
if ((i >= region.getMinX()) && (i <= region.getMaxX()) &&
(j >= region.getMinY()) && (j <= region.getMaxY()))
{
// Backup values
m_zoneBuilder->ligoData(data, ZonePosition(i, j, m_index));
}
}
region.resize(m_newMinX, m_newMaxX, m_newMinY, m_newMaxY);
for (j = m_newMinY; j <= m_newMaxY; ++j)
for (i = m_newMinX; i <= m_newMaxX; ++i)
{
// Ref on the new value
const LigoData &data = newZones[(i - m_newMinX) + (j - m_newMinY) * newStride];
region.setName(i, j, data.zoneName);
region.setPosX(i, j, data.posX);
region.setPosY(i, j, data.posY);
region.setRot(i, j, data.rot);
region.setFlip(i, j, data.flip);
uint k;
for (k = 0; k < 4; k++)
{
region.setSharingMatNames(i, j, k, data.sharingMatNames[k]);
region.setSharingCutEdges(i, j, k, data.sharingCutEdges[k]);
}
}
}
} /* namespace LandscapeEditor */

@ -0,0 +1,111 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef LANDSCAPE_ACTIONS_H
#define LANDSCAPE_ACTIONS_H
// Project includes
#include "builder_zone.h"
#include "landscape_scene.h"
// NeL includes
// Qt includes
#include <QtGui/QUndoCommand>
#include <QtGui/QGraphicsScene>
#include <QtGui/QGraphicsItem>
namespace LandscapeEditor
{
/**
@class LigoTileCommand
@brief
@details
*/
class LigoTileCommand: public QUndoCommand
{
public:
LigoTileCommand(const LigoData &data, const ZonePosition &zonePos,
ZoneBuilder *zoneBuilder, LandscapeScene *scene,
QUndoCommand *parent = 0);
virtual ~LigoTileCommand();
virtual void undo();
virtual void redo();
private:
ZonePosition m_zonePos;
LigoData m_newLigoData;
LigoData m_oldLigoData;
ZoneBuilder *m_zoneBuilder;
LandscapeScene *m_scene;
};
/**
@class UndoScanRegionCommand
@brief
@details
*/
class UndoScanRegionCommand: public QUndoCommand
{
public:
UndoScanRegionCommand(bool direction, ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent = 0);
virtual ~UndoScanRegionCommand();
void setScanList(const QList<ZonePosition> &zonePositionList);
virtual void undo();
virtual void redo();
private:
void applyChanges();
bool m_direction;
QList<ZonePosition> m_zonePositionList;
ZoneBuilder *m_zoneBuilder;
LandscapeScene *m_scene;
};
/**
@class LigoResizeCommand
@brief
@details
*/
class LigoResizeCommand: public QUndoCommand
{
public:
LigoResizeCommand(int index, sint32 newMinX, sint32 newMaxX,
sint32 newMinY, sint32 newMaxY, ZoneBuilder *zoneBuilder,
QUndoCommand *parent = 0);
virtual ~LigoResizeCommand();
virtual void undo();
virtual void redo();
private:
int m_index;
sint32 m_newMinX;
sint32 m_newMaxX;
sint32 m_newMinY;
sint32 m_newMaxY;
NLLIGO::CZoneRegion m_oldZoneRegion;
ZoneBuilder *m_zoneBuilder;
};
} /* namespace LandscapeEditor */
#endif // LANDSCAPE_ACTIONS_H

@ -1,5 +1,9 @@
<RCC> <RCC>
<qresource prefix="/"> <qresource prefix="/">
<file>icons/ic_nel_zones.png</file>
<file>icons/ic_snapshot.png</file>
<file>icons/ic_grid.png</file>
<file>icons/ic_nel_transition_land.png</file>
<file>icons/ic_nel_landscape_item.png</file> <file>icons/ic_nel_landscape_item.png</file>
<file>icons/ic_nel_landscape_settings.png</file> <file>icons/ic_nel_landscape_settings.png</file>
<file>icons/ic_nel_world_editor.png</file> <file>icons/ic_nel_world_editor.png</file>

@ -1,5 +1,4 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/> // Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by> // Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
@ -22,13 +21,19 @@ namespace LandscapeEditor
{ {
namespace Constants namespace Constants
{ {
const char * const LANDSCAPE_EDITOR_PLUGIN = "LandscapeEditor"; const char *const LANDSCAPE_EDITOR_PLUGIN = "LandscapeEditor";
//settings //settings
const char * const LANDSCAPE_EDITOR_SECTION = "LandscapeEditor"; const char *const LANDSCAPE_EDITOR_SECTION = "LandscapeEditor";
const char *const LANDSCAPE_WINDOW_STATE = "LandscapeWindowState";
const char *const LANDSCAPE_WINDOW_GEOMETRY = "LandscapeWindowGeometry";
const char *const LANDSCAPE_DATA_DIRECTORY = "LandscapeDataDirectory";
const char *const LANDSCAPE_USE_OPENGL = "LandscapeUseOpenGL";
//resources //resources
const char * const ICON_LANDSCAPE_ITEM = ":/icons/ic_nel_landscape_item.png"; const char *const ICON_LANDSCAPE_ITEM = ":/icons/ic_nel_landscape_item.png";
const char *const ICON_ZONE_ITEM = ":/icons/ic_nel_zone.png";
const char *const ICON_LANDSCAPE_ZONES = ":/icons/ic_nel_zones.png";
} // namespace Constants } // namespace Constants

@ -68,33 +68,6 @@ void LandscapeEditorPlugin::setNelContext(NLMISC::INelContext *nelContext)
m_libContext = new NLMISC::CLibraryContext(*nelContext); m_libContext = new NLMISC::CLibraryContext(*nelContext);
} }
QString LandscapeEditorPlugin::name() const
{
return tr("LandscapeEditor");
}
QString LandscapeEditorPlugin::version() const
{
return "0.0.1";
}
QString LandscapeEditorPlugin::vendor() const
{
return "GSoC2011_dnk-88";
}
QString LandscapeEditorPlugin::description() const
{
return "Landscape editor ovqt plugin.";
}
QStringList LandscapeEditorPlugin::dependencies() const
{
QStringList list;
list.append(Core::Constants::OVQT_CORE_PLUGIN);
return list;
}
void LandscapeEditorPlugin::addAutoReleasedObject(QObject *obj) void LandscapeEditorPlugin::addAutoReleasedObject(QObject *obj)
{ {
m_plugMan->addObject(obj); m_plugMan->addObject(obj);
@ -124,5 +97,4 @@ QWidget *LandscapeEditorContext::widget()
} }
} }
Q_EXPORT_PLUGIN(LandscapeEditor::LandscapeEditorPlugin) Q_EXPORT_PLUGIN(LandscapeEditor::LandscapeEditorPlugin)

@ -1,5 +1,4 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/> // Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by> // Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
@ -35,11 +34,6 @@ namespace NLMISC
class CLibraryContext; class CLibraryContext;
} }
namespace ExtensionSystem
{
class IPluginSpec;
}
namespace LandscapeEditor namespace LandscapeEditor
{ {
class LandscapeEditorWindow; class LandscapeEditorWindow;
@ -55,15 +49,8 @@ public:
bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString); bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString);
void extensionsInitialized(); void extensionsInitialized();
void shutdown(); void shutdown();
void setNelContext(NLMISC::INelContext *nelContext); void setNelContext(NLMISC::INelContext *nelContext);
QString name() const;
QString version() const;
QString vendor() const;
QString description() const;
QStringList dependencies() const;
void addAutoReleasedObject(QObject *obj); void addAutoReleasedObject(QObject *obj);
protected: protected:
@ -78,7 +65,7 @@ class LandscapeEditorContext: public Core::IContext
{ {
Q_OBJECT Q_OBJECT
public: public:
LandscapeEditorContext(QObject *parent = 0); explicit LandscapeEditorContext(QObject *parent = 0);
virtual ~LandscapeEditorContext() {} virtual ~LandscapeEditorContext() {}
virtual QString id() const virtual QString id() const
@ -91,7 +78,7 @@ public:
} }
virtual QIcon icon() const virtual QIcon icon() const
{ {
return QIcon(); return QIcon(Constants::ICON_LANDSCAPE_ITEM);
} }
virtual void open(); virtual void open();

@ -1,5 +1,4 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/> // Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by> // Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
@ -18,8 +17,14 @@
// Project includes // Project includes
#include "landscape_editor_window.h" #include "landscape_editor_window.h"
#include "landscape_editor_constants.h" #include "landscape_editor_constants.h"
#include "builder_zone.h"
#include "zone_region_editor.h"
#include "landscape_scene.h"
#include "project_settings_dialog.h"
#include "snapshot_dialog.h"
#include "../core/icore.h" #include "../core/icore.h"
#include "../core/menu_manager.h"
#include "../core/core_constants.h" #include "../core/core_constants.h"
// NeL includes // NeL includes
@ -27,26 +32,78 @@
// Qt includes // Qt includes
#include <QtCore/QSettings> #include <QtCore/QSettings>
#include <QtGui/QMenu>
#include <QtGui/QFileDialog> #include <QtGui/QFileDialog>
#include <QtGui/QMessageBox>
#include <QtGui/QStatusBar>
namespace LandscapeEditor namespace LandscapeEditor
{ {
static const int LANDSCAPE_ID = 32;
int NewLandCounter = 0;
QString _lastDir; QString _lastDir;
LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent),
m_currentItem(0),
m_landscapeScene(0),
m_zoneBuilder(0),
m_undoStack(0),
m_oglWidget(0)
{ {
m_ui.setupUi(this); m_ui.setupUi(this);
m_undoStack = new QUndoStack(this); m_undoStack = new QUndoStack(this);
m_landscapeScene = new LandscapeScene(160, this);
m_zoneBuilder = new ZoneBuilder(m_landscapeScene, m_ui.zoneListWidget, m_undoStack);
m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder);
m_ui.zoneListWidget->updateUi();
m_landscapeScene->setZoneBuilder(m_zoneBuilder);
m_ui.graphicsView->setScene(m_landscapeScene);
m_ui.newLandAction->setIcon(QIcon(Core::Constants::ICON_NEW));
m_ui.saveAction->setIcon(QIcon(Core::Constants::ICON_SAVE));
m_ui.saveLandAction->setIcon(QIcon(Core::Constants::ICON_SAVE));
m_ui.saveAsLandAction->setIcon(QIcon(Core::Constants::ICON_SAVE_AS));
m_ui.zonesDockWidget->toggleViewAction()->setIcon(QIcon(Constants::ICON_LANDSCAPE_ZONES));
m_ui.landscapesDockWidget->toggleViewAction()->setIcon(QIcon(Constants::ICON_ZONE_ITEM));
m_ui.deleteLandAction->setEnabled(false);
createMenus(); createMenus();
createToolBars();
readSettings(); readSettings();
connect(m_ui.saveAction, SIGNAL(triggered()), this, SLOT(save()));
connect(m_ui.projectSettingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings()));
connect(m_ui.snapshotAction, SIGNAL(triggered()), this, SLOT(openSnapshotDialog()));
connect(m_ui.enableGridAction, SIGNAL(toggled(bool)), m_ui.graphicsView, SLOT(setVisibleGrid(bool)));
connect(m_ui.newLandAction, SIGNAL(triggered()), this, SLOT(newLand()));
connect(m_ui.setActiveLandAction, SIGNAL(triggered()), this, SLOT(setActiveLand()));
connect(m_ui.saveLandAction, SIGNAL(triggered()), this, SLOT(saveSelectedLand()));
connect(m_ui.saveAsLandAction, SIGNAL(triggered()), this, SLOT(saveAsSelectedLand()));
connect(m_ui.deleteLandAction, SIGNAL(triggered()), this, SLOT(deleteSelectedLand()));
connect(m_ui.transitionModeAction, SIGNAL(toggled(bool)), m_landscapeScene, SLOT(setTransitionMode(bool)));
connect(m_ui.landscapesListWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenu()));
m_ui.landscapesListWidget->setContextMenuPolicy(Qt::CustomContextMenu);
m_statusBarTimer = new QTimer(this);
connect(m_statusBarTimer, SIGNAL(timeout()), this, SLOT(updateStatusBar()));
m_statusInfo = new QLabel(this);
m_statusInfo->hide();
Core::ICore::instance()->mainWindow()->statusBar()->addPermanentWidget(m_statusInfo);
} }
LandscapeEditorWindow::~LandscapeEditorWindow() LandscapeEditorWindow::~LandscapeEditorWindow()
{ {
writeSettings(); writeSettings();
delete m_zoneBuilder;
} }
QUndoStack *LandscapeEditorWindow::undoStack() const QUndoStack *LandscapeEditorWindow::undoStack() const
@ -65,18 +122,281 @@ void LandscapeEditorWindow::open()
{ {
QStringList list = fileNames; QStringList list = fileNames;
_lastDir = QFileInfo(list.front()).absolutePath(); _lastDir = QFileInfo(list.front()).absolutePath();
Q_FOREACH(QString fileName, fileNames)
{
int row = createLandscape(fileName);
if (row != -1)
setActiveLandscape(row);
}
}
setCursor(Qt::ArrowCursor);
}
void LandscapeEditorWindow::save()
{
saveLandscape(m_ui.landscapesListWidget->row(m_currentItem), true);
}
void LandscapeEditorWindow::openProjectSettings()
{
ProjectSettingsDialog *dialog = new ProjectSettingsDialog(m_zoneBuilder->dataPath(), this);
dialog->show();
int ok = dialog->exec();
if (ok == QDialog::Accepted)
{
m_zoneBuilder->init(dialog->dataPath(), true);
m_ui.zoneListWidget->updateUi();
}
delete dialog;
}
void LandscapeEditorWindow::openSnapshotDialog()
{
SnapshotDialog *dialog = new SnapshotDialog(this);
dialog->show();
int ok = dialog->exec();
if (ok == QDialog::Accepted)
{
QString fileName = QFileDialog::getSaveFileName(this,
tr("Save screenshot landscape"), _lastDir,
tr("Image file (*.png)"));
setCursor(Qt::WaitCursor);
NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->currentZoneRegion()->ligoZoneRegion();
sint32 regionMinX = zoneRegion.getMinX();
sint32 regionMaxX = zoneRegion.getMaxX();
sint32 regionMinY = zoneRegion.getMinY();
sint32 regionMaxY = zoneRegion.getMaxY();
int regionWidth = (regionMaxX - regionMinX + 1);
int regionHeight = (regionMaxY - regionMinY + 1);
int cellSize = m_landscapeScene->cellSize();
QRectF rect(regionMinX * cellSize, abs(regionMaxY) * cellSize, regionWidth * cellSize, regionHeight * cellSize);
if (dialog->isCustomSize())
{
int widthSnapshot = dialog->widthSnapshot();
int heightSnapshot = dialog->heightSnapshot();
if (dialog->isKeepRatio())
heightSnapshot = (widthSnapshot / regionWidth) * regionHeight;
m_landscapeScene->snapshot(fileName, widthSnapshot, heightSnapshot, rect);
}
else
{
m_landscapeScene->snapshot(fileName, regionWidth * dialog->resolutionZone(),
regionHeight * dialog->resolutionZone(), rect);
} }
setCursor(Qt::ArrowCursor); setCursor(Qt::ArrowCursor);
}
delete dialog;
}
void LandscapeEditorWindow::customContextMenu()
{
if (m_ui.landscapesListWidget->currentRow() == -1)
return;
QMenu *popurMenu = new QMenu(this);
popurMenu->addAction(m_ui.setActiveLandAction);
popurMenu->addAction(m_ui.saveLandAction);
popurMenu->addAction(m_ui.saveAsLandAction);
popurMenu->addAction(m_ui.deleteLandAction);
popurMenu->exec(QCursor::pos());
delete popurMenu;
}
void LandscapeEditorWindow::newLand()
{
int row = createLandscape(QString());
if (row != -1)
setActiveLandscape(row);
}
void LandscapeEditorWindow::setActiveLand()
{
setActiveLandscape(m_ui.landscapesListWidget->currentRow());
}
void LandscapeEditorWindow::saveSelectedLand()
{
saveLandscape(m_ui.landscapesListWidget->currentRow(), true);
}
void LandscapeEditorWindow::saveAsSelectedLand()
{
saveLandscape(m_ui.landscapesListWidget->currentRow(), false);
}
void LandscapeEditorWindow::deleteSelectedLand()
{
int row = m_ui.landscapesListWidget->currentRow();
int current_row = m_ui.landscapesListWidget->row(m_currentItem);
QListWidgetItem *item = m_ui.landscapesListWidget->item(row);
if (row == current_row)
{
if (row == 0)
++row;
else
--row;
setActiveLandscape(row);
}
m_zoneBuilder->deleteZoneRegion(item->data(LANDSCAPE_ID).toInt());
m_ui.landscapesListWidget->removeItemWidget(item);
delete item;
if (m_ui.landscapesListWidget->count() == 1)
m_ui.deleteLandAction->setEnabled(false);
m_undoStack->clear();
}
int LandscapeEditorWindow::createLandscape(const QString &fileName)
{
int id;
if (fileName.isEmpty())
id = m_zoneBuilder->createZoneRegion();
else
id = m_zoneBuilder->createZoneRegion(fileName);
if (id == -1)
{
QMessageBox::critical(this, "Landscape Editor", tr("Cannot add this zone because it overlaps existing ones"));
return -1;
}
ZoneRegionObject *zoneRegion = m_zoneBuilder->zoneRegion(id);
m_ui.graphicsView->setCenter(QPointF(zoneRegion->ligoZoneRegion().getMinX() * m_landscapeScene->cellSize(),
abs(zoneRegion->ligoZoneRegion().getMinY()) * m_landscapeScene->cellSize()));
QListWidgetItem *item;
if (fileName.isEmpty())
item = new QListWidgetItem(QString("NewLandscape%1").arg(NewLandCounter++), m_ui.landscapesListWidget);
else
item = new QListWidgetItem(fileName, m_ui.landscapesListWidget);
item->setData(LANDSCAPE_ID, id);
item->setFont(QFont("SansSerif", 9, QFont::Normal));
if (m_ui.landscapesListWidget->count() > 1)
m_ui.deleteLandAction->setEnabled(true);
return m_ui.landscapesListWidget->count() - 1;
}
void LandscapeEditorWindow::setActiveLandscape(int row)
{
if ((0 <= row) && (row < m_ui.landscapesListWidget->count()))
{
if (m_currentItem != 0)
m_currentItem->setFont(QFont("SansSerif", 9, QFont::Normal));
QListWidgetItem *item = m_ui.landscapesListWidget->item(row);
item->setFont(QFont("SansSerif", 9, QFont::Bold));
m_zoneBuilder->setCurrentZoneRegion(item->data(LANDSCAPE_ID).toInt());
m_currentItem = item;
}
}
void LandscapeEditorWindow::saveLandscape(int row, bool force)
{
if ((0 <= row) && (row < m_ui.landscapesListWidget->count()))
{
QListWidgetItem *item = m_ui.landscapesListWidget->item(row);
ZoneRegionObject *regionObject = m_zoneBuilder->zoneRegion(item->data(LANDSCAPE_ID).toInt());
if ((!force) || (regionObject->fileName().empty()))
{
QString fileName = QFileDialog::getSaveFileName(this,
tr("Save NeL Ligo land file"), _lastDir,
tr("NeL Ligo land file (*.land)"));
if (!fileName.isEmpty())
{
regionObject->setFileName(fileName.toUtf8().constData());
regionObject->save();
regionObject->setModified(false);
item->setText(fileName);
}
}
else
{
regionObject->save();
regionObject->setModified(false);
}
}
}
void LandscapeEditorWindow::showEvent(QShowEvent *showEvent)
{
QMainWindow::showEvent(showEvent);
if (m_oglWidget != 0)
m_oglWidget->makeCurrent();
m_statusInfo->show();
m_statusBarTimer->start(100);
}
void LandscapeEditorWindow::hideEvent(QHideEvent *hideEvent)
{
QMainWindow::hideEvent(hideEvent);
m_statusInfo->hide();
m_statusBarTimer->stop();
}
void LandscapeEditorWindow::updateStatusBar()
{
m_statusInfo->setText(m_landscapeScene->zoneNameFromMousePos());
} }
void LandscapeEditorWindow::createMenus() void LandscapeEditorWindow::createMenus()
{ {
Core::MenuManager *menuManager = Core::ICore::instance()->menuManager();
}
void LandscapeEditorWindow::createToolBars()
{
Core::MenuManager *menuManager = Core::ICore::instance()->menuManager();
//QAction *action = menuManager->action(Core::Constants::NEW);
//m_ui.fileToolBar->addAction(action);
//action = menuManager->action(Core::Constants::SAVE);
//m_ui.fileToolBar->addAction(action);
//action = menuManager->action(Core::Constants::SAVE_AS);
//m_ui.fileToolBar->addAction(action);
QAction *action = menuManager->action(Core::Constants::OPEN);
m_ui.fileToolBar->addAction(m_ui.newLandAction);
m_ui.fileToolBar->addAction(action);
m_ui.fileToolBar->addAction(m_ui.saveAction);
m_ui.fileToolBar->addSeparator();
action = menuManager->action(Core::Constants::UNDO);
if (action != 0)
m_ui.fileToolBar->addAction(action);
action = menuManager->action(Core::Constants::REDO);
if (action != 0)
m_ui.fileToolBar->addAction(action);
m_ui.zoneToolBar->insertAction(m_ui.enableGridAction, m_ui.landscapesDockWidget->toggleViewAction());
m_ui.zoneToolBar->insertAction(m_ui.enableGridAction, m_ui.zonesDockWidget->toggleViewAction());
} }
void LandscapeEditorWindow::readSettings() void LandscapeEditorWindow::readSettings()
{ {
QSettings *settings = Core::ICore::instance()->settings(); QSettings *settings = Core::ICore::instance()->settings();
settings->beginGroup(Constants::LANDSCAPE_EDITOR_SECTION); settings->beginGroup(Constants::LANDSCAPE_EDITOR_SECTION);
restoreState(settings->value(Constants::LANDSCAPE_WINDOW_STATE).toByteArray());
restoreGeometry(settings->value(Constants::LANDSCAPE_WINDOW_GEOMETRY).toByteArray());
// Read landscape data directory (contains sub-paths: zone logos, zone bitmaps)
m_zoneBuilder->init(settings->value(Constants::LANDSCAPE_DATA_DIRECTORY).toString());
m_ui.zoneListWidget->updateUi();
// Use OpenGL graphics system instead raster graphics system
if (settings->value(Constants::LANDSCAPE_USE_OPENGL, false).toBool())
{
m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer));
m_ui.graphicsView->setViewport(m_oglWidget);
}
settings->endGroup(); settings->endGroup();
} }
@ -84,6 +404,9 @@ void LandscapeEditorWindow::writeSettings()
{ {
QSettings *settings = Core::ICore::instance()->settings(); QSettings *settings = Core::ICore::instance()->settings();
settings->beginGroup(Constants::LANDSCAPE_EDITOR_SECTION); settings->beginGroup(Constants::LANDSCAPE_EDITOR_SECTION);
settings->setValue(Constants::LANDSCAPE_WINDOW_STATE, saveState());
settings->setValue(Constants::LANDSCAPE_WINDOW_GEOMETRY, saveGeometry());
settings->setValue(Constants::LANDSCAPE_DATA_DIRECTORY, m_zoneBuilder->dataPath());
settings->endGroup(); settings->endGroup();
settings->sync(); settings->sync();
} }

@ -1,5 +1,4 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/> // Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by> // Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
@ -23,16 +22,22 @@
// Qt includes // Qt includes
#include <QtGui/QUndoStack> #include <QtGui/QUndoStack>
#include <QtOpenGL/QGLWidget>
#include <QtGui/QLabel>
#include <QtCore/QTimer>
namespace LandscapeEditor namespace LandscapeEditor
{ {
class LandscapeScene;
class ZoneBuilder;
class LandscapeEditorWindow: public QMainWindow class LandscapeEditorWindow: public QMainWindow
{ {
Q_OBJECT Q_OBJECT
public: public:
LandscapeEditorWindow(QWidget *parent = 0); explicit LandscapeEditorWindow(QWidget *parent = 0);
~LandscapeEditorWindow(); ~LandscapeEditorWindow();
QUndoStack *undoStack() const; QUndoStack *undoStack() const;
@ -40,14 +45,41 @@ public:
Q_SIGNALS: Q_SIGNALS:
public Q_SLOTS: public Q_SLOTS:
void open(); void open();
void save();
private Q_SLOTS: private Q_SLOTS:
void openProjectSettings();
void openSnapshotDialog();
void customContextMenu();
void updateStatusBar();
void newLand();
void setActiveLand();
void saveSelectedLand();
void saveAsSelectedLand();
void deleteSelectedLand();
protected:
virtual void showEvent(QShowEvent *showEvent);
virtual void hideEvent(QHideEvent *hideEvent);
private: private:
void createMenus(); void createMenus();
void createToolBars();
void readSettings(); void readSettings();
void writeSettings(); void writeSettings();
void setActiveLandscape(int row);
void saveLandscape(int row, bool force);
int createLandscape(const QString &fileName);
QLabel *m_statusInfo;
QTimer *m_statusBarTimer;
QListWidgetItem *m_currentItem;
LandscapeScene *m_landscapeScene;
ZoneBuilder *m_zoneBuilder;
QUndoStack *m_undoStack; QUndoStack *m_undoStack;
QGLWidget *m_oglWidget;
Ui::LandscapeEditorWindow m_ui; Ui::LandscapeEditorWindow m_ui;
}; /* class LandscapeEditorWindow */ }; /* class LandscapeEditorWindow */

@ -19,12 +19,91 @@
</property> </property>
<widget class="QWidget" name="centralwidget"> <widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>3</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<widget class="LandscapeEditor::LandscapeView" name="graphicsView">
<property name="sceneRect">
<rectf>
<x>0.000000000000000</x>
<y>0.000000000000000</y>
<width>0.000000000000000</width>
<height>0.000000000000000</height>
</rectf>
</property>
<property name="dragMode">
<enum>QGraphicsView::NoDrag</enum>
</property>
<property name="transformationAnchor">
<enum>QGraphicsView::AnchorUnderMouse</enum>
</property>
<property name="resizeAnchor">
<enum>QGraphicsView::AnchorUnderMouse</enum>
</property>
<property name="viewportUpdateMode">
<enum>QGraphicsView::FullViewportUpdate</enum>
</property>
<property name="optimizationFlags">
<set>QGraphicsView::DontSavePainterState</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QToolBar" name="fileToolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QDockWidget" name="zonesDockWidget">
<property name="windowIcon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_nel_zones.png</normaloff>:/icons/ic_nel_zones.png</iconset>
</property>
<property name="windowTitle">
<string>Zones</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="LandscapeEditor::ListZonesWidget" name="zoneListWidget"/>
</widget>
<widget class="QDockWidget" name="landscapesDockWidget">
<property name="windowIcon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_nel_zone.png</normaloff>:/icons/ic_nel_zone.png</iconset>
</property>
<property name="windowTitle">
<string>Landscapes</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<number>3</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QGraphicsView" name="graphicsView"/> <widget class="QListWidget" name="landscapesListWidget"/>
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QToolBar" name="toolBar"> </widget>
<widget class="QToolBar" name="zoneToolBar">
<property name="windowTitle"> <property name="windowTitle">
<string>toolBar</string> <string>toolBar</string>
</property> </property>
@ -34,8 +113,129 @@
<attribute name="toolBarBreak"> <attribute name="toolBarBreak">
<bool>false</bool> <bool>false</bool>
</attribute> </attribute>
<addaction name="transitionModeAction"/>
<addaction name="enableGridAction"/>
<addaction name="projectSettingsAction"/>
<addaction name="snapshotAction"/>
</widget> </widget>
<action name="projectSettingsAction">
<property name="icon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_nel_landscape_settings.png</normaloff>:/icons/ic_nel_landscape_settings.png</iconset>
</property>
<property name="text">
<string>Project settings</string>
</property>
</action>
<action name="enableGridAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_grid.png</normaloff>:/icons/ic_grid.png</iconset>
</property>
<property name="text">
<string>EnableGrid</string>
</property>
<property name="toolTip">
<string>Show/Hide Grid</string>
</property>
<property name="shortcut">
<string>Ctrl+G</string>
</property>
</action>
<action name="snapshotAction">
<property name="icon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_snapshot.png</normaloff>:/icons/ic_snapshot.png</iconset>
</property>
<property name="text">
<string>snapshot</string>
</property>
</action>
<action name="saveAction">
<property name="text">
<string>Save</string>
</property>
</action>
<action name="setActiveLandAction">
<property name="icon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_nel_zone.png</normaloff>:/icons/ic_nel_zone.png</iconset>
</property>
<property name="text">
<string>Set active</string>
</property>
<property name="toolTip">
<string>Set active selected landscape</string>
</property>
</action>
<action name="saveLandAction">
<property name="text">
<string>Save</string>
</property>
<property name="toolTip">
<string>Save selected landscape</string>
</property>
</action>
<action name="saveAsLandAction">
<property name="text">
<string>Save As landscape</string>
</property>
<property name="toolTip">
<string>Save as selected landscape</string>
</property>
</action>
<action name="deleteLandAction">
<property name="text">
<string>Delete</string>
</property>
<property name="toolTip">
<string>Delete selected landscape</string>
</property>
</action>
<action name="newLandAction">
<property name="text">
<string>New</string>
</property>
<property name="toolTip">
<string>Create new landscape</string>
</property>
</action>
<action name="transitionModeAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_nel_landscape_item.png</normaloff>
<normalon>:/icons/ic_nel_transition_land.png</normalon>:/icons/ic_nel_landscape_item.png</iconset>
</property>
<property name="text">
<string>Transition mode</string>
</property>
<property name="toolTip">
<string>Enable transition mode</string>
</property>
</action>
</widget> </widget>
<customwidgets>
<customwidget>
<class>LandscapeEditor::ListZonesWidget</class>
<extends>QWidget</extends>
<header>list_zones_widget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>LandscapeEditor::LandscapeView</class>
<extends>QGraphicsView</extends>
<header>landscape_view.h</header>
</customwidget>
</customwidgets>
<resources> <resources>
<include location="landscape_editor.qrc"/> <include location="landscape_editor.qrc"/>
</resources> </resources>

@ -0,0 +1,498 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Project includes
#include "landscape_scene.h"
#include "pixmap_database.h"
// NeL includes
#include <nel/misc/debug.h>
// Qt includes
#include <QtGui/QPainter>
#include <QtGui/QGraphicsPixmapItem>
#include <QtGui/QGraphicsSimpleTextItem>
#include <QApplication>
namespace LandscapeEditor
{
static const int ZONE_NAME = 0;
static const int LAYER_ZONES = 2;
static const int LAYER_EMPTY_ZONES = 3;
static const int LAYER_BLACKOUT = 4;
const char *const LAYER_BLACKOUT_NAME = "blackout";
const int MAX_SCENE_WIDTH = 256;
const int MAX_SCENE_HEIGHT = 256;
LandscapeScene::LandscapeScene(int sizeCell, QObject *parent)
: QGraphicsScene(parent),
m_cellSize(sizeCell),
m_transitionMode(false),
m_mouseButton(Qt::NoButton),
m_zoneBuilder(0)
{
setSceneRect(QRectF(0, m_cellSize, MAX_SCENE_WIDTH * m_cellSize, MAX_SCENE_HEIGHT * m_cellSize));
}
LandscapeScene::~LandscapeScene()
{
}
int LandscapeScene::cellSize() const
{
return m_cellSize;
}
void LandscapeScene::setZoneBuilder(ZoneBuilder *zoneBuilder)
{
m_zoneBuilder = zoneBuilder;
}
QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePosition &zonePos)
{
if ((data.zoneName == STRING_OUT_OF_BOUND) || (checkUnderZone(zonePos.x, zonePos.y)))
return 0;
if (data.zoneName == STRING_UNUSED)
return createItemEmptyZone(zonePos);
if ((m_zoneBuilder == 0) || (data.zoneName.empty()))
return 0;
// Get image from pixmap database
QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(data.zoneName.c_str()));
if (pixmap == 0)
return 0;
// Rotate the image counterclockwise
QMatrix matrix;
matrix.rotate(-data.rot * 90.0);
QGraphicsPixmapItem *item;
if (data.flip == 0)
{
item = addPixmap(pixmap->transformed(matrix, Qt::SmoothTransformation));
}
else
{
// mirror image
QImage mirrorImage = pixmap->toImage();
QPixmap mirrorPixmap = QPixmap::fromImage(mirrorImage.mirrored(true, false));
item = addPixmap(mirrorPixmap.transformed(matrix, Qt::SmoothTransformation));
}
// Enable bilinear filtering
item->setTransformationMode(Qt::SmoothTransformation);
sint32 sizeX = 1, sizeY = 1;
sizeX = float(pixmap->width()) / m_zoneBuilder->pixmapDatabase()->textureSize();
sizeY = float(pixmap->width()) / m_zoneBuilder->pixmapDatabase()->textureSize();
sint32 deltaX = 0, deltaY = 0;
// Calculate offset for graphics item (for items with size that are larger than 1)
if ((sizeX > 1) || (sizeY > 1))
{
if (data.flip == 0)
{
switch (data.rot)
{
case 0:
deltaX = -data.posX;
deltaY = -data.posY + sizeY - 1;
break;
case 1:
deltaX = -(sizeY - 1 - data.posY);
deltaY = -data.posX + sizeX - 1;
break;
case 2:
deltaX = -(sizeX - 1 - data.posX);
deltaY = data.posY;
break;
case 3:
deltaX = -data.posY;
deltaY = data.posX;
break;
}
}
else
{
switch (data.rot)
{
case 0:
deltaX = -(sizeX - 1 - data.posX);
deltaY = -data.posY + sizeY - 1;
break;
case 1:
deltaX = -(sizeY - 1 - data.posY);
deltaY = +data.posX;
break;
case 2:
deltaX = -data.posX;
deltaY = data.posY;
break;
case 3:
deltaX = -data.posY;
deltaY = -data.posX + sizeX - 1;
break;
}
}
}
// Set position graphics item with offset for large piece
item->setPos((zonePos.x + deltaX) * m_cellSize, (abs(int(zonePos.y + deltaY))) * m_cellSize);
// The size graphics item should be equal or proportional m_cellSize
item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize());
item->setData(ZONE_NAME, QString(data.zoneName.c_str()));
// for not full item zone
item->setZValue(LAYER_ZONES);
item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
return item;
}
QGraphicsItem *LandscapeScene::createItemEmptyZone(const ZonePosition &zonePos)
{
if (m_zoneBuilder == 0)
return 0;
if (checkUnderZone(zonePos.x, zonePos.y))
return 0;
// Get image from pixmap database
QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(STRING_UNUSED));
if (pixmap == 0)
return 0;
QGraphicsPixmapItem *item = addPixmap(*pixmap);
// Enable bilinear filtering
item->setTransformationMode(Qt::SmoothTransformation);
// Set position graphics item
item->setPos(zonePos.x * m_cellSize, abs(int(zonePos.y)) * m_cellSize);
// The size graphics item should be equal or proportional m_cellSize
item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize());
// for not full item zone
item->setZValue(LAYER_EMPTY_ZONES);
item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
return item;
}
QGraphicsRectItem *LandscapeScene::createLayerBlackout(const NLLIGO::CZoneRegion &zoneRegion)
{
QGraphicsRectItem *rectItem = addRect(zoneRegion.getMinX() * m_cellSize,
abs(zoneRegion.getMaxY()) * m_cellSize,
(abs(zoneRegion.getMaxX() - zoneRegion.getMinX()) + 1) * m_cellSize,
(abs(zoneRegion.getMaxY() - zoneRegion.getMinY()) + 1) * m_cellSize,
Qt::NoPen, QBrush(QColor(0, 0, 0, 50)));
rectItem->setZValue(LAYER_BLACKOUT);
rectItem->setData(ZONE_NAME, QString(LAYER_BLACKOUT_NAME));
return rectItem;
}
void LandscapeScene::deleteItemZone(const ZonePosition &zonePos)
{
QGraphicsItem *item = itemAt(zonePos.x * m_cellSize, abs(zonePos.y) * m_cellSize);
if ((item != 0) && (item->data(ZONE_NAME).toString() != QString(LAYER_BLACKOUT_NAME)))
{
removeItem(item);
delete item;
}
}
void LandscapeScene::addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
{
for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
{
for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
{
std::string zoneName = zoneRegion.getName(i, j);
if (zoneName == STRING_UNUSED)
{
ZonePosition zonePos(i, j, -1);
QGraphicsItem *item = createItemEmptyZone(zonePos);
}
else if (!zoneName.empty())
{
LigoData data;
ZonePosition zonePos(i, j, -1);
data.zoneName = zoneName;
data.rot = zoneRegion.getRot(i, j);
data.flip = zoneRegion.getFlip(i, j);
data.posX = zoneRegion.getPosX(i, j);
data.posY = zoneRegion.getPosY(i, j);
QGraphicsItem *item = createItemZone(data, zonePos);
}
}
}
}
void LandscapeScene::delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
{
for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
{
for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
{
deleteItemZone(ZonePosition(i, -j, -1));
}
}
}
void LandscapeScene::snapshot(const QString &fileName, int width, int height, const QRectF &landRect)
{
if (m_zoneBuilder == 0)
return;
// Create image
QImage image(landRect.width(), landRect.height(), QImage::Format_RGB888);
QPainter painter(&image);
painter.setRenderHint(QPainter::Antialiasing, true);
// Add white background
painter.setBrush(QBrush(Qt::white));
painter.setPen(Qt::NoPen);
painter.drawRect(0, 0, landRect.width(), landRect.height());
// Paint landscape
render(&painter, QRectF(0, 0, landRect.width(), landRect.height()), landRect);
QImage scaledImage = image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
scaledImage.save(fileName);
}
QString LandscapeScene::zoneNameFromMousePos() const
{
if ((m_posY > 0) || (m_posY < -MAX_SCENE_HEIGHT) ||
(m_posX < 0) || (m_posX > MAX_SCENE_WIDTH))
return "NOT A VALID ZONE";
return QString("%1_%2%3 %4 %5 ").arg(-m_posY).arg(QChar('A' + (m_posX/26))).
arg(QChar('A' + (m_posX%26))).arg(m_mouseX, 0,'f',2).arg(-m_mouseY, 0,'f',2);
}
void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
qreal x = mouseEvent->scenePos().x();
qreal y = mouseEvent->scenePos().y();
if ((x < 0) || (y < 0))
return;
m_posX = sint32(floor(x / m_cellSize));
m_posY = sint32(-floor(y / m_cellSize));
if (m_zoneBuilder == 0)
return;
if (m_transitionMode)
{
if (mouseEvent->button() == Qt::LeftButton)
// Need add offset(= cellSize) on y axes
m_zoneBuilder->addTransition(sint(x), sint(-y + m_cellSize));
}
else
{
if (mouseEvent->button() == Qt::LeftButton)
m_zoneBuilder->addZone(m_posX, m_posY);
else if (mouseEvent->button() == Qt::RightButton)
m_zoneBuilder->delZone(m_posX, m_posY);
}
m_mouseButton = mouseEvent->button();
QGraphicsScene::mousePressEvent(mouseEvent);
}
void LandscapeScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
qreal x = mouseEvent->scenePos().x();
qreal y = mouseEvent->scenePos().y();
sint32 posX = sint32(floor(x / m_cellSize));
sint32 posY = sint32(-floor(y / m_cellSize));
if ((m_posX != posX || m_posY != posY) &&
(m_mouseButton == Qt::LeftButton ||
m_mouseButton == Qt::RightButton))
{
if (m_transitionMode)
{
}
else
{
if (m_mouseButton == Qt::LeftButton)
m_zoneBuilder->addZone(posX, posY);
else if (m_mouseButton == Qt::RightButton)
m_zoneBuilder->delZone(posX, posY);
}
m_posX = posX;
m_posY = posY;
QApplication::processEvents();
}
m_posX = posX;
m_posY = posY;
m_mouseX = mouseEvent->scenePos().x();
m_mouseY = mouseEvent->scenePos().y() - m_cellSize;
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
void LandscapeScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
m_mouseButton = Qt::NoButton;
}
bool LandscapeScene::checkUnderZone(const int posX, const int posY)
{
QGraphicsItem *item = itemAt((posX * m_cellSize), abs(posY) * m_cellSize);
if (item != 0)
{
//if (item->data(ZONE_NAME) == QString(LAYER_BLACKOUT_NAME))
// return false;
//else
return true;
}
return false;
}
bool LandscapeScene::transitionMode() const
{
return m_transitionMode;
}
void LandscapeScene::setTransitionMode(bool enabled)
{
m_transitionMode = enabled;
update();
}
void LandscapeScene::drawForeground(QPainter *painter, const QRectF &rect)
{
QGraphicsScene::drawForeground(painter, rect);
if ((m_zoneBuilder->currentIdZoneRegion() != -1) && (m_transitionMode))
drawTransition(painter, rect);
}
void LandscapeScene::drawTransition(QPainter *painter, const QRectF &rect)
{
int left = int(floor(rect.left() / m_cellSize));
int right = int(floor(rect.right() / m_cellSize));
int top = int(floor(rect.top() / m_cellSize));
int bottom = int(floor(rect.bottom() / m_cellSize));
QVector<QLine> redLines;
QVector<QLine> whiteLines;
for (int i = left; i < right + 1; ++i)
{
for (int j = top; j < bottom + 1; ++j)
{
// Get LIGO data
NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->currentZoneRegion()->ligoZoneRegion();
uint8 ceUp = zoneRegion.getCutEdge (i, -j, 0);
uint8 ceLeft = zoneRegion.getCutEdge (i, -j, 2);
if ((ceUp > 0) && (ceUp < 3))
{
// Calculate position vertical lines
int x1, x2, y1, y2;
y1 = j * m_cellSize + m_cellSize / 12.0f;
y2 = y1 - (m_cellSize / 6.0f);
x1 = i * m_cellSize + 3.0f * m_cellSize / 12.0f;
x2 = i * m_cellSize + 5.0f * m_cellSize / 12.0f;
if (ceUp == 1)
{
whiteLines.push_back(QLine(x1, y1, x1, y2));
whiteLines.push_back(QLine(x2, y1, x2, y2));
}
else
{
redLines.push_back(QLine(x1, y1, x1, y2));
redLines.push_back(QLine(x2, y1, x2, y2));
}
x1 = i * m_cellSize + 7.0f * m_cellSize / 12.0f;
x2 = i * m_cellSize + 9.0f * m_cellSize / 12.0f;
if (ceUp == 1)
{
redLines.push_back(QLine(x1, y1, x1, y2));
redLines.push_back(QLine(x2, y1, x2, y2));
}
else
{
whiteLines.push_back(QLine(x1, y1, x1, y2));
whiteLines.push_back(QLine(x2, y1, x2, y2));
}
}
if ((ceLeft > 0) && (ceLeft < 3))
{
// Calculate position horizontal lines
int x1, x2, y1, y2;
x1 = i * m_cellSize - m_cellSize / 12.0f;
x2 = x1 + (m_cellSize / 6.0f);
y1 = j * m_cellSize + 3.0f * m_cellSize / 12.0f;
y2 = j * m_cellSize + 5.0f * m_cellSize / 12.0f;
if (ceLeft == 1)
{
redLines.push_back(QLine(x1, y1, x2, y1));
redLines.push_back(QLine(x1, y2, x2, y2));
}
else
{
whiteLines.push_back(QLine(x1, y1, x2, y1));
whiteLines.push_back(QLine(x1, y2, x2, y2));
}
y1 = j * m_cellSize + 7.0f * m_cellSize / 12.0f;
y2 = j * m_cellSize + 9.0f * m_cellSize / 12.0f;
if (ceLeft == 1)
{
whiteLines.push_back(QLine(x1, y1, x2, y1));
whiteLines.push_back(QLine(x1, y2, x2, y2));
}
else
{
redLines.push_back(QLine(x1, y1, x2, y1));
redLines.push_back(QLine(x1, y2, x2, y2));
}
}
}
}
// Draw lines
painter->setPen(QPen(Qt::red, 0, Qt::SolidLine));
painter->drawLines(redLines);
painter->setPen(QPen(Qt::white, 0, Qt::SolidLine));
painter->drawLines(whiteLines);
}
} /* namespace LandscapeEditor */

@ -0,0 +1,89 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef LANDSCAPE_SCENE_H
#define LANDSCAPE_SCENE_H
// Project includes
#include "zone_region_editor.h"
#include "builder_zone.h"
#include "landscape_editor_global.h"
// NeL includes
#include <nel/ligo/zone_region.h>
// Qt includes
#include <QtGui/QGraphicsScene>
#include <QtGui/QGraphicsSceneMouseEvent>
namespace LandscapeEditor
{
/**
@class LandscapeScene
@brief
@details
*/
class LandscapeScene : public QGraphicsScene
{
Q_OBJECT
public:
LandscapeScene(int sizeCell = 160, QObject *parent = 0);
virtual ~LandscapeScene();
int cellSize() const;
void setZoneBuilder(ZoneBuilder *zoneBuilder);
QGraphicsItem *createItemZone(const LigoData &data, const ZonePosition &zonePos);
QGraphicsItem *createItemEmptyZone(const ZonePosition &zonePos);
QGraphicsRectItem *createLayerBlackout(const NLLIGO::CZoneRegion &zoneRegion);
void deleteItemZone(const ZonePosition &zonePos);
void addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
void delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
void snapshot(const QString &fileName, int width, int height, const QRectF &landRect);
QString zoneNameFromMousePos() const;
bool transitionMode() const;
public Q_SLOTS:
void setTransitionMode(bool enabled);
protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);
virtual void drawForeground(QPainter *painter, const QRectF &rect);
void drawTransition(QPainter *painter, const QRectF &rect);
private:
bool checkUnderZone(const int posX, const int posY);
int m_cellSize;
bool m_transitionMode;
qreal m_mouseX, m_mouseY;
sint32 m_posX, m_posY;
Qt::MouseButton m_mouseButton;
ZoneBuilder *m_zoneBuilder;
};
} /* namespace LandscapeEditor */
#endif // LANDSCAPE_SCENE_H

@ -0,0 +1,331 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Project includes
#include "landscape_scene_base.h"
#include "pixmap_database.h"
// NeL includes
#include <nel/misc/debug.h>
// Qt includes
#include <QtGui/QPainter>
#include <QtGui/QGraphicsPixmapItem>
#include <QtGui/QGraphicsSimpleTextItem>
#include <QApplication>
namespace LandscapeEditor
{
static const int ZONE_NAME = 0;
static const int LAYER_ZONES = 2;
static const int LAYER_EMPTY_ZONES = 3;
// TODO: delete
const char *const LAYER_BLACKOUT_NAME = "blackout";
const int MAX_SCENE_WIDTH = 256;
const int MAX_SCENE_HEIGHT = 256;
LandscapeSceneBase::LandscapeSceneBase(int sizeCell, QObject *parent)
: QGraphicsScene(parent),
m_cellSize(sizeCell),
m_zoneBuilderBase(0)
{
setSceneRect(QRectF(0, m_cellSize, MAX_SCENE_WIDTH * m_cellSize, MAX_SCENE_HEIGHT * m_cellSize));
}
LandscapeSceneBase::~LandscapeSceneBase()
{
}
int LandscapeSceneBase::cellSize() const
{
return m_cellSize;
}
void LandscapeSceneBase::setZoneBuilder(ZoneBuilderBase *zoneBuilder)
{
m_zoneBuilderBase = zoneBuilder;
}
QGraphicsItem *LandscapeSceneBase::createItemZone(const LigoData &data, const ZonePosition &zonePos)
{
if ((data.zoneName == STRING_OUT_OF_BOUND) || (checkUnderZone(zonePos.x, zonePos.y)))
return 0;
if (data.zoneName == STRING_UNUSED)
return createItemEmptyZone(zonePos);
if ((m_zoneBuilderBase == 0) || (data.zoneName.empty()))
return 0;
// Get image from pixmap database
QPixmap *pixmap = m_zoneBuilderBase->pixmapDatabase()->pixmap(QString(data.zoneName.c_str()));
if (pixmap == 0)
return 0;
// Rotate the image counter clockwise
QMatrix matrix;
matrix.rotate(-data.rot * 90.0);
QGraphicsPixmapItem *item;
if (data.flip == 0)
{
item = addPixmap(pixmap->transformed(matrix, Qt::SmoothTransformation));
}
else
{
// mirror image
QImage mirrorImage = pixmap->toImage();
QPixmap mirrorPixmap = QPixmap::fromImage(mirrorImage.mirrored(true, false));
item = addPixmap(mirrorPixmap.transformed(matrix, Qt::SmoothTransformation));
}
// Enable bilinear filtering
item->setTransformationMode(Qt::SmoothTransformation);
sint32 sizeX = 1, sizeY = 1;
sizeX = float(pixmap->width()) / m_zoneBuilderBase->pixmapDatabase()->textureSize();
sizeY = float(pixmap->width()) / m_zoneBuilderBase->pixmapDatabase()->textureSize();
sint32 deltaX = 0, deltaY = 0;
// Calculate offset for graphics item (for items with size that are larger than 1)
if ((sizeX > 1) || (sizeY > 1))
{
if (data.flip == 0)
{
switch (data.rot)
{
case 0:
deltaX = -data.posX;
deltaY = -data.posY + sizeY - 1;
break;
case 1:
deltaX = -(sizeY - 1 - data.posY);
deltaY = -data.posX + sizeX - 1;
break;
case 2:
deltaX = -(sizeX - 1 - data.posX);
deltaY = data.posY;
break;
case 3:
deltaX = -data.posY;
deltaY = data.posX;
break;
}
}
else
{
switch (data.rot)
{
case 0:
deltaX = -(sizeX - 1 - data.posX);
deltaY = -data.posY + sizeY - 1;
break;
case 1:
deltaX = -(sizeY - 1 - data.posY);
deltaY = +data.posX;
break;
case 2:
deltaX = -data.posX;
deltaY = data.posY;
break;
case 3:
deltaX = -data.posY;
deltaY = -data.posX + sizeX - 1;
break;
}
}
}
// Set position graphics item with offset for large piece
item->setPos((zonePos.x + deltaX) * m_cellSize, (abs(int(zonePos.y + deltaY))) * m_cellSize);
// The size graphics item should be equal or proportional m_cellSize
item->setScale(float(m_cellSize) / m_zoneBuilderBase->pixmapDatabase()->textureSize());
item->setData(ZONE_NAME, QString(data.zoneName.c_str()));
// for not full item zone
item->setZValue(LAYER_ZONES);
item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
return item;
}
QGraphicsItem *LandscapeSceneBase::createItemEmptyZone(const ZonePosition &zonePos)
{
if (m_zoneBuilderBase == 0)
return 0;
if (checkUnderZone(zonePos.x, zonePos.y))
return 0;
// Get image from pixmap database
QPixmap *pixmap = m_zoneBuilderBase->pixmapDatabase()->pixmap(QString(STRING_UNUSED));
if (pixmap == 0)
return 0;
QGraphicsPixmapItem *item = addPixmap(*pixmap);
// Enable bilinear filtering
item->setTransformationMode(Qt::SmoothTransformation);
// Set position graphics item
item->setPos(zonePos.x * m_cellSize, abs(int(zonePos.y)) * m_cellSize);
// The size graphics item should be equal or proportional m_cellSize
item->setScale(float(m_cellSize) / m_zoneBuilderBase->pixmapDatabase()->textureSize());
// for not full item zone
item->setZValue(LAYER_EMPTY_ZONES);
item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
return item;
}
void LandscapeSceneBase::deleteItemZone(const ZonePosition &zonePos)
{
QList<QGraphicsItem *> listItems = items(QPointF(zonePos.x * m_cellSize + 10, abs(zonePos.y) * m_cellSize + 10),
Qt::IntersectsItemBoundingRect, Qt::AscendingOrder);
Q_FOREACH(QGraphicsItem *item, listItems)
{
if (qgraphicsitem_cast<QGraphicsPixmapItem *>(item) != 0)
{
removeItem(item);
delete item;
return;
}
}
}
void LandscapeSceneBase::addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
{
for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
{
for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
{
std::string zoneName = zoneRegion.getName(i, j);
if (zoneName == STRING_UNUSED)
{
ZonePosition zonePos(i, j, -1);
QGraphicsItem *item = createItemEmptyZone(zonePos);
}
else if (!zoneName.empty())
{
LigoData data;
ZonePosition zonePos(i, j, -1);
data.zoneName = zoneName;
data.rot = zoneRegion.getRot(i, j);
data.flip = zoneRegion.getFlip(i, j);
data.posX = zoneRegion.getPosX(i, j);
data.posY = zoneRegion.getPosY(i, j);
QGraphicsItem *item = createItemZone(data, zonePos);
}
}
}
}
void LandscapeSceneBase::delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
{
for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
{
for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
{
deleteItemZone(ZonePosition(i, -j, -1));
}
}
}
void LandscapeSceneBase::snapshot(const QString &fileName, int width, int height, const QRectF &landRect)
{
if (m_zoneBuilderBase == 0)
return;
// Create image
QImage image(landRect.width(), landRect.height(), QImage::Format_RGB888);
QPainter painter(&image);
painter.setRenderHint(QPainter::Antialiasing, true);
// Add white background
painter.setBrush(QBrush(Qt::white));
painter.setPen(Qt::NoPen);
painter.drawRect(0, 0, landRect.width(), landRect.height());
// Paint landscape
render(&painter, QRectF(0, 0, landRect.width(), landRect.height()), landRect);
QImage scaledImage = image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
scaledImage.save(fileName);
}
QString LandscapeSceneBase::zoneNameFromMousePos() const
{
if ((m_posY > 0) || (m_posY < -MAX_SCENE_HEIGHT) ||
(m_posX < 0) || (m_posX > MAX_SCENE_WIDTH))
return "NOT A VALID ZONE";
return QString("%1_%2%3 %4 %5 ").arg(-m_posY+1).arg(QChar('A' + (m_posX/26))).
arg(QChar('A' + (m_posX%26))).arg(m_mouseX, 0,'f',2).arg(-m_mouseY, 0,'f',2);
}
void LandscapeSceneBase::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
QGraphicsScene::mousePressEvent(mouseEvent);
qreal x = mouseEvent->scenePos().x();
qreal y = mouseEvent->scenePos().y();
m_posX = sint32(floor(x / m_cellSize));
m_posY = sint32(-floor(y / m_cellSize));
}
void LandscapeSceneBase::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
m_mouseX = mouseEvent->scenePos().x();
m_mouseY = mouseEvent->scenePos().y() - m_cellSize;
m_posX = sint32(floor(m_mouseX / m_cellSize));
m_posY = sint32(-floor(m_mouseY / m_cellSize));
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
bool LandscapeSceneBase::checkUnderZone(const int posX, const int posY)
{
// TODO: Why crash program?
// QList<QGraphicsItem *> listItems = items(QPointF(posX * m_cellSize + 10, abs(posY) * m_cellSize + 10),
// Qt::IntersectsItemBoundingRect, Qt::AscendingOrder);
QList<QGraphicsItem *> listItems = items();
QPointF point(posX, abs(posY));
Q_FOREACH(QGraphicsItem *item, listItems)
{
if (item->pos() == point)
{
if (qgraphicsitem_cast<QGraphicsPixmapItem *>(item) != 0)
return true;
}
}
return false;
}
} /* namespace LandscapeEditor */

@ -0,0 +1,79 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef LANDSCAPE_SCENE_BASE_H
#define LANDSCAPE_SCENE_BASE_H
// Project includes
#include "landscape_editor_global.h"
#include "builder_zone_base.h"
#include "zone_region_editor.h"
// NeL includes
#include <nel/ligo/zone_region.h>
// Qt includes
#include <QtGui/QGraphicsScene>
#include <QtGui/QGraphicsSceneMouseEvent>
namespace LandscapeEditor
{
/**
@class LandscapeSceneBase
@brief
@details
*/
class LANDSCAPE_EDITOR_EXPORT LandscapeSceneBase : public QGraphicsScene
{
Q_OBJECT
public:
LandscapeSceneBase(int sizeCell = 160, QObject *parent = 0);
virtual ~LandscapeSceneBase();
int cellSize() const;
void setZoneBuilder(ZoneBuilderBase *zoneBuilder);
QGraphicsItem *createItemZone(const LigoData &data, const ZonePosition &zonePos);
QGraphicsItem *createItemEmptyZone(const ZonePosition &zonePos);
void deleteItemZone(const ZonePosition &zonePos);
void addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
void delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
void snapshot(const QString &fileName, int width, int height, const QRectF &landRect);
QString zoneNameFromMousePos() const;
public Q_SLOTS:
protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
private:
bool checkUnderZone(const int posX, const int posY);
int m_cellSize;
qreal m_mouseX, m_mouseY;
sint32 m_posX, m_posY;
ZoneBuilderBase *m_zoneBuilderBase;
};
} /* namespace LandscapeEditor */
#endif // LANDSCAPE_SCENE_BASE_H

@ -0,0 +1,254 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Project includes
#include "landscape_view.h"
#include "landscape_editor_constants.h"
#include "../core/icore.h"
#include "../core/core_constants.h"
// NeL includes
#include <nel/misc/debug.h>
// Qt includes
#include <QApplication>
namespace LandscapeEditor
{
LandscapeView::LandscapeView(QWidget *parent)
: QGraphicsView(parent),
m_visibleGrid(true),
m_visibleText(true)
{
setTransformationAnchor(AnchorUnderMouse);
setBackgroundBrush(QBrush(Qt::lightGray));
m_cellSize = 160;
m_maxView = 0.06;
m_minView = 32.0;
m_maxViewText = 0.6;
//A modified version of centerOn(), handles special cases
setCenter(QPointF(500.0, 500.0));
}
LandscapeView::~LandscapeView()
{
}
bool LandscapeView::isVisibleGrid() const
{
return m_visibleGrid;
}
void LandscapeView::setVisibleGrid(bool visible)
{
m_visibleGrid = visible;
scene()->update();
}
void LandscapeView::setVisibleText(bool visible)
{
m_visibleText = visible;
scene()->update();
}
void LandscapeView::wheelEvent(QWheelEvent *event)
{
//How fast we zoom
float numSteps = (( event->delta() / 8 ) / 15) * 1.2;
QMatrix mat = matrix();
QPointF mousePosition = event->pos();
mat.translate((width() / 2) - mousePosition.x(), (height() / 2) - mousePosition.y());
if ( numSteps > 0 )
mat.scale(numSteps, numSteps);
else
mat.scale(-1 / numSteps, -1 / numSteps);
mat.translate(mousePosition.x() - (width() / 2), mousePosition.y() - (height() / 2));
//Adjust to the new center for correct zooming
setMatrix(mat);
event->accept();
}
void LandscapeView::mousePressEvent(QMouseEvent *event)
{
QGraphicsView::mousePressEvent(event);
if (event->button() != Qt::MiddleButton)
return;
//For panning the view
m_lastPanPoint = event->pos();
setCursor(Qt::ClosedHandCursor);
}
void LandscapeView::mouseMoveEvent(QMouseEvent *event)
{
if(!m_lastPanPoint.isNull())
{
//Get how much we panned
QPointF delta = mapToScene(m_lastPanPoint) - mapToScene(event->pos());
m_lastPanPoint = event->pos();
//Update the center ie. do the pan
setCenter(getCenter() + delta);
}
QGraphicsView::mouseMoveEvent(event);
}
void LandscapeView::mouseReleaseEvent(QMouseEvent *event)
{
m_lastPanPoint = QPoint();
setCursor(Qt::ArrowCursor);
QGraphicsView::mouseReleaseEvent(event);
}
void LandscapeView::resizeEvent(QResizeEvent *event)
{
//Get the rectangle of the visible area in scene coords
QRectF visibleArea = mapToScene(rect()).boundingRect();
setCenter(visibleArea.center());
//Call the subclass resize so the scrollbars are updated correctly
QGraphicsView::resizeEvent(event);
}
void LandscapeView::setCenter(const QPointF &centerPoint)
{
//Get the rectangle of the visible area in scene coords
QRectF visibleArea = mapToScene(rect()).boundingRect();
//Get the scene area
QRectF sceneBounds = sceneRect();
double boundX = visibleArea.width() / 2.0;
double boundY = visibleArea.height() / 2.0;
double boundWidth = sceneBounds.width() - 2.0 * boundX;
double boundHeight = sceneBounds.height() - 2.0 * boundY;
//The max boundary that the centerPoint can be to
QRectF bounds(boundX, boundY, boundWidth, boundHeight);
if(bounds.contains(centerPoint))
{
//We are within the bounds
m_currentCenterPoint = centerPoint;
}
else
{
//We need to clamp or use the center of the screen
if(visibleArea.contains(sceneBounds))
{
//Use the center of scene ie. we can see the whole scene
m_currentCenterPoint = sceneBounds.center();
}
else
{
m_currentCenterPoint = centerPoint;
//We need to clamp the center. The centerPoint is too large
if (centerPoint.x() > bounds.x() + bounds.width())
m_currentCenterPoint.setX(bounds.x() + bounds.width());
else if(centerPoint.x() < bounds.x())
m_currentCenterPoint.setX(bounds.x());
if(centerPoint.y() > bounds.y() + bounds.height())
m_currentCenterPoint.setY(bounds.y() + bounds.height());
else if(centerPoint.y() < bounds.y())
m_currentCenterPoint.setY(bounds.y());
}
}
//Update the scrollbars
centerOn(m_currentCenterPoint);
}
QPointF LandscapeView::getCenter() const
{
//return m_currentCenterPoint;
return mapToScene(viewport()->rect().center());
}
void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect)
{
QGraphicsView::drawForeground(painter, rect);
if (!m_visibleGrid)
return;
painter->setPen(QPen(Qt::white, 0, Qt::SolidLine));
drawGrid(painter, rect);
if (!m_visibleText)
return;
if (transform().m11() > m_maxViewText)
{
painter->setPen(QPen(Qt::white, 0.5, Qt::SolidLine));
drawZoneNames(painter, rect);
}
}
void LandscapeView::drawGrid(QPainter *painter, const QRectF &rect)
{
qreal left = m_cellSize * floor(rect.left() / m_cellSize);
qreal top = m_cellSize * floor(rect.top() / m_cellSize);
QVector<QLine> lines;
// Calculate vertical lines
while (left < rect.right())
{
lines.push_back(QLine(int(left), int(rect.bottom()), int(left), int(rect.top())));
left += m_cellSize;
}
// Calculate horizontal lines
while (top < rect.bottom())
{
lines.push_back(QLine(int(rect.left()), int(top), int(rect.right()), int(top)));
top += m_cellSize;
}
// Draw lines
painter->drawLines(lines);
}
void LandscapeView::drawZoneNames(QPainter *painter, const QRectF &rect)
{
int leftSide = int(floor(rect.left() / m_cellSize));
int rightSide = int(floor(rect.right() / m_cellSize));
int topSide = int(floor(rect.top() / m_cellSize));
int bottomSide = int(floor(rect.bottom() / m_cellSize));
for (int i = leftSide; i < rightSide + 1; ++i)
{
for (int j = topSide; j < bottomSide + 1; ++j)
{
QString text = QString("%1_%2%3").arg(j).arg(QChar('A' + (i / 26))).arg(QChar('A' + (i % 26)));
painter->drawText(i * m_cellSize + 5, j * m_cellSize + 15, text);
}
}
}
} /* namespace LandscapeEditor */

@ -0,0 +1,84 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef LANDSCAPE_VIEW_H
#define LANDSCAPE_VIEW_H
// Project includes
#include "landscape_editor_global.h"
// Qt includes
#include <QtGui/QGraphicsView>
#include <QtGui/QWheelEvent>
namespace LandscapeEditor
{
/**
@class LandscapeView
@brief Provides graphics view for viewing zone regions.
@details Also provides zooming, panning and displaying grid
*/
class LANDSCAPE_EDITOR_EXPORT LandscapeView: public QGraphicsView
{
Q_OBJECT
public:
explicit LandscapeView(QWidget *parent = 0);
virtual ~LandscapeView();
//Set the current centerpoint in the
void setCenter(const QPointF &centerPoint);
QPointF getCenter() const;
bool isVisibleGrid() const;
public Q_SLOTS:
/// Enable/disable displaying grid.
void setVisibleGrid(bool visible);
/// Enable/disable displaying text(coord.) above each zone bricks.
void setVisibleText(bool visible);
private Q_SLOTS:
protected:
//Take over the interaction
virtual void wheelEvent(QWheelEvent *event);
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
virtual void drawForeground(QPainter *painter, const QRectF &rect);
virtual void resizeEvent(QResizeEvent *event);
void drawGrid(QPainter *painter, const QRectF &rect);
void drawZoneNames(QPainter *painter, const QRectF &rect);
private:
bool m_visibleGrid, m_visibleText;
qreal m_maxView, m_minView, m_maxViewText;
int m_cellSize;
//Holds the current centerpoint for the view, used for panning and zooming
QPointF m_currentCenterPoint;
//From panning the view
QPoint m_lastPanPoint;
}; /* class LandscapeView */
} /* namespace LandscapeEditor */
#endif // LANDSCAPE_VIEW_H

@ -0,0 +1,137 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Project includes
#include "list_zones_model.h"
#include "builder_zone.h"
// NeL includes
#include <nel/misc/debug.h>
// STL includes
#include <string>
#include <vector>
// Qt includes
#include <QApplication>
#include <QtGui/QProgressDialog>
namespace LandscapeEditor
{
ListZonesModel::ListZonesModel(int scaleRatio, QObject *parent)
: QAbstractListModel(parent),
m_scaleRatio(scaleRatio)
{
}
ListZonesModel::~ListZonesModel()
{
resetModel();
}
int ListZonesModel::rowCount(const QModelIndex & /* parent */) const
{
return m_listNames.count();
}
int ListZonesModel::columnCount(const QModelIndex & /* parent */) const
{
return 1;
}
QVariant ListZonesModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
switch (role)
{
case Qt::TextAlignmentRole:
return int(Qt::AlignLeft | Qt::AlignVCenter);
case Qt::DisplayRole:
return m_listNames.at(index.row());
case Qt::DecorationRole:
{
QPixmap *pixmap = getPixmap(m_listNames.at(index.row()));
return qVariantFromValue(*pixmap);
}
default:
return QVariant();
}
}
QVariant ListZonesModel::headerData(int section, Qt::Orientation, int role) const
{
return QVariant();
}
void ListZonesModel::setScaleRatio(int scaleRatio)
{
m_scaleRatio = scaleRatio;
}
void ListZonesModel::setListZones(QStringList &listZones)
{
beginResetModel();
m_listNames.clear();
m_listNames = listZones;
endResetModel();
}
void ListZonesModel::resetModel()
{
beginResetModel();
QStringList listNames(m_pixmapMap.keys());
Q_FOREACH(QString name, listNames)
{
QPixmap *pixmap = m_pixmapMap.value(name);
delete pixmap;
}
m_pixmapMap.clear();
m_listNames.clear();
endResetModel();
}
void ListZonesModel::rebuildModel(PixmapDatabase *pixmapDatabase)
{
resetModel();
beginResetModel();
QStringList listNames;
listNames = pixmapDatabase->listPixmaps();
Q_FOREACH(QString name, listNames)
{
QPixmap *pixmap = pixmapDatabase->pixmap(name);
QPixmap *smallPixmap = new QPixmap(pixmap->scaled(pixmap->width() / m_scaleRatio, pixmap->height() / m_scaleRatio));
m_pixmapMap.insert(name, smallPixmap);
}
endResetModel();
}
QPixmap *ListZonesModel::getPixmap(const QString &zoneName) const
{
QPixmap *result = 0;
if (!m_pixmapMap.contains(zoneName))
nlwarning("QPixmap %s not found", zoneName.toUtf8().constData());
else
result = m_pixmapMap.value(zoneName);
return result;
}
} /* namespace LandscapeEditor */

@ -0,0 +1,79 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef LIST_ZONES_MODEL_H
#define LIST_ZONES_MODEL_H
// Project includes
// NeL includes
#include <nel/ligo/zone_bank.h>
// Qt includes
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtGui/QPixmap>
#include <QAbstractListModel>
namespace LandscapeEditor
{
class PixmapDatabase;
/**
@class ListZonesModel
@brief ListZonesModel is used for managed list bricks by ListZonesWidget
@details ListZonesModel contains the small images for QListView
*/
class ListZonesModel : public QAbstractListModel
{
Q_OBJECT
public:
ListZonesModel(int scaleRatio = 4, QObject *parent = 0);
~ListZonesModel();
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role) const;
/// Set size for small pixmaps
/// Value should be set before calling rebuildModel
void setScaleRatio(int scaleRatio);
/// Delete all small images and reset model
void resetModel();
/// Set current list zones which will be available in QListView
void setListZones(QStringList &listZones);
/// Build own pixmaps database(all images are scaled: width/scaleRatio, height/scaleRatio) from pixmapDatabase
void rebuildModel(PixmapDatabase *pixmapDatabase);
private:
/// Get pixmap
/// @return QPixmap* if the image is in the database ; otherwise returns 0.
QPixmap *getPixmap(const QString &zoneName) const;
int m_scaleRatio;
QMap<QString, QPixmap *> m_pixmapMap;
QStringList m_listNames;
};
} /* namespace LandscapeEditor */
#endif // LIST_ZONES_MODEL_H

@ -0,0 +1,308 @@
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Project includes
#include "list_zones_widget.h"
#include "list_zones_model.h"
#include "builder_zone.h"
// NeL includes
#include <nel/misc/debug.h>
#include <nel/ligo/zone_bank.h>
#include <nel/ligo/zone_region.h>
// STL includes
#include <vector>
#include <string>
// Qt includes
#include <QtGui/QIcon>
#include <QtCore/QModelIndex>
namespace LandscapeEditor
{
ListZonesWidget::ListZonesWidget(QWidget *parent)
: QWidget(parent),
m_rotCycle(0),
m_flipCycle(0),
m_listZonesModel(0),
m_zoneBuilder(0)
{
m_ui.setupUi(this);
m_listZonesModel = new ListZonesModel(4, this);
m_ui.listView->setModel(m_listZonesModel);
m_ui.addFilterButton_1->setChecked(false);
m_ui.addFilterButton_2->setChecked(false);
m_ui.addFilterButton_3->setChecked(false);
connect(m_ui.categoryTypeComboBox_1, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_1(QString)));
connect(m_ui.categoryTypeComboBox_2, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_2(QString)));
connect(m_ui.categoryTypeComboBox_3, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_3(QString)));
connect(m_ui.categoryTypeComboBox_4, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_4(QString)));
connect(m_ui.categoryValueComboBox_1, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
connect(m_ui.categoryValueComboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
connect(m_ui.categoryValueComboBox_3, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
connect(m_ui.categoryValueComboBox_4, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
connect(m_ui.logicComboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
connect(m_ui.logicComboBox_3, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
connect(m_ui.logicComboBox_4, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
}
ListZonesWidget::~ListZonesWidget()
{
}
void ListZonesWidget::updateUi()
{
if (m_zoneBuilder == 0)
return;
disableSignals(true);
std::vector<std::string> listCategoryType;
m_zoneBuilder->getZoneBank().getCategoriesType(listCategoryType);
QStringList listCategories;
listCategories << STRING_UNUSED;
for (size_t i = 0; i < listCategoryType.size(); ++i)
listCategories << QString(listCategoryType[i].c_str());
m_ui.categoryTypeComboBox_1->clear();
m_ui.categoryTypeComboBox_2->clear();
m_ui.categoryTypeComboBox_3->clear();
m_ui.categoryTypeComboBox_4->clear();
m_ui.categoryValueComboBox_1->clear();
m_ui.categoryValueComboBox_2->clear();
m_ui.categoryValueComboBox_3->clear();
m_ui.categoryValueComboBox_4->clear();
m_ui.categoryTypeComboBox_1->addItems(listCategories);
m_ui.categoryTypeComboBox_2->addItems(listCategories);
m_ui.categoryTypeComboBox_3->addItems(listCategories);
m_ui.categoryTypeComboBox_4->addItems(listCategories);
disableSignals(false);
m_listZonesModel->rebuildModel(m_zoneBuilder->pixmapDatabase());
}
QString ListZonesWidget::currentZoneName()
{
QString zoneName = "";
QModelIndex index = m_ui.listView->currentIndex();
if (index.isValid())
zoneName = index.data().toString();
if (m_ui.zoneSelectComboBox->currentIndex() == 1)
{
// Random value
if (m_listSelection.size() > 0)
{
uint32 randZone = uint32(NLMISC::frand(m_listSelection.size()));
NLMISC::clamp(randZone, (uint32)0, uint32(m_listSelection.size() - 1));
zoneName = m_listSelection[randZone];
}
}
else if (m_ui.zoneSelectComboBox->currentIndex() == 2)
{
// Full cycle
if (m_listSelection.size() > 0)
{
zoneName = m_listSelection[m_zoneNameCycle];
m_zoneNameCycle++;
m_zoneNameCycle = m_zoneNameCycle % m_listSelection.size();
}
}
return zoneName;
}
int ListZonesWidget::currentRot()
{
int rot = m_ui.rotComboBox->currentIndex();
if (rot == 4)
{
// Random value
uint32 randRot = uint32(NLMISC::frand(4.0));
NLMISC::clamp(randRot, (uint32)0, (uint32)3);
rot = int(randRot);
}
else if (rot == 5)
{
// Full cycle
rot = m_rotCycle;
m_rotCycle++;
m_rotCycle = m_rotCycle % 4;
}
return rot;
}
int ListZonesWidget::currentFlip()
{
int flip = m_ui.flipComboBox->currentIndex();
if (flip == 2)
{
// Random value
uint32 randFlip = uint32(NLMISC::frand(2.0));
NLMISC::clamp (randFlip, (uint32)0, (uint32)1);
flip = int(randFlip);
}
else if (flip == 3)
{
// Full cycle
flip = m_flipCycle;
m_flipCycle++;
m_flipCycle = m_flipCycle % 2;
}
return flip;
}
bool ListZonesWidget::isNotPropogate() const
{
return m_ui.propogateCheckBox->isChecked();
}
bool ListZonesWidget::isForce() const
{
return m_ui.forceCheckBox->isChecked();
}
void ListZonesWidget::setZoneBuilder(ZoneBuilder *zoneBuilder)
{
m_zoneBuilder = zoneBuilder;
}
void ListZonesWidget::updateFilters_1(const QString &value)
{
disableSignals(true);
std::vector<std::string> allCategoryValues;
m_zoneBuilder->getZoneBank().getCategoryValues(value.toUtf8().constData(), allCategoryValues);
m_ui.categoryValueComboBox_1->clear();
for(size_t i = 0; i < allCategoryValues.size(); ++i)
m_ui.categoryValueComboBox_1->addItem(QString(allCategoryValues[i].c_str()));
disableSignals(false);
updateListZones();
}
void ListZonesWidget::updateFilters_2(const QString &value)
{
disableSignals(true);
std::vector<std::string> allCategoryValues;
m_zoneBuilder->getZoneBank().getCategoryValues(value.toUtf8().constData(), allCategoryValues);
m_ui.categoryValueComboBox_2->clear();
for(size_t i = 0; i < allCategoryValues.size(); ++i)
m_ui.categoryValueComboBox_2->addItem(QString(allCategoryValues[i].c_str()));
disableSignals(false);
updateListZones();
}
void ListZonesWidget::updateFilters_3(const QString &value)
{
disableSignals(true);
std::vector<std::string> allCategoryValues;
m_zoneBuilder->getZoneBank().getCategoryValues(value.toUtf8().constData(), allCategoryValues);
m_ui.categoryValueComboBox_3->clear();
for(size_t i = 0; i < allCategoryValues.size(); ++i)
m_ui.categoryValueComboBox_3->addItem(QString(allCategoryValues[i].c_str()));
disableSignals(false);
updateListZones();
}
void ListZonesWidget::updateFilters_4(const QString &value)
{
disableSignals(true);
std::vector<std::string> allCategoryValues;
m_zoneBuilder->getZoneBank().getCategoryValues(value.toUtf8().constData(), allCategoryValues);
m_ui.categoryValueComboBox_4->clear();
for(size_t i = 0; i < allCategoryValues.size(); ++i)
m_ui.categoryValueComboBox_4->addItem(QString(allCategoryValues[i].c_str()));
disableSignals(false);
updateListZones();
}
void ListZonesWidget::updateListZones()
{
// Execute the filter
NLLIGO::CZoneBank &zoneBank = m_zoneBuilder->getZoneBank();
zoneBank.resetSelection ();
if(m_ui.categoryTypeComboBox_1->currentIndex() > 0 )
zoneBank.addOrSwitch (m_ui.categoryTypeComboBox_1->currentText().toUtf8().constData()
, m_ui.categoryValueComboBox_1->currentText().toUtf8().constData());
if(m_ui.categoryTypeComboBox_2->currentIndex() > 0 )
{
if (m_ui.logicComboBox_2->currentIndex() == 0) // AND switch wanted
zoneBank.addAndSwitch(m_ui.categoryTypeComboBox_2->currentText().toUtf8().constData()
,m_ui.categoryValueComboBox_2->currentText().toUtf8().constData());
else // OR switch wanted
zoneBank.addOrSwitch(m_ui.categoryTypeComboBox_2->currentText().toUtf8().constData()
,m_ui.categoryValueComboBox_2->currentText().toUtf8().constData());
}
if(m_ui.categoryTypeComboBox_3->currentIndex() > 0 )
{
if (m_ui.logicComboBox_3->currentIndex() == 0) // AND switch wanted
zoneBank.addAndSwitch(m_ui.categoryTypeComboBox_3->currentText().toUtf8().constData()
,m_ui.categoryValueComboBox_3->currentText().toUtf8().constData());
else // OR switch wanted
zoneBank.addOrSwitch(m_ui.categoryTypeComboBox_3->currentText().toUtf8().constData()
,m_ui.categoryValueComboBox_3->currentText().toUtf8().constData());
}
if(m_ui.categoryTypeComboBox_4->currentIndex() > 0 )
{
if (m_ui.logicComboBox_4->currentIndex() == 0) // AND switch wanted
zoneBank.addAndSwitch(m_ui.categoryTypeComboBox_4->currentText().toUtf8().constData()
,m_ui.categoryValueComboBox_4->currentText().toUtf8().constData());
else // OR switch wanted
zoneBank.addOrSwitch(m_ui.categoryTypeComboBox_4->currentText().toUtf8().constData()
,m_ui.categoryValueComboBox_4->currentText().toUtf8().constData());
}
std::vector<NLLIGO::CZoneBankElement *> currentSelection;
zoneBank.getSelection (currentSelection);
m_listSelection.clear();
m_zoneNameCycle = 0;
for (size_t i = 0; i < currentSelection.size(); ++i)
m_listSelection << currentSelection[i]->getName().c_str();
m_listZonesModel->setListZones(m_listSelection);
}
void ListZonesWidget::disableSignals(bool block)
{
m_ui.categoryTypeComboBox_1->blockSignals(block);
m_ui.categoryTypeComboBox_2->blockSignals(block);
m_ui.categoryTypeComboBox_3->blockSignals(block);
m_ui.categoryTypeComboBox_4->blockSignals(block);
m_ui.categoryValueComboBox_1->blockSignals(block);
m_ui.categoryValueComboBox_2->blockSignals(block);
m_ui.categoryValueComboBox_3->blockSignals(block);
m_ui.categoryValueComboBox_4->blockSignals(block);
}
} /* namespace LandscapeEditor */

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save