reduce the use of GSlist
Quake3FileSystem::forEachFile: avoid double extension check, support "*", as advertised
This commit is contained in:
parent
41c3dfc96e
commit
aa4f3a1f72
|
|
@ -75,18 +75,6 @@ public:
|
||||||
/// Use "*" as \p extension to match all file extensions.
|
/// Use "*" as \p extension to match all file extensions.
|
||||||
virtual void forEachFile( const char* basedir, const char* extension, const FileNameCallback& callback, std::size_t depth = 1 ) = 0;
|
virtual void forEachFile( const char* basedir, const char* extension, const FileNameCallback& callback, std::size_t depth = 1 ) = 0;
|
||||||
|
|
||||||
/// \brief Returns a list containing the relative names of all the directories under \p basedir.
|
|
||||||
/// The caller must free the returned list by calling \c clearFileDirList;
|
|
||||||
/// \deprecated Deprecated - use \c forEachDirectory.
|
|
||||||
virtual GSList* getDirList( const char *basedir ) = 0;
|
|
||||||
/// \brief Returns a list containing the relative names of the files under \p basedir (\p extension can be "*" for all files).
|
|
||||||
/// The caller must free the returned list by calling \c clearFileDirList.
|
|
||||||
/// \deprecated Deprecated - use \c forEachFile.
|
|
||||||
virtual GSList* getFileList( const char *basedir, const char *extension ) = 0;
|
|
||||||
/// \brief Frees the \p list returned from \c getDirList or \c getFileList.
|
|
||||||
/// \deprecated Deprecated.
|
|
||||||
virtual void clearFileDirList( GSList **list ) = 0;
|
|
||||||
|
|
||||||
/// \brief Returns the absolute filename for a relative \p name, or "" if not found.
|
/// \brief Returns the absolute filename for a relative \p name, or "" if not found.
|
||||||
virtual const char* findFile( const char* name ) = 0;
|
virtual const char* findFile( const char* name ) = 0;
|
||||||
/// \brief Returns the filesystem root for an absolute \p name, or "" if not found.
|
/// \brief Returns the filesystem root for an absolute \p name, or "" if not found.
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,6 @@ public:
|
||||||
virtual qtexture_t* lightFalloffImage() const = 0;
|
virtual qtexture_t* lightFalloffImage() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _GSList GSList;
|
|
||||||
typedef Callback1<const char*> ShaderNameCallback;
|
typedef Callback1<const char*> ShaderNameCallback;
|
||||||
|
|
||||||
class ModuleObserver;
|
class ModuleObserver;
|
||||||
|
|
|
||||||
|
|
@ -1511,11 +1511,7 @@ IShader *Shader_ForName( const char *name ){
|
||||||
|
|
||||||
// the list of scripts/*.shader files we need to work with
|
// the list of scripts/*.shader files we need to work with
|
||||||
// those are listed in shaderlist file
|
// those are listed in shaderlist file
|
||||||
GSList *l_shaderfiles = 0;
|
std::vector<CopiedString> l_shaderfiles;
|
||||||
|
|
||||||
GSList* Shaders_getShaderFileList(){
|
|
||||||
return l_shaderfiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
|
|
@ -1526,9 +1522,9 @@ GSList* Shaders_getShaderFileList(){
|
||||||
void IfFound_dumpUnreferencedShader( bool& bFound, const char* filename ){
|
void IfFound_dumpUnreferencedShader( bool& bFound, const char* filename ){
|
||||||
bool listed = false;
|
bool listed = false;
|
||||||
|
|
||||||
for ( GSList* sh = l_shaderfiles; sh != 0; sh = g_slist_next( sh ) )
|
for ( const CopiedString& sh : l_shaderfiles )
|
||||||
{
|
{
|
||||||
if ( !strcmp( (char*)sh->data, filename ) ) {
|
if ( !strcmp( sh.c_str(), filename ) ) {
|
||||||
listed = true;
|
listed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1552,17 +1548,17 @@ void DumpUnreferencedShaders(){
|
||||||
void ShaderList_addShaderFile( const char* dirstring ){
|
void ShaderList_addShaderFile( const char* dirstring ){
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
for ( GSList* tmp = l_shaderfiles; tmp != 0; tmp = tmp->next )
|
for ( const CopiedString& sh : l_shaderfiles )
|
||||||
{
|
{
|
||||||
if ( string_equal_nocase( dirstring, (char*)tmp->data ) ) {
|
if ( string_equal_nocase( dirstring, sh.c_str() ) ) {
|
||||||
found = true;
|
found = true;
|
||||||
globalOutputStream() << "duplicate entry \"" << (char*)tmp->data << "\" in shaderlist.txt\n";
|
globalOutputStream() << "duplicate entry \"" << sh.c_str() << "\" in shaderlist.txt\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !found ) {
|
if ( !found ) {
|
||||||
l_shaderfiles = g_slist_append( l_shaderfiles, strdup( dirstring ) );
|
l_shaderfiles.emplace_back( dirstring );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1597,14 +1593,6 @@ void BuildShaderList( TextInputStream& shaderlist ){
|
||||||
tokeniser.release();
|
tokeniser.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreeShaderList(){
|
|
||||||
while ( l_shaderfiles != 0 )
|
|
||||||
{
|
|
||||||
free( l_shaderfiles->data );
|
|
||||||
l_shaderfiles = g_slist_remove( l_shaderfiles, l_shaderfiles->data );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShaderList_addFromArchive( const char *archivename ){
|
void ShaderList_addFromArchive( const char *archivename ){
|
||||||
const char *shaderpath = GlobalRadiant().getGameDescriptionKeyValue( "shaderpath" );
|
const char *shaderpath = GlobalRadiant().getGameDescriptionKeyValue( "shaderpath" );
|
||||||
if ( string_empty( shaderpath ) ) {
|
if ( string_empty( shaderpath ) ) {
|
||||||
|
|
@ -1673,7 +1661,7 @@ void Shaders_Load(){
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalFileSystem().forEachArchive( AddShaderListFromArchiveCaller(), false, true );
|
GlobalFileSystem().forEachArchive( AddShaderListFromArchiveCaller(), false, true );
|
||||||
if( l_shaderfiles != nullptr ){
|
if( !l_shaderfiles.empty() ){
|
||||||
DumpUnreferencedShaders();
|
DumpUnreferencedShaders();
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
@ -1686,14 +1674,12 @@ void Shaders_Load(){
|
||||||
GlobalFileSystem().forEachFile( path.c_str(), g_shadersExtension, AddShaderFileCaller(), 0 );
|
GlobalFileSystem().forEachFile( path.c_str(), g_shadersExtension, AddShaderFileCaller(), 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList *lst = l_shaderfiles;
|
|
||||||
StringOutputStream shadername( 256 );
|
StringOutputStream shadername( 256 );
|
||||||
while ( lst )
|
for( const CopiedString& sh : l_shaderfiles )
|
||||||
{
|
{
|
||||||
shadername << path.c_str() << reinterpret_cast<const char*>( lst->data );
|
shadername << path.c_str() << sh.c_str();
|
||||||
LoadShaderFile( shadername.c_str() );
|
LoadShaderFile( shadername.c_str() );
|
||||||
shadername.clear();
|
shadername.clear();
|
||||||
lst = lst->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1702,7 +1688,7 @@ void Shaders_Load(){
|
||||||
|
|
||||||
void Shaders_Free(){
|
void Shaders_Free(){
|
||||||
FreeShaders();
|
FreeShaders();
|
||||||
FreeShaderList();
|
l_shaderfiles.clear();
|
||||||
g_shaderFilenames.clear();
|
g_shaderFilenames.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ struct archive_entry_t
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
typedef std::list<archive_entry_t> archives_t;
|
using archives_t = std::list<archive_entry_t>;
|
||||||
|
|
||||||
static archives_t g_archives;
|
static archives_t g_archives;
|
||||||
static char g_strDirs[VFS_MAXDIRS][PATH_MAX + 1];
|
static char g_strDirs[VFS_MAXDIRS][PATH_MAX + 1];
|
||||||
|
|
@ -96,6 +96,8 @@ static constexpr bool g_bUsePak = true;
|
||||||
|
|
||||||
ModuleObservers g_observers;
|
ModuleObservers g_observers;
|
||||||
|
|
||||||
|
using StrList = std::vector<CopiedString>;
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Static functions
|
// Static functions
|
||||||
|
|
||||||
|
|
@ -146,22 +148,18 @@ static void InitPakFile( ArchiveModules& archiveModules, const char *filename ){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void pathlist_prepend_unique( GSList*& pathlist, char* path ){
|
inline void pathlist_append_unique( StrList& pathlist, CopiedString path ){
|
||||||
if ( g_slist_find_custom( pathlist, path, (GCompareFunc)path_compare ) == 0 ) {
|
if( pathlist.cend() == std::find_if( pathlist.cbegin(), pathlist.cend(),
|
||||||
pathlist = g_slist_prepend( pathlist, path );
|
[&path]( const CopiedString& str ){ return path_compare( str.c_str(), path.c_str() ) == 0; } ) )
|
||||||
}
|
pathlist.emplace_back( std::move( path ) );
|
||||||
else
|
|
||||||
{
|
|
||||||
g_free( path );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DirectoryListVisitor : public Archive::Visitor
|
class DirectoryListVisitor : public Archive::Visitor
|
||||||
{
|
{
|
||||||
GSList*& m_matches;
|
StrList& m_matches;
|
||||||
const char* m_directory;
|
const char* m_directory;
|
||||||
public:
|
public:
|
||||||
DirectoryListVisitor( GSList*& matches, const char* directory )
|
DirectoryListVisitor( StrList& matches, const char* directory )
|
||||||
: m_matches( matches ), m_directory( directory )
|
: m_matches( matches ), m_directory( directory )
|
||||||
{}
|
{}
|
||||||
void visit( const char* name ){
|
void visit( const char* name ){
|
||||||
|
|
@ -170,23 +168,22 @@ public:
|
||||||
if ( subname[0] == '/' ) {
|
if ( subname[0] == '/' ) {
|
||||||
++subname;
|
++subname;
|
||||||
}
|
}
|
||||||
char* dir = g_strdup( subname );
|
const char* last_char = subname + strlen( subname );
|
||||||
char* last_char = dir + strlen( dir );
|
if ( last_char != subname && *( last_char - 1 ) == '/' ) {
|
||||||
if ( last_char != dir && *( --last_char ) == '/' ) {
|
--last_char;
|
||||||
*last_char = '\0';
|
|
||||||
}
|
}
|
||||||
pathlist_prepend_unique( m_matches, dir );
|
pathlist_append_unique( m_matches, StringRange( subname, last_char ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileListVisitor : public Archive::Visitor
|
class FileListVisitor : public Archive::Visitor
|
||||||
{
|
{
|
||||||
GSList*& m_matches;
|
StrList& m_matches;
|
||||||
const char* m_directory;
|
const char* m_directory;
|
||||||
const char* m_extension;
|
const char* m_extension;
|
||||||
public:
|
public:
|
||||||
FileListVisitor( GSList*& matches, const char* directory, const char* extension )
|
FileListVisitor( StrList& matches, const char* directory, const char* extension )
|
||||||
: m_matches( matches ), m_directory( directory ), m_extension( extension )
|
: m_matches( matches ), m_directory( directory ), m_extension( extension )
|
||||||
{}
|
{}
|
||||||
void visit( const char* name ){
|
void visit( const char* name ){
|
||||||
|
|
@ -196,14 +193,14 @@ public:
|
||||||
++subname;
|
++subname;
|
||||||
}
|
}
|
||||||
if ( m_extension[0] == '*' || extension_equal( path_get_extension( subname ), m_extension ) ) {
|
if ( m_extension[0] == '*' || extension_equal( path_get_extension( subname ), m_extension ) ) {
|
||||||
pathlist_prepend_unique( m_matches, g_strdup( subname ) );
|
pathlist_append_unique( m_matches, subname );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static GSList* GetListInternal( const char *refdir, const char *ext, bool directories, std::size_t depth ){
|
static StrList GetListInternal( const char *refdir, const char *ext, bool directories, std::size_t depth ){
|
||||||
GSList* files = 0;
|
StrList files;
|
||||||
|
|
||||||
ASSERT_MESSAGE( refdir[strlen( refdir ) - 1] == '/', "search path does not end in '/'" );
|
ASSERT_MESSAGE( refdir[strlen( refdir ) - 1] == '/', "search path does not end in '/'" );
|
||||||
|
|
||||||
|
|
@ -223,8 +220,6 @@ static GSList* GetListInternal( const char *refdir, const char *ext, bool direct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
files = g_slist_reverse( files );
|
|
||||||
|
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -507,22 +502,14 @@ void FreeFile( void *p ){
|
||||||
free( p );
|
free( p );
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList* GetFileList( const char *dir, const char *ext, std::size_t depth ){
|
StrList GetFileList( const char *dir, const char *ext, std::size_t depth ){
|
||||||
return GetListInternal( dir, ext, false, depth );
|
return GetListInternal( dir, ext, false, depth );
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList* GetDirList( const char *dir, std::size_t depth ){
|
StrList GetDirList( const char *dir, std::size_t depth ){
|
||||||
return GetListInternal( dir, 0, true, depth );
|
return GetListInternal( dir, 0, true, depth );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearFileDirList( GSList **lst ){
|
|
||||||
while ( *lst )
|
|
||||||
{
|
|
||||||
g_free( ( *lst )->data );
|
|
||||||
*lst = g_slist_remove( *lst, ( *lst )->data );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* FindFile( const char* relative ){
|
const char* FindFile( const char* relative ){
|
||||||
for ( archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i )
|
for ( archives_t::iterator i = g_archives.begin(); i != g_archives.end(); ++i )
|
||||||
{
|
{
|
||||||
|
|
@ -582,37 +569,31 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void forEachDirectory( const char* basedir, const FileNameCallback& callback, std::size_t depth ){
|
void forEachDirectory( const char* basedir, const FileNameCallback& callback, std::size_t depth ){
|
||||||
GSList* list = GetDirList( basedir, depth );
|
StrList list = GetDirList( basedir, depth );
|
||||||
|
|
||||||
for ( GSList* i = list; i != 0; i = g_slist_next( i ) )
|
for ( const CopiedString& str : list )
|
||||||
{
|
{
|
||||||
callback( reinterpret_cast<const char*>( ( *i ).data ) );
|
callback( str.c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearFileDirList( &list );
|
|
||||||
}
|
}
|
||||||
void forEachFile( const char* basedir, const char* extension, const FileNameCallback& callback, std::size_t depth ){
|
void forEachFile( const char* basedir, const char* extension, const FileNameCallback& callback, std::size_t depth ){
|
||||||
GSList* list = GetFileList( basedir, extension, depth );
|
StrList list = GetFileList( basedir, extension, depth );
|
||||||
|
|
||||||
for ( GSList* i = list; i != 0; i = g_slist_next( i ) )
|
for ( const CopiedString& str : list )
|
||||||
{
|
{
|
||||||
const char* name = reinterpret_cast<const char*>( ( *i ).data );
|
callback( str.c_str() );
|
||||||
if ( extension_equal( path_get_extension( name ), extension ) ) {
|
|
||||||
callback( name );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearFileDirList( &list );
|
|
||||||
}
|
}
|
||||||
GSList* getDirList( const char *basedir ){
|
/// \brief Returns a list containing the relative names of all the directories under \p basedir.
|
||||||
|
/// \deprecated Deprecated - use \c forEachDirectory.
|
||||||
|
StrList getDirList( const char *basedir ){
|
||||||
return GetDirList( basedir, 1 );
|
return GetDirList( basedir, 1 );
|
||||||
}
|
}
|
||||||
GSList* getFileList( const char *basedir, const char *extension ){
|
/// \brief Returns a list containing the relative names of the files under \p basedir (\p extension can be "*" for all files).
|
||||||
|
/// \deprecated Deprecated - use \c forEachFile.
|
||||||
|
StrList getFileList( const char *basedir, const char *extension ){
|
||||||
return GetFileList( basedir, extension, 1 );
|
return GetFileList( basedir, extension, 1 );
|
||||||
}
|
}
|
||||||
void clearFileDirList( GSList **lst ){
|
|
||||||
ClearFileDirList( lst );
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* findFile( const char *name ){
|
const char* findFile( const char *name ){
|
||||||
return FindFile( name );
|
return FindFile( name );
|
||||||
|
|
|
||||||
|
|
@ -930,7 +930,7 @@ EMessageBoxReturn DoLightIntensityDlg( int *intensity ){
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Add new shader tag dialog
|
// Add new shader tag dialog
|
||||||
|
|
||||||
EMessageBoxReturn DoShaderTagDlg( CopiedString* tag, const char* title ){
|
EMessageBoxReturn DoShaderTagDlg( CopiedString& tag, const char* title ){
|
||||||
ModalDialog dialog;
|
ModalDialog dialog;
|
||||||
GtkEntry* textentry;
|
GtkEntry* textentry;
|
||||||
ModalDialogButton ok_button( dialog, eIDOK );
|
ModalDialogButton ok_button( dialog, eIDOK );
|
||||||
|
|
@ -983,7 +983,7 @@ EMessageBoxReturn DoShaderTagDlg( CopiedString* tag, const char* title ){
|
||||||
|
|
||||||
EMessageBoxReturn ret = modal_dialog_show( window, dialog );
|
EMessageBoxReturn ret = modal_dialog_show( window, dialog );
|
||||||
if ( ret == eIDOK ) {
|
if ( ret == eIDOK ) {
|
||||||
*tag = gtk_entry_get_text( textentry );
|
tag = gtk_entry_get_text( textentry );
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_widget_destroy( GTK_WIDGET( window ) );
|
gtk_widget_destroy( GTK_WIDGET( window ) );
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
#include "string/string.h"
|
#include "string/string.h"
|
||||||
|
|
||||||
EMessageBoxReturn DoLightIntensityDlg( int *intensity );
|
EMessageBoxReturn DoLightIntensityDlg( int *intensity );
|
||||||
EMessageBoxReturn DoShaderTagDlg( CopiedString *tag, const char* title );
|
EMessageBoxReturn DoShaderTagDlg( CopiedString& tag, const char* title );
|
||||||
EMessageBoxReturn DoShaderInfoDlg( const char* name, const char* filename, const char* title );
|
EMessageBoxReturn DoShaderInfoDlg( const char* name, const char* filename, const char* title );
|
||||||
EMessageBoxReturn DoTextureLayout( float *fx, float *fy );
|
EMessageBoxReturn DoTextureLayout( float *fx, float *fy );
|
||||||
void DoShaderView( const char *shaderFileName, const char *shaderName, bool external_editor );
|
void DoShaderView( const char *shaderFileName, const char *shaderName, bool external_editor );
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "patch.h"
|
#include "patch.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <forward_list>
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
#include "brush_primit.h"
|
#include "brush_primit.h"
|
||||||
#include "signal/signal.h"
|
#include "signal/signal.h"
|
||||||
|
|
@ -77,10 +77,10 @@ std::size_t BezierCurveTree_Setup( BezierCurveTree *pCurve, std::size_t index, s
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BezierCurve_IsCurved( BezierCurve *pCurve ){
|
bool BezierCurve_IsCurved( const BezierCurve& curve ){
|
||||||
Vector3 vTemp( vector3_subtracted( pCurve->right, pCurve->left ) );
|
Vector3 vTemp( vector3_subtracted( curve.right, curve.left ) );
|
||||||
Vector3 v1( vector3_subtracted( pCurve->crd, pCurve->left ) );
|
Vector3 v1( vector3_subtracted( curve.crd, curve.left ) );
|
||||||
Vector3 v2( vector3_subtracted( pCurve->right, pCurve->crd ) );
|
Vector3 v2( vector3_subtracted( curve.right, curve.crd ) );
|
||||||
|
|
||||||
if ( vector3_equal( v1, g_vector3_identity ) || vector3_equal( vTemp, v1 ) ) { // return 0 if 1->2 == 0 or 1->2 == 1->3
|
if ( vector3_equal( v1, g_vector3_identity ) || vector3_equal( vTemp, v1 ) ) { // return 0 if 1->2 == 0 or 1->2 == 1->3
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -110,58 +110,40 @@ bool BezierCurve_IsCurved( BezierCurve *pCurve ){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BezierInterpolate( BezierCurve *pCurve ){
|
void BezierInterpolate( BezierCurve& curve ){
|
||||||
pCurve->left = vector3_mid( pCurve->left, pCurve->crd );
|
curve.left = vector3_mid( curve.left, curve.crd );
|
||||||
pCurve->right = vector3_mid( pCurve->crd, pCurve->right );
|
curve.right = vector3_mid( curve.crd, curve.right );
|
||||||
pCurve->crd = vector3_mid( pCurve->left, pCurve->right );
|
curve.crd = vector3_mid( curve.left, curve.right );
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::size_t PATCH_MAX_SUBDIVISION_DEPTH = 16;
|
const std::size_t PATCH_MAX_SUBDIVISION_DEPTH = 16;
|
||||||
|
|
||||||
void BezierCurveTree_FromCurveList( BezierCurveTree *pTree, GSList *pCurveList, std::size_t depth = 0 ){
|
void BezierCurveTree_FromCurveList( BezierCurveTree *pTree, std::forward_list<BezierCurve>& curveList, std::size_t depth = 0 ){
|
||||||
GSList *pLeftList = 0;
|
std::forward_list<BezierCurve> leftList;
|
||||||
GSList *pRightList = 0;
|
std::forward_list<BezierCurve> rightList;
|
||||||
BezierCurve *pCurve, *pLeftCurve, *pRightCurve;
|
|
||||||
bool bSplit = false;
|
bool bSplit = false;
|
||||||
|
|
||||||
for ( GSList *l = pCurveList; l; l = l->next )
|
for ( BezierCurve& curve : curveList )
|
||||||
{
|
{
|
||||||
pCurve = (BezierCurve *)( l->data );
|
if ( bSplit || BezierCurve_IsCurved( curve ) ) {
|
||||||
if ( bSplit || BezierCurve_IsCurved( pCurve ) ) {
|
|
||||||
bSplit = true;
|
bSplit = true;
|
||||||
pLeftCurve = new BezierCurve;
|
BezierCurve& leftCurve = leftList.emplace_front();
|
||||||
pRightCurve = new BezierCurve;
|
BezierCurve& rightCurve = rightList.emplace_front();
|
||||||
pLeftCurve->left = pCurve->left;
|
leftCurve.left = curve.left;
|
||||||
pRightCurve->right = pCurve->right;
|
rightCurve.right = curve.right;
|
||||||
BezierInterpolate( pCurve );
|
BezierInterpolate( curve );
|
||||||
pLeftCurve->crd = pCurve->left;
|
leftCurve.crd = curve.left;
|
||||||
pRightCurve->crd = pCurve->right;
|
rightCurve.crd = curve.right;
|
||||||
pLeftCurve->right = pCurve->crd;
|
leftCurve.right = curve.crd;
|
||||||
pRightCurve->left = pCurve->crd;
|
rightCurve.left = curve.crd;
|
||||||
|
|
||||||
pLeftList = g_slist_prepend( pLeftList, pLeftCurve );
|
|
||||||
pRightList = g_slist_prepend( pRightList, pRightCurve );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pLeftList != 0 && pRightList != 0 && depth != PATCH_MAX_SUBDIVISION_DEPTH ) {
|
if ( !leftList.empty() && !rightList.empty() && depth != PATCH_MAX_SUBDIVISION_DEPTH ) {
|
||||||
pTree->left = new BezierCurveTree;
|
pTree->left = new BezierCurveTree;
|
||||||
pTree->right = new BezierCurveTree;
|
pTree->right = new BezierCurveTree;
|
||||||
BezierCurveTree_FromCurveList( pTree->left, pLeftList, depth + 1 );
|
BezierCurveTree_FromCurveList( pTree->left, leftList, depth + 1 );
|
||||||
BezierCurveTree_FromCurveList( pTree->right, pRightList, depth + 1 );
|
BezierCurveTree_FromCurveList( pTree->right, rightList, depth + 1 );
|
||||||
|
|
||||||
for ( GSList* l = pLeftList; l != 0; l = g_slist_next( l ) )
|
|
||||||
{
|
|
||||||
delete (BezierCurve*)l->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( GSList* l = pRightList; l != 0; l = g_slist_next( l ) )
|
|
||||||
{
|
|
||||||
delete (BezierCurve*)l->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_slist_free( pLeftList );
|
|
||||||
g_slist_free( pRightList );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -2314,7 +2296,7 @@ void Patch::BuildTesselationCurves( EMatrixMajor major ){
|
||||||
for ( std::size_t i = 0; i != length; ++i )
|
for ( std::size_t i = 0; i != length; ++i )
|
||||||
{
|
{
|
||||||
PatchControl* p1 = m_ctrlTransformed.data() + ( i * 2 * strideU );
|
PatchControl* p1 = m_ctrlTransformed.data() + ( i * 2 * strideU );
|
||||||
GSList* pCurveList = 0;
|
std::forward_list<BezierCurve> curveList;
|
||||||
for ( std::size_t j = 0; j < cross; j += 2 )
|
for ( std::size_t j = 0; j < cross; j += 2 )
|
||||||
{
|
{
|
||||||
PatchControl* p2 = p1 + strideV;
|
PatchControl* p2 = p1 + strideV;
|
||||||
|
|
@ -2322,11 +2304,10 @@ void Patch::BuildTesselationCurves( EMatrixMajor major ){
|
||||||
|
|
||||||
// directly taken from one row of control points
|
// directly taken from one row of control points
|
||||||
{
|
{
|
||||||
BezierCurve* pCurve = new BezierCurve;
|
BezierCurve& curve = curveList.emplace_front();
|
||||||
pCurve->crd = ( p1 + strideU )->m_vertex;
|
curve.crd = ( p1 + strideU )->m_vertex;
|
||||||
pCurve->left = p1->m_vertex;
|
curve.left = p1->m_vertex;
|
||||||
pCurve->right = ( p1 + ( strideU << 1 ) )->m_vertex;
|
curve.right = ( p1 + ( strideU << 1 ) )->m_vertex;
|
||||||
pCurveList = g_slist_prepend( pCurveList, pCurve );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( j + 2 >= cross ) {
|
if ( j + 2 >= cross ) {
|
||||||
|
|
@ -2335,27 +2316,21 @@ void Patch::BuildTesselationCurves( EMatrixMajor major ){
|
||||||
|
|
||||||
// interpolated from three columns of control points
|
// interpolated from three columns of control points
|
||||||
{
|
{
|
||||||
BezierCurve* pCurve = new BezierCurve;
|
BezierCurve& curve = curveList.emplace_front();
|
||||||
pCurve->crd = vector3_mid( ( p1 + strideU )->m_vertex, ( p3 + strideU )->m_vertex );
|
curve.crd = vector3_mid( ( p1 + strideU )->m_vertex, ( p3 + strideU )->m_vertex );
|
||||||
pCurve->left = vector3_mid( p1->m_vertex, p3->m_vertex );
|
curve.left = vector3_mid( p1->m_vertex, p3->m_vertex );
|
||||||
pCurve->right = vector3_mid( ( p1 + ( strideU << 1 ) )->m_vertex, ( p3 + ( strideU << 1 ) )->m_vertex );
|
curve.right = vector3_mid( ( p1 + ( strideU << 1 ) )->m_vertex, ( p3 + ( strideU << 1 ) )->m_vertex );
|
||||||
|
|
||||||
pCurve->crd = vector3_mid( pCurve->crd, ( p2 + strideU )->m_vertex );
|
curve.crd = vector3_mid( curve.crd, ( p2 + strideU )->m_vertex );
|
||||||
pCurve->left = vector3_mid( pCurve->left, p2->m_vertex );
|
curve.left = vector3_mid( curve.left, p2->m_vertex );
|
||||||
pCurve->right = vector3_mid( pCurve->right, ( p2 + ( strideU << 1 ) )->m_vertex );
|
curve.right = vector3_mid( curve.right, ( p2 + ( strideU << 1 ) )->m_vertex );
|
||||||
pCurveList = g_slist_prepend( pCurveList, pCurve );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p1 = p3;
|
p1 = p3;
|
||||||
}
|
}
|
||||||
|
|
||||||
pCurveTree[i] = new BezierCurveTree;
|
pCurveTree[i] = new BezierCurveTree;
|
||||||
BezierCurveTree_FromCurveList( pCurveTree[i], pCurveList );
|
BezierCurveTree_FromCurveList( pCurveTree[i], curveList );
|
||||||
for ( GSList* l = pCurveList; l != 0; l = g_slist_next( l ) )
|
|
||||||
{
|
|
||||||
delete static_cast<BezierCurve*>( ( *l ).data );
|
|
||||||
}
|
|
||||||
g_slist_free( pCurveList );
|
|
||||||
|
|
||||||
// set up array indices for binary tree
|
// set up array indices for binary tree
|
||||||
// accumulate subarray width
|
// accumulate subarray width
|
||||||
|
|
|
||||||
|
|
@ -1738,40 +1738,38 @@ GtkMenuItem* TextureBrowser_constructTagsMenu( GtkMenu* menu ){
|
||||||
return textures_menu_item;
|
return textures_menu_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean TextureBrowser_tagMoveHelper( GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, GSList** selected ){
|
gboolean TextureBrowser_tagMoveHelper( GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, std::vector<GtkTreeRowReference*>* selected ){
|
||||||
g_assert( selected != NULL );
|
g_assert( selected != NULL );
|
||||||
|
|
||||||
GtkTreeRowReference* rowref = gtk_tree_row_reference_new( model, path );
|
GtkTreeRowReference* rowref = gtk_tree_row_reference_new( model, path );
|
||||||
*selected = g_slist_append( *selected, rowref );
|
selected->push_back( rowref );
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureBrowser_assignTags(){
|
void TextureBrowser_assignTags(){
|
||||||
GSList* selected = NULL;
|
std::vector<GtkTreeRowReference*> selected;
|
||||||
GSList* node;
|
|
||||||
gchar* tag_assigned;
|
|
||||||
|
|
||||||
GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_available_tree ) );
|
GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_available_tree ) );
|
||||||
|
|
||||||
gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected );
|
gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected );
|
||||||
|
|
||||||
if ( selected != NULL ) {
|
if ( !selected.empty() ) {
|
||||||
for ( node = selected; node != NULL; node = node->next )
|
for ( GtkTreeRowReference* ref : selected )
|
||||||
{
|
{
|
||||||
GtkTreePath* path = gtk_tree_row_reference_get_path( (GtkTreeRowReference*)node->data );
|
GtkTreePath* path = gtk_tree_row_reference_get_path( ref );
|
||||||
|
|
||||||
if ( path ) {
|
if ( path ) {
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
|
|
||||||
if ( gtk_tree_model_get_iter( GTK_TREE_MODEL( g_TextureBrowser.m_available_store ), &iter, path ) ) {
|
if ( gtk_tree_model_get_iter( GTK_TREE_MODEL( g_TextureBrowser.m_available_store ), &iter, path ) ) {
|
||||||
|
gchar* tag_assigned;
|
||||||
gtk_tree_model_get( GTK_TREE_MODEL( g_TextureBrowser.m_available_store ), &iter, TAG_COLUMN, &tag_assigned, -1 );
|
gtk_tree_model_get( GTK_TREE_MODEL( g_TextureBrowser.m_available_store ), &iter, TAG_COLUMN, &tag_assigned, -1 );
|
||||||
if ( !TagBuilder.CheckShaderTag( g_TextureBrowser.shader.c_str() ) ) {
|
if ( !TagBuilder.CheckShaderTag( g_TextureBrowser.shader.c_str() ) ) {
|
||||||
// create a custom shader/texture entry
|
// create a custom shader/texture entry
|
||||||
IShader* ishader = QERApp_Shader_ForName( g_TextureBrowser.shader.c_str() );
|
IShader* ishader = QERApp_Shader_ForName( g_TextureBrowser.shader.c_str() );
|
||||||
CopiedString filename = ishader->getShaderFileName();
|
|
||||||
|
|
||||||
if ( filename.empty() ) {
|
if ( ishader->IsDefault() ) {
|
||||||
// it's a texture
|
// it's a texture
|
||||||
TagBuilder.AddShaderNode( g_TextureBrowser.shader.c_str(), CUSTOM, TEXTURE );
|
TagBuilder.AddShaderNode( g_TextureBrowser.shader.c_str(), CUSTOM, TEXTURE );
|
||||||
}
|
}
|
||||||
|
|
@ -1792,26 +1790,24 @@ void TextureBrowser_assignTags(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_slist_foreach( selected, (GFunc)gtk_tree_row_reference_free, NULL );
|
std::for_each( selected.begin(), selected.end(), gtk_tree_row_reference_free );
|
||||||
|
|
||||||
// Save changes
|
// Save changes
|
||||||
TagBuilder.SaveXmlDoc();
|
TagBuilder.SaveXmlDoc();
|
||||||
}
|
}
|
||||||
g_slist_free( selected );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureBrowser_removeTags(){
|
void TextureBrowser_removeTags(){
|
||||||
GSList* selected = NULL;
|
std::vector<GtkTreeRowReference*> selected;
|
||||||
GSList* node;
|
|
||||||
|
|
||||||
GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_assigned_tree ) );
|
GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_assigned_tree ) );
|
||||||
|
|
||||||
gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected );
|
gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected );
|
||||||
|
|
||||||
if ( selected != NULL ) {
|
if ( !selected.empty() ) {
|
||||||
for ( node = selected; node != NULL; node = node->next )
|
for ( GtkTreeRowReference* ref : selected )
|
||||||
{
|
{
|
||||||
GtkTreePath* path = gtk_tree_row_reference_get_path( (GtkTreeRowReference*)node->data );
|
GtkTreePath* path = gtk_tree_row_reference_get_path( ref );
|
||||||
|
|
||||||
if ( path ) {
|
if ( path ) {
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
|
|
@ -1826,7 +1822,7 @@ void TextureBrowser_removeTags(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_slist_foreach( selected, (GFunc)gtk_tree_row_reference_free, NULL );
|
std::for_each( selected.begin(), selected.end(), gtk_tree_row_reference_free );
|
||||||
|
|
||||||
// Update the "available tags list"
|
// Update the "available tags list"
|
||||||
BuildStoreAvailableTags( g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, g_TextureBrowser.m_all_tags, &g_TextureBrowser );
|
BuildStoreAvailableTags( g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, g_TextureBrowser.m_all_tags, &g_TextureBrowser );
|
||||||
|
|
@ -1834,7 +1830,6 @@ void TextureBrowser_removeTags(){
|
||||||
// Save changes
|
// Save changes
|
||||||
TagBuilder.SaveXmlDoc();
|
TagBuilder.SaveXmlDoc();
|
||||||
}
|
}
|
||||||
g_slist_free( selected );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureBrowser_buildTagList(){
|
void TextureBrowser_buildTagList(){
|
||||||
|
|
@ -1851,8 +1846,7 @@ void TextureBrowser_buildTagList(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureBrowser_searchTags(){
|
void TextureBrowser_searchTags(){
|
||||||
GSList* selected = NULL;
|
std::vector<GtkTreeRowReference*> selected;
|
||||||
GSList* node;
|
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
char tags_searched[256];
|
char tags_searched[256];
|
||||||
|
|
||||||
|
|
@ -1860,13 +1854,13 @@ void TextureBrowser_searchTags(){
|
||||||
|
|
||||||
gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected );
|
gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected );
|
||||||
|
|
||||||
if ( selected != NULL ) {
|
if ( !selected.empty() ) {
|
||||||
strcpy( buffer, "/root/*/*[tag='" );
|
strcpy( buffer, "/root/*/*[tag='" );
|
||||||
strcpy( tags_searched, "[TAGS] " );
|
strcpy( tags_searched, "[TAGS] " );
|
||||||
|
|
||||||
for ( node = selected; node != NULL; node = node->next )
|
for ( auto it = selected.begin(); it != selected.end(); ++it )
|
||||||
{
|
{
|
||||||
GtkTreePath* path = gtk_tree_row_reference_get_path( (GtkTreeRowReference*)node->data );
|
GtkTreePath* path = gtk_tree_row_reference_get_path( *it );
|
||||||
|
|
||||||
if ( path ) {
|
if ( path ) {
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
|
|
@ -1878,7 +1872,7 @@ void TextureBrowser_searchTags(){
|
||||||
strcat( buffer, tag );
|
strcat( buffer, tag );
|
||||||
strcat( tags_searched, tag );
|
strcat( tags_searched, tag );
|
||||||
g_free( tag );
|
g_free( tag );
|
||||||
if ( node != g_slist_last( node ) ) {
|
if ( it + 1 != selected.end() ) {
|
||||||
strcat( buffer, "' and tag='" );
|
strcat( buffer, "' and tag='" );
|
||||||
strcat( tags_searched, ", " );
|
strcat( tags_searched, ", " );
|
||||||
}
|
}
|
||||||
|
|
@ -1888,7 +1882,7 @@ void TextureBrowser_searchTags(){
|
||||||
|
|
||||||
strcat( buffer, "']" );
|
strcat( buffer, "']" );
|
||||||
|
|
||||||
g_slist_foreach( selected, (GFunc)gtk_tree_row_reference_free, NULL );
|
std::for_each( selected.begin(), selected.end(), gtk_tree_row_reference_free );
|
||||||
|
|
||||||
g_TextureBrowser.m_found_shaders.clear(); // delete old list
|
g_TextureBrowser.m_found_shaders.clear(); // delete old list
|
||||||
TagBuilder.TagSearch( buffer, g_TextureBrowser.m_found_shaders );
|
TagBuilder.TagSearch( buffer, g_TextureBrowser.m_found_shaders );
|
||||||
|
|
@ -1919,7 +1913,6 @@ void TextureBrowser_searchTags(){
|
||||||
TextureBrowser_heightChanged( g_TextureBrowser );
|
TextureBrowser_heightChanged( g_TextureBrowser );
|
||||||
TextureBrowser_updateTitle();
|
TextureBrowser_updateTitle();
|
||||||
}
|
}
|
||||||
g_slist_free( selected );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureBrowser_toggleSearchButton(){
|
void TextureBrowser_toggleSearchButton(){
|
||||||
|
|
@ -2319,12 +2312,12 @@ void TextureBrowser_setBackgroundColour( TextureBrowser& textureBrowser, const V
|
||||||
TextureBrowser_queueDraw( textureBrowser );
|
TextureBrowser_queueDraw( textureBrowser );
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureBrowser_selectionHelper( GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, GSList** selected ){
|
void TextureBrowser_selectionHelper( GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, std::vector<gchar*>* selected ){
|
||||||
g_assert( selected != NULL );
|
g_assert( selected != NULL );
|
||||||
|
|
||||||
gchar* name;
|
gchar* name;
|
||||||
gtk_tree_model_get( model, iter, TAG_COLUMN, &name, -1 );
|
gtk_tree_model_get( model, iter, TAG_COLUMN, &name, -1 );
|
||||||
*selected = g_slist_append( *selected, name );
|
selected->push_back( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureBrowser_shaderInfo(){
|
void TextureBrowser_shaderInfo(){
|
||||||
|
|
@ -2339,7 +2332,7 @@ void TextureBrowser_shaderInfo(){
|
||||||
void TextureBrowser_addTag(){
|
void TextureBrowser_addTag(){
|
||||||
CopiedString tag;
|
CopiedString tag;
|
||||||
|
|
||||||
EMessageBoxReturn result = DoShaderTagDlg( &tag, "Add shader tag" );
|
EMessageBoxReturn result = DoShaderTagDlg( tag, "Add shader tag" );
|
||||||
|
|
||||||
if ( result == eIDOK && !tag.empty() ) {
|
if ( result == eIDOK && !tag.empty() ) {
|
||||||
GtkTreeIter iter, iter2;
|
GtkTreeIter iter, iter2;
|
||||||
|
|
@ -2364,18 +2357,18 @@ void TextureBrowser_renameTag(){
|
||||||
rows (which always contains a single row).
|
rows (which always contains a single row).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GSList* selected = NULL;
|
std::vector<gchar*> selected;
|
||||||
|
|
||||||
GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_treeViewTags ) );
|
GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_treeViewTags ) );
|
||||||
gtk_tree_selection_selected_foreach( selection, GtkTreeSelectionForeachFunc( TextureBrowser_selectionHelper ), &selected );
|
gtk_tree_selection_selected_foreach( selection, GtkTreeSelectionForeachFunc( TextureBrowser_selectionHelper ), &selected );
|
||||||
|
|
||||||
if ( g_slist_length( selected ) == 1 ) { // we only rename a single tag
|
if ( selected.size() == 1 ) { // we only rename a single tag
|
||||||
CopiedString newTag;
|
CopiedString newTag;
|
||||||
EMessageBoxReturn result = DoShaderTagDlg( &newTag, "Rename shader tag" );
|
EMessageBoxReturn result = DoShaderTagDlg( newTag, "Rename shader tag" );
|
||||||
|
|
||||||
if ( result == eIDOK && !newTag.empty() ) {
|
if ( result == eIDOK && !newTag.empty() ) {
|
||||||
GtkTreeIter iterList;
|
GtkTreeIter iterList;
|
||||||
gchar* oldTag = (char*)selected->data;
|
gchar* oldTag = selected.front();
|
||||||
|
|
||||||
bool row = gtk_tree_model_get_iter_first( GTK_TREE_MODEL( g_TextureBrowser.m_all_tags_list ), &iterList ) != 0;
|
bool row = gtk_tree_model_get_iter_first( GTK_TREE_MODEL( g_TextureBrowser.m_all_tags_list ), &iterList ) != 0;
|
||||||
|
|
||||||
|
|
@ -2405,22 +2398,22 @@ void TextureBrowser_renameTag(){
|
||||||
gtk_MessageBox( GTK_WIDGET( g_TextureBrowser.m_parent ), "Select a single tag for renaming." );
|
gtk_MessageBox( GTK_WIDGET( g_TextureBrowser.m_parent ), "Select a single tag for renaming." );
|
||||||
}
|
}
|
||||||
|
|
||||||
g_slist_free_full( selected, g_free );
|
std::for_each( selected.begin(), selected.end(), g_free );
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureBrowser_deleteTag(){
|
void TextureBrowser_deleteTag(){
|
||||||
GSList* selected = NULL;
|
std::vector<gchar*> selected;
|
||||||
|
|
||||||
GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_treeViewTags ) );
|
GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( g_TextureBrowser.m_treeViewTags ) );
|
||||||
gtk_tree_selection_selected_foreach( selection, GtkTreeSelectionForeachFunc( TextureBrowser_selectionHelper ), &selected );
|
gtk_tree_selection_selected_foreach( selection, GtkTreeSelectionForeachFunc( TextureBrowser_selectionHelper ), &selected );
|
||||||
|
|
||||||
if ( g_slist_length( selected ) == 1 ) { // we only delete a single tag
|
if ( selected.size() == 1 ) { // we only delete a single tag
|
||||||
EMessageBoxReturn result = gtk_MessageBox( GTK_WIDGET( g_TextureBrowser.m_parent ), "Are you sure you want to delete the selected tag?", "Delete Tag", eMB_YESNO, eMB_ICONQUESTION );
|
EMessageBoxReturn result = gtk_MessageBox( GTK_WIDGET( g_TextureBrowser.m_parent ), "Are you sure you want to delete the selected tag?", "Delete Tag", eMB_YESNO, eMB_ICONQUESTION );
|
||||||
|
|
||||||
if ( result == eIDYES ) {
|
if ( result == eIDYES ) {
|
||||||
GtkTreeIter iterSelected;
|
GtkTreeIter iterSelected;
|
||||||
|
|
||||||
gchar* tagSelected = (char*)selected->data;
|
gchar* tagSelected = selected.front();
|
||||||
|
|
||||||
bool row = gtk_tree_model_get_iter_first( GTK_TREE_MODEL( g_TextureBrowser.m_all_tags_list ), &iterSelected ) != 0;
|
bool row = gtk_tree_model_get_iter_first( GTK_TREE_MODEL( g_TextureBrowser.m_all_tags_list ), &iterSelected ) != 0;
|
||||||
|
|
||||||
|
|
@ -2449,7 +2442,7 @@ void TextureBrowser_deleteTag(){
|
||||||
gtk_MessageBox( GTK_WIDGET( g_TextureBrowser.m_parent ), "Select a single tag for deletion." );
|
gtk_MessageBox( GTK_WIDGET( g_TextureBrowser.m_parent ), "Select a single tag for deletion." );
|
||||||
}
|
}
|
||||||
|
|
||||||
g_slist_free_full( selected, g_free );
|
std::for_each( selected.begin(), selected.end(), g_free );
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureBrowser_copyTag(){
|
void TextureBrowser_copyTag(){
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user