* entity inspector: select entities by key, value, key+value buttons
replaces and complements obscure behavior of SelectAllOfType with entity inspector shown
This commit is contained in:
parent
fdef42427d
commit
2944cff834
|
|
@ -1503,6 +1503,19 @@ void EntityInspector_focusSelected( GtkButton *button, gpointer user_data ){
|
|||
FocusAllViews();
|
||||
}
|
||||
|
||||
void EntityInspector_selectByKey( GtkButton *button, gpointer user_data ){
|
||||
Select_EntitiesByKeyValue( gtk_entry_get_text( g_entityKeyEntry ), nullptr );
|
||||
}
|
||||
|
||||
void EntityInspector_selectByValue( GtkButton *button, gpointer user_data ){
|
||||
Select_EntitiesByKeyValue( nullptr, gtk_entry_get_text( g_entityValueEntry ) );
|
||||
}
|
||||
|
||||
void EntityInspector_selectByKeyValue( GtkButton *button, gpointer user_data ){
|
||||
Select_EntitiesByKeyValue( gtk_entry_get_text( g_entityKeyEntry ), gtk_entry_get_text( g_entityValueEntry ) );
|
||||
}
|
||||
|
||||
|
||||
GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){
|
||||
GtkWidget* vbox = gtk_vbox_new( FALSE, 2 );
|
||||
gtk_widget_show( vbox );
|
||||
|
|
@ -1663,7 +1676,7 @@ GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){
|
|||
|
||||
{
|
||||
// key/value entry
|
||||
GtkTable* table = GTK_TABLE( gtk_table_new( 2, 2, FALSE ) );
|
||||
GtkTable* table = GTK_TABLE( gtk_table_new( 2, 3, FALSE ) );
|
||||
gtk_widget_show( GTK_WIDGET( table ) );
|
||||
gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( table ), FALSE, TRUE, 0 );
|
||||
gtk_table_set_row_spacings( table, 3 );
|
||||
|
|
@ -1708,6 +1721,49 @@ GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){
|
|||
(GtkAttachOptions)( 0 ), 0, 0 );
|
||||
gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
|
||||
}
|
||||
|
||||
/* select by key/value buttons */
|
||||
GtkTable* tab = GTK_TABLE( gtk_table_new( 2, 2, FALSE ) );
|
||||
gtk_table_attach( table, GTK_WIDGET( tab ), 2, 3, 0, 2,
|
||||
(GtkAttachOptions)( GTK_FILL ),
|
||||
(GtkAttachOptions)( 0 ), 0, 0 );
|
||||
table = tab;
|
||||
gtk_widget_show( GTK_WIDGET( table ) );
|
||||
gtk_table_set_row_spacings( table, 0 );
|
||||
gtk_table_set_col_spacings( table, 0 );
|
||||
{
|
||||
GtkWidget* button = gtk_button_new();
|
||||
gtk_button_set_image( GTK_BUTTON( button ), gtk_image_new_from_stock( GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU ) );
|
||||
gtk_widget_set_can_focus( button, FALSE );
|
||||
gtk_widget_set_tooltip_text( button, "Select by key" );
|
||||
gtk_widget_show( button );
|
||||
gtk_table_attach( table, button, 0, 1, 0, 1,
|
||||
(GtkAttachOptions)( GTK_FILL ),
|
||||
(GtkAttachOptions)( 0 ), 0, 0 );
|
||||
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectByKey ), 0 );
|
||||
}
|
||||
{
|
||||
GtkWidget* button = gtk_button_new();
|
||||
gtk_button_set_image( GTK_BUTTON( button ), gtk_image_new_from_stock( GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU ) );
|
||||
gtk_widget_set_can_focus( button, FALSE );
|
||||
gtk_widget_set_tooltip_text( button, "Select by value" );
|
||||
gtk_widget_show( button );
|
||||
gtk_table_attach( table, button, 0, 1, 1, 2,
|
||||
(GtkAttachOptions)( GTK_FILL ),
|
||||
(GtkAttachOptions)( 0 ), 0, 0 );
|
||||
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectByValue ), 0 );
|
||||
}
|
||||
{
|
||||
GtkWidget* button = gtk_button_new();
|
||||
gtk_button_set_image( GTK_BUTTON( button ), gtk_image_new_from_stock( GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU ) );
|
||||
gtk_widget_set_can_focus( button, FALSE );
|
||||
gtk_widget_set_tooltip_text( button, "Select by key + value" );
|
||||
gtk_widget_show( button );
|
||||
gtk_table_attach( table, button, 1, 2, 0, 2,
|
||||
(GtkAttachOptions)( GTK_FILL ),
|
||||
(GtkAttachOptions)( GTK_FILL ), 0, 0 );
|
||||
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectByKeyValue ), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -1755,9 +1811,8 @@ GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){
|
|||
}
|
||||
{
|
||||
GtkWidget* button = gtk_toggle_button_new();
|
||||
GtkImage* image = GTK_IMAGE( gtk_image_new_from_stock( GTK_STOCK_ZOOM_IN, GTK_ICON_SIZE_SMALL_TOOLBAR ) );
|
||||
gtk_widget_show( GTK_WIDGET( image ) );
|
||||
gtk_container_add( GTK_CONTAINER( button ), GTK_WIDGET( image ) );
|
||||
GtkWidget* image = gtk_image_new_from_stock( GTK_STOCK_ZOOM_IN, GTK_ICON_SIZE_SMALL_TOOLBAR );
|
||||
gtk_button_set_image( GTK_BUTTON( button ), image );
|
||||
gtk_button_set_relief( GTK_BUTTON( button ), GTK_RELIEF_NONE );
|
||||
gtk_widget_set_can_focus( button, FALSE );
|
||||
gtk_box_pack_start( hbox, button, FALSE, FALSE, 0 );
|
||||
|
|
@ -1856,13 +1911,3 @@ void EntityInspector_construct(){
|
|||
void EntityInspector_destroy(){
|
||||
GlobalEntityClassManager().detach( g_EntityInspector );
|
||||
}
|
||||
|
||||
const char *EntityInspector_getCurrentKey(){
|
||||
if ( !GroupDialog_isShown() ) {
|
||||
return 0;
|
||||
}
|
||||
if ( GroupDialog_getPage() != g_page_entity ) {
|
||||
return 0;
|
||||
}
|
||||
return gtk_entry_get_text( g_entityKeyEntry );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,5 @@ typedef struct _GtkWindow GtkWindow;
|
|||
GtkWidget* EntityInspector_constructWindow( GtkWindow* parent );
|
||||
void EntityInspector_construct();
|
||||
void EntityInspector_destroy();
|
||||
const char *EntityInspector_getCurrentKey();
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -43,7 +43,5 @@ GtkWidget* GroupDialog_addPage( const char* tabLabel, GtkWidget* widget, const S
|
|||
|
||||
void GroupDialog_showPage( GtkWidget* page );
|
||||
void GroupDialog_updatePageTitle( GtkWidget* page );
|
||||
bool GroupDialog_isShown();
|
||||
GtkWidget* GroupDialog_getPage();
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -725,14 +725,14 @@ bool propertyvalues_contain( const PropertyValues& propertyvalues, const char *s
|
|||
return false;
|
||||
}
|
||||
|
||||
template<typename EntityMatcher>
|
||||
class EntityFindByPropertyValueWalker : public scene::Graph::Walker
|
||||
{
|
||||
const PropertyValues& m_propertyvalues;
|
||||
const char *m_prop;
|
||||
const EntityMatcher& m_entityMatcher;
|
||||
const scene::Node* m_world;
|
||||
public:
|
||||
EntityFindByPropertyValueWalker( const char *prop, const PropertyValues& propertyvalues )
|
||||
: m_propertyvalues( propertyvalues ), m_prop( prop ), m_world( Map_FindWorldspawn( g_map ) ){
|
||||
EntityFindByPropertyValueWalker( const EntityMatcher& entityMatcher )
|
||||
: m_entityMatcher( entityMatcher ), m_world( Map_FindWorldspawn( g_map ) ){
|
||||
}
|
||||
bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
||||
if( !path.top().get().visible() ){
|
||||
|
|
@ -745,7 +745,7 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
|||
|
||||
Entity* entity = Node_getEntity( path.top() );
|
||||
if ( entity != 0 ){
|
||||
if( propertyvalues_contain( m_propertyvalues, entity->getKeyValue( m_prop ) ) ) {
|
||||
if( m_entityMatcher( entity ) ) {
|
||||
Instance_getSelectable( instance )->setSelected( true );
|
||||
return true;
|
||||
}
|
||||
|
|
@ -760,8 +760,15 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename EntityMatcher>
|
||||
void Scene_EntitySelectByPropertyValues( scene::Graph& graph, const EntityMatcher& entityMatcher ){
|
||||
graph.traverse( EntityFindByPropertyValueWalker<EntityMatcher>( entityMatcher ) );
|
||||
}
|
||||
|
||||
void Scene_EntitySelectByPropertyValues( scene::Graph& graph, const char *prop, const PropertyValues& propertyvalues ){
|
||||
graph.traverse( EntityFindByPropertyValueWalker( prop, propertyvalues ) );
|
||||
Scene_EntitySelectByPropertyValues( GlobalSceneGraph(), [prop, &propertyvalues]( const Entity* entity )->bool{
|
||||
return propertyvalues_contain( propertyvalues, entity->getKeyValue( prop ) );
|
||||
} );
|
||||
}
|
||||
|
||||
class EntityGetSelectedPropertyValuesWalker : public scene::Graph::Walker
|
||||
|
|
@ -841,10 +848,7 @@ void Select_AllOfType(){
|
|||
else
|
||||
{
|
||||
PropertyValues propertyvalues;
|
||||
const char *prop = EntityInspector_getCurrentKey();
|
||||
if ( !prop || !*prop ) {
|
||||
prop = "classname";
|
||||
}
|
||||
const char *prop = "classname";
|
||||
Scene_EntityGetPropertyValues( GlobalSceneGraph(), prop, propertyvalues );
|
||||
GlobalSelectionSystem().setSelectedAll( false );
|
||||
if ( !propertyvalues.empty() ) {
|
||||
|
|
@ -858,6 +862,45 @@ void Select_AllOfType(){
|
|||
}
|
||||
}
|
||||
|
||||
void Select_EntitiesByKeyValue( const char* key, const char* value ){
|
||||
GlobalSelectionSystem().setSelectedAll( false );
|
||||
if( key != nullptr && value != nullptr ){
|
||||
if( !string_empty( key ) && !string_empty( value ) ){
|
||||
Scene_EntitySelectByPropertyValues( GlobalSceneGraph(), [key, value]( const Entity* entity )->bool{
|
||||
return string_equal_nocase( entity->getKeyValue( key ), value );
|
||||
} );
|
||||
}
|
||||
}
|
||||
else if( key != nullptr ){
|
||||
if( !string_empty( key ) ){
|
||||
Scene_EntitySelectByPropertyValues( GlobalSceneGraph(), [key]( const Entity* entity )->bool{
|
||||
return !string_empty( entity->getKeyValue( key ) );
|
||||
} );
|
||||
}
|
||||
}
|
||||
else if( value != nullptr ){
|
||||
if( !string_empty( value ) ){
|
||||
Scene_EntitySelectByPropertyValues( GlobalSceneGraph(), [value]( const Entity* entity )->bool{
|
||||
class Visitor : public Entity::Visitor
|
||||
{
|
||||
const char* const m_value;
|
||||
public:
|
||||
bool m_found = false;
|
||||
Visitor( const char* value ) : m_value( value ){
|
||||
}
|
||||
void visit( const char* key, const char* value ){
|
||||
if ( string_equal_nocase( m_value, value ) ) {
|
||||
m_found = true;
|
||||
}
|
||||
}
|
||||
} visitor( value );
|
||||
entity->forEachKeyValue( visitor );
|
||||
return visitor.m_found;
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Select_FacesAndPatchesByShader(){
|
||||
Scene_BrushFacesSelectByShader( GlobalSceneGraph(), TextureBrowser_GetSelectedShader() );
|
||||
Scene_PatchSelectByShader( GlobalSceneGraph(), TextureBrowser_GetSelectedShader() );
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ void Selection_MoveDown();
|
|||
void Selection_MoveUp();
|
||||
|
||||
void Select_AllOfType();
|
||||
void Select_EntitiesByKeyValue( const char* key, const char* value );
|
||||
|
||||
void Select_ConnectedEntities( bool targeting, bool targets, bool focus );
|
||||
void SelectConnectedEntities();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user