]> git.xonotic.org Git - xonotic/netradiant.git/commitdiff
Radiant:
authorGarux <garux@mail.ru>
Tue, 1 Aug 2017 11:27:03 +0000 (14:27 +0300)
committerGarux <garux@mail.ru>
Tue, 1 Aug 2017 11:27:03 +0000 (14:27 +0300)
misc...
* fix: select inside and touching: ignored ANY filters and hiding, and region
* fix: M3 tex paint/grab ignored _hidden_ models
* fix: M3 tex paint/grab ignored group ent (world, triggers, et cetera), model filters
* fix: shift+a by tex: ignored group ent (world, triggers, et cetera) filters
* fix: tex find/replace: ignored any filters, regioning & hiding
* fix: shift+a by classname: ignored filters, hiding, region
* fix: floor walker ignored group ent filters
* fix: csg subtract ignored group ent filters
* fix: invert selection: ignored group ent filters
* fix: tex find/replace: 'select by shader' mode for patches (was replacing with notex instead)
* fix: select inside and touching: were selecting group ents, as single unit (=sensitive to parent node and its bbox)
* fix: csg merge two group ents = empty group ent
* fix: csg subtract group ent completely = empty group ent
* fix: hollow group ent: could produce empty group ent
* func_groups are filtered by world filter only, not entities one
* new func_group filter, filterBar button; Rightclick = create func_group

14 files changed:
include/ifilter.h
libs/scenelib.h
plugins/entity/entity.cpp
radiant/brushmanip.cpp
radiant/camwindow.cpp
radiant/csg.cpp
radiant/filterbar.cpp
radiant/filters.cpp
radiant/mainframe.cpp
radiant/patch.h
radiant/patchmanip.cpp
radiant/select.cpp
radiant/surfacedialog.cpp
setup/data/tools/bitmaps/f-funcgroups.png [new file with mode: 0644]

index 7efbb8a9c878eee60bf753db0753ed1ef9d2de87..f75a217a4de23a13ce1fccbdb03608fd53442c03 100644 (file)
@@ -47,6 +47,7 @@ enum
        EXCLUDE_BOTCLIP          = 0x00040000,
        EXCLUDE_VISPORTALS       = 0x00080000,
        EXCLUDE_DECALS           = 0x00100000,
+       EXCLUDE_FUNC_GROUPS       = 0x00200000,
 };
 
 class Filter
index 29402065252cf7c8f2cb4d040d244e48d2e67427..08566259a4b9c0621dabec060b12b0daf4855071 100644 (file)
@@ -762,7 +762,14 @@ public:
 InstanceWalker( const Functor& functor ) : m_functor( functor ){
 }
 bool pre( const scene::Path& path, scene::Instance& instance ) const {
-       m_functor( instance );
+       //m_functor( instance );
+       //return true;
+       if ( path.top().get().visible() ) {
+               m_functor( instance );
+       }
+       else{
+               return false;
+       }
        return true;
 }
 };
index db0e16b47f316d75871296b88626109c9a2492a4..c862459e94ac43d9dec87c59cd3eece5e496f2dc 100644 (file)
@@ -307,7 +307,7 @@ bool filter( const Entity& entity ) const {
 }
 };
 
-filter_entity_classname g_filter_entity_world( "worldspawn" );
+//filter_entity_classname g_filter_entity_world( "worldspawn" );
 filter_entity_classname g_filter_entity_func_group( "func_group" );
 filter_entity_classname g_filter_entity_light( "light" );
 filter_entity_classname g_filter_entity_misc_model( "misc_model" );
@@ -327,9 +327,20 @@ bool filter( const Entity& entity ) const {
 filter_entity_doom3model g_filter_entity_doom3model;
 
 
+class filter_entity_world : public EntityFilter
+{
+public:
+bool filter( const Entity& entity ) const {
+       return string_equal( entity.getKeyValue( "classname" ), "worldspawn" )
+                  || string_equal( entity.getKeyValue( "classname" ), "func_group" );
+}
+};
+
+filter_entity_world g_filter_entity_world;
+
 void Entity_InitFilters(){
        add_entity_filter( g_filter_entity_world, EXCLUDE_WORLD );
-       add_entity_filter( g_filter_entity_func_group, EXCLUDE_WORLD );
+       add_entity_filter( g_filter_entity_func_group, EXCLUDE_FUNC_GROUPS );
        add_entity_filter( g_filter_entity_world, EXCLUDE_ENT, true );
        add_entity_filter( g_filter_entity_trigger, EXCLUDE_TRIGGERS );
        add_entity_filter( g_filter_entity_misc_model, EXCLUDE_MODELS );
index 36ed6a9b13cf01dfc9ba3c1afaeeca0b3fa014c0..11db0ba99fdfb8838fb0a759376c48e4dd438462 100644 (file)
@@ -696,6 +696,9 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
                        Instance_getSelectable( instance )->setSelected( true );
                }
        }
+       else{
+               return false;
+       }
        return true;
 }
 };
index 462812959e0a256af15109c1893c7c2357687f23..134ab7d2063a3bb010ce2c7adcd799974325434d 100644 (file)
@@ -1249,6 +1249,9 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
                        m_bestDown = floorHeight;
                }
        }
+       else if( !path.top().get().visible() ){
+               return false;
+       }
        return true;
 }
 };
index 1b0d6004e622366d14852a53e312386afff429b3..1b824b6abedc8f5e0e1199fc841803bb9cd55271 100644 (file)
@@ -379,7 +379,7 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
        return true;
 }
 };
-
+/*
 class BrushDeleteSelected : public scene::Graph::Walker
 {
 public:
@@ -397,7 +397,47 @@ void post( const scene::Path& path, scene::Instance& instance ) const {
        }
 }
 };
+*/
+#include "ientity.h"
 
+class BrushDeleteSelected : public scene::Graph::Walker
+{
+scene::Node* m_keepNode;
+mutable bool m_eraseParent;
+public:
+BrushDeleteSelected( scene::Node* keepNode ): m_keepNode( keepNode ), m_eraseParent( false ){
+}
+BrushDeleteSelected(): m_keepNode( NULL ), m_eraseParent( false ){
+}
+bool pre( const scene::Path& path, scene::Instance& instance ) const {
+       return true;
+}
+void post( const scene::Path& path, scene::Instance& instance ) const {
+       //globalOutputStream() << path.size() << "\n";
+       if ( path.top().get().visible() ) {
+               Brush* brush = Node_getBrush( path.top() );
+               if ( brush != 0
+                        && Instance_getSelectable( instance )->isSelected()
+                        && path.size() > 1 ) {
+                       Path_deleteTop( path );
+                       if( Node_getTraversable( path.parent() )->empty() ){
+                               m_eraseParent = true;
+                               //globalOutputStream() << "Empty node?!.\n";
+                       }
+               }
+       }
+       if( m_eraseParent && !Node_isPrimitive( path.top() ) && path.size() > 1 ){
+               //globalOutputStream() << "about to Delete empty node!.\n";
+               m_eraseParent = false;
+               Entity* entity = Node_getEntity( path.top() );
+               if ( entity != 0 && path.top().get_pointer() != Map_FindWorldspawn( g_map )
+                       && Node_getTraversable( path.top() )->empty() && path.top().get_pointer() != m_keepNode ) {
+                       //globalOutputStream() << "now Deleting empty node!.\n";
+                       Path_deleteTop( path );
+               }
+       }
+}
+};
 
 /*
    =============
@@ -568,12 +608,16 @@ class SubtractBrushesFromUnselected : public scene::Graph::Walker
 const brush_vector_t& m_brushlist;
 std::size_t& m_before;
 std::size_t& m_after;
+mutable bool m_eraseParent;
 public:
 SubtractBrushesFromUnselected( const brush_vector_t& brushlist, std::size_t& before, std::size_t& after )
-       : m_brushlist( brushlist ), m_before( before ), m_after( after ){
+       : m_brushlist( brushlist ), m_before( before ), m_after( after ), m_eraseParent( false ){
 }
 bool pre( const scene::Path& path, scene::Instance& instance ) const {
-       return true;
+       if ( path.top().get().visible() ) {
+               return true;
+       }
+       return false;
 }
 void post( const scene::Path& path, scene::Instance& instance ) const {
        if ( path.top().get().visible() ) {
@@ -626,9 +670,20 @@ void post( const scene::Path& path, scene::Instance& instance ) const {
                                        }
                                }
                                Path_deleteTop( path );
+                               if( Node_getTraversable( path.parent() )->empty() ){
+                                       m_eraseParent = true;
+                               }
                        }
                }
        }
+       if( m_eraseParent && !Node_isPrimitive( path.top() ) && path.size() > 1 ){
+               m_eraseParent = false;
+               Entity* entity = Node_getEntity( path.top() );
+               if ( entity != 0 && path.top().get_pointer() != Map_FindWorldspawn( g_map )
+                       && Node_getTraversable( path.top() )->empty() ) {
+                       Path_deleteTop( path );
+               }
+       }
 }
 };
 
@@ -868,7 +923,7 @@ void CSG_Merge( void ){
                ASSERT_MESSAGE( !brush->empty(), "brush left with no faces after merge" );
 
                // free the original brushes
-               GlobalSceneGraph().traverse( BrushDeleteSelected() );
+               GlobalSceneGraph().traverse( BrushDeleteSelected( merged_path.parent().get_pointer() ) );
 
                merged_path.pop();
                Node_getTraversable( merged_path.top() )->insert( node );
index 918f3d808b3ae12d9420333a71cf333fc14229bb..6317fa4711653411e5cba77c54f89e0c2a4db98e 100644 (file)
@@ -11,7 +11,7 @@
 #include "gtkutil/accelerator.h"
 #include "generic/callback.h"
 
-
+#include "entity.h"
 
 
 int ToggleActions = 0;
@@ -147,6 +147,16 @@ gboolean Trigger_button_press( GtkWidget *widget, GdkEventButton *event, gpointe
        return FALSE;
 }
 
+gboolean Func_Groups_button_press( GtkWidget *widget, GdkEventButton *event, gpointer data ){
+       if ( event->button == 3 && event->type == GDK_BUTTON_PRESS ) {
+               UndoableCommand undo( "create func_group" );
+               Entity_createFromSelection( "func_group", g_vector3_identity );
+               ToggleActions = 0;
+               return TRUE;
+       }
+       return FALSE;
+}
+
 gboolean Detail_button_press( GtkWidget *widget, GdkEventButton *event, gpointer data ){
        if ( event->button == 3 && event->type == GDK_BUTTON_PRESS ) {
                GlobalCommands_find( "MakeDetail" ).m_callback();
@@ -181,6 +191,8 @@ GtkToolbar* create_filter_toolbar(){
                        button = toolbar_append_toggle_button( filter_toolbar, "Details (CTRL + D)\nRightClick: MakeDetail", "f-details.png", "FilterDetails" );
                        g_signal_connect( G_OBJECT( button ), "button_press_event", G_CALLBACK( Detail_button_press ), 0 );
 
+                       button = toolbar_append_toggle_button( filter_toolbar, "Func_Groups\nRightClick: create func_group", "f-funcgroups.png", "FilterFuncGroups" );
+                       g_signal_connect( G_OBJECT( button ), "button_press_event", G_CALLBACK( Func_Groups_button_press ), 0 );
 
                        toolbar_append_toggle_button( filter_toolbar, "Patches (CTRL + P)", "patch_wireframe.png", "FilterPatches" );
                        gtk_toolbar_append_space( GTK_TOOLBAR( filter_toolbar ) );
@@ -216,6 +228,7 @@ GtkToolbar* create_filter_toolbar(){
                        //toolbar_append_toggle_button( filter_toolbar, "Decals (SHIFT + D)", "f-decals.png", "FilterDecals" );
                        gtk_toolbar_append_space( GTK_TOOLBAR( filter_toolbar ) );
                        toolbar_append_button( filter_toolbar, "InvertFilters", "f-invert.png", "InvertFilters" );
+
                        toolbar_append_button( filter_toolbar, "ResetFilters", "f-reset.png", "ResetFilters" );
                        return filter_toolbar;
 }
index 3ff4ddd0703c2290f65624d66ac96a9397ab7029..b232b791abc44a2d69cd94c11aa105ce06abc50c 100644 (file)
@@ -205,6 +205,7 @@ void Filters_constructMenu( GtkMenu* menu_in_menu ){
                create_check_menu_item_with_mnemonic( menu_in_menu, "Botclips", "FilterBotClips" );
                create_check_menu_item_with_mnemonic( menu_in_menu, "Decals", "FilterDecals" );
        }
+       create_check_menu_item_with_mnemonic( menu_in_menu, "FuncGroups", "FilterFuncGroups" );
        // filter manipulation
        menu_separator( menu_in_menu );
        create_menu_item_with_mnemonic( menu_in_menu, "Invert filters", "InvertFilters" );
@@ -252,6 +253,7 @@ void ConstructFilters(){
                add_filter_command( EXCLUDE_BOTCLIP, "FilterBotClips", Accelerator( 'M', (GdkModifierType)GDK_MOD1_MASK ) );
                add_filter_command( EXCLUDE_DECALS, "FilterDecals", Accelerator( 'D', (GdkModifierType)GDK_SHIFT_MASK ) );
        }
+       add_filter_command( EXCLUDE_FUNC_GROUPS, "FilterFuncGroups", accelerator_null() );
 
        PerformFiltering();
 }
index 4c9fc6b32a9e2425279b8fcf88d5c8e13e4929bd..4c8ddd7c2ce911fccf953ad9223addb8f9ab7814 100644 (file)
@@ -2778,6 +2778,7 @@ void MainFrame::Create(){
        GtkWidget* vbox = gtk_vbox_new( FALSE, 0 );
        gtk_container_add( GTK_CONTAINER( window ), vbox );
        gtk_widget_show( vbox );
+       gtk_container_set_focus_chain( GTK_CONTAINER( vbox ), NULL );
 
        global_accel_connect_window( window );
 
index 7cca42862722f75e94aa07e2f28c307500637bb4..b1a897be5a3eb9e191c8e43c9714a278668ee5ba 100644 (file)
@@ -1810,6 +1810,9 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
                        m_functor( *patch );
                }
        }
+       else{
+               return false;
+       }
        return true;
 }
 };
@@ -1834,6 +1837,9 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
                        m_functor( *patch );
                }
        }
+       else{
+               return false;
+       }
        return true;
 }
 };
@@ -1857,6 +1863,9 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
                        m_functor( *patch );
                }
        }
+       else{
+               return false;
+       }
        return true;
 }
 };
index 4a7e72abed0c1b365f5958207e383f11f35a459b..b941e2ae5649919a7a1d56606489ed0f97d68efd 100644 (file)
@@ -453,12 +453,28 @@ void operator()( Patch& patch ) const {
 }
 };
 
+namespace{
+bool DoingSearch( const char *repl ){
+       return ( repl == NULL || ( strcmp( "textures/", repl ) == 0 ) );
+}
+}
 void Scene_PatchFindReplaceShader( scene::Graph& graph, const char* find, const char* replace ){
-       Scene_forEachVisiblePatch( PatchFindReplaceShader( find, replace ) );
+       if( DoingSearch( replace ) ){
+               Scene_forEachVisiblePatchInstance( PatchSelectByShader( find ) );
+       }
+       else{
+               Scene_forEachVisiblePatch( PatchFindReplaceShader( find, replace ) );
+       }
 }
 
 void Scene_PatchFindReplaceShader_Selected( scene::Graph& graph, const char* find, const char* replace ){
-       Scene_forEachVisibleSelectedPatch( PatchFindReplaceShader( find, replace ) );
+       if( DoingSearch( replace ) ){
+               //do nothing, because alternative is replacing to notex
+               //perhaps deselect ones with not matching shaders here?
+       }
+       else{
+               Scene_forEachVisibleSelectedPatch( PatchFindReplaceShader( find, replace ) );
+       }
 }
 
 
index 175af349eed067fd706e985384f6e41a2a798d0a..c42b4003d649d0fe2b285282984e1ce87ff65e81 100644 (file)
@@ -110,27 +110,33 @@ SelectByBounds( AABB* aabbs, Unsigned count )
 }
 
 bool pre( const scene::Path& path, scene::Instance& instance ) const {
-       Selectable* selectable = Instance_getSelectable( instance );
+       if( path.top().get().visible() ){
+               Selectable* selectable = Instance_getSelectable( instance );
 
-       // ignore worldspawn
-       Entity* entity = Node_getEntity( path.top() );
-       if ( entity ) {
-               if ( string_equal( entity->getKeyValue( "classname" ), "worldspawn" ) ) {
-                       return true;
+               // ignore worldspawn
+               Entity* entity = Node_getEntity( path.top() );
+               if ( entity ) {
+                       if ( string_equal( entity->getKeyValue( "classname" ), "worldspawn" ) ) {
+                               return true;
+                       }
                }
-       }
 
-       if ( ( path.size() > 1 ) &&
-                ( !path.top().get().isRoot() ) &&
-                ( selectable != 0 )
-                ) {
-               for ( Unsigned i = 0; i < m_count; ++i )
-               {
-                       if ( policy.Evaluate( m_aabbs[i], instance ) ) {
-                               selectable->setSelected( true );
+               if ( ( path.size() > 1 ) &&
+                       ( !path.top().get().isRoot() ) &&
+                       ( selectable != 0 ) &&
+                       ( !node_is_group( path.top() ) )
+                       ) {
+                       for ( Unsigned i = 0; i < m_count; ++i )
+                       {
+                               if ( policy.Evaluate( m_aabbs[i], instance ) ) {
+                                       selectable->setSelected( true );
+                               }
                        }
                }
        }
+       else{
+               return false;
+       }
 
        return true;
 }
@@ -275,6 +281,10 @@ InvertSelectionWalker( SelectionSystem::EMode mode )
        : m_mode( mode ), m_selectable( 0 ){
 }
 bool pre( const scene::Path& path, scene::Instance& instance ) const {
+       if( !path.top().get().visible() ){
+               m_selectable = 0;
+               return false;
+       }
        Selectable* selectable = Instance_getSelectable( instance );
        if ( selectable ) {
                switch ( m_mode )
@@ -608,6 +618,9 @@ EntityFindByPropertyValueWalker( const char *prop, const PropertyValues& propert
        : m_propertyvalues( propertyvalues ), m_prop( prop ){
 }
 bool pre( const scene::Path& path, scene::Instance& instance ) const {
+       if( !path.top().get().visible() ){
+               return false;
+       }
        Entity* entity = Node_getEntity( path.top() );
        if ( entity != 0
                 && propertyvalues_contain( m_propertyvalues, entity->getKeyValue( m_prop ) ) ) {
index d0ff4c1c719719da656c5b2312b3b608a53cc3d3..cc6c116b0df9b95f0b35abfb1bdaeb8cc9a97694 100644 (file)
@@ -1392,6 +1392,9 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
                        }
                }
        }
+       else{
+               return false;
+       }
        return true;
 }
 };
diff --git a/setup/data/tools/bitmaps/f-funcgroups.png b/setup/data/tools/bitmaps/f-funcgroups.png
new file mode 100644 (file)
index 0000000..aef9613
Binary files /dev/null and b/setup/data/tools/bitmaps/f-funcgroups.png differ