]> git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/entityinspector.cpp
Q3map2:
[xonotic/netradiant.git] / radiant / entityinspector.cpp
index e187d8030fd8158ab64b713c52745c53ef9ac029..201a4f12b370567688e580b01da5d8691a688d3d 100644 (file)
@@ -49,6 +49,7 @@
 #include <gtk/gtkscrolledwindow.h>
 #include <gtk/gtkentry.h>
 #include <gtk/gtkcombobox.h>
+#include <gtk/gtkstock.h>
 
 
 #include "os/path.h"
@@ -78,6 +79,8 @@
 #include "textureentry.h"
 #include "groupdialog.h"
 
+#include "select.h"
+
 GtkEntry* numeric_entry_new(){
        GtkEntry* entry = GTK_ENTRY( gtk_entry_new() );
        gtk_widget_show( GTK_WIDGET( entry ) );
@@ -153,7 +156,7 @@ void release(){
        delete this;
 }
 void apply(){
-       Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( m_check ) ) ? "1" : "0" );
+       Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( m_check ) ) ? "1" : "" );
 }
 typedef MemberCaller<BooleanAttribute, &BooleanAttribute::apply> ApplyCaller;
 
@@ -222,6 +225,52 @@ ShaderAttribute( const char* key ) : StringAttribute( key ){
 };
 
 
+class ColorAttribute : public EntityAttribute
+{
+CopiedString m_key;
+BrowsedPathEntry m_entry;
+NonModalEntry m_nonModal;
+public:
+ColorAttribute( const char* key ) :
+       m_key( key ),
+       m_entry( BrowseCaller( *this ) ),
+       m_nonModal( ApplyCaller( *this ), UpdateCaller( *this ) ){
+       m_nonModal.connect( m_entry.m_entry.m_entry );
+}
+void release(){
+       delete this;
+}
+GtkWidget* getWidget() const {
+       return GTK_WIDGET( m_entry.m_entry.m_frame );
+}
+void apply(){
+       StringOutputStream value( 64 );
+       value << gtk_entry_get_text( GTK_ENTRY( m_entry.m_entry.m_entry ) );
+       Scene_EntitySetKeyValue_Selected_Undoable( m_key.c_str(), value.c_str() );
+}
+typedef MemberCaller<ColorAttribute, &ColorAttribute::apply> ApplyCaller;
+void update(){
+       StringOutputStream value( 64 );
+       value << SelectedEntity_getValueForKey( m_key.c_str() );
+       gtk_entry_set_text( GTK_ENTRY( m_entry.m_entry.m_entry ), value.c_str() );
+}
+typedef MemberCaller<ColorAttribute, &ColorAttribute::update> UpdateCaller;
+void browse( const BrowsedPathEntry::SetPathCallback& setPath ){
+       //const char *filename = misc_model_dialog( gtk_widget_get_toplevel( GTK_WIDGET( m_entry.m_entry.m_frame ) ) );
+
+       /* hijack BrowsedPathEntry to call colour chooser */
+       Entity_setColour();
+
+//     if ( filename != 0 ) {
+//             setPath( filename );
+//             apply();
+//     }
+       update();
+}
+typedef MemberCaller1<ColorAttribute, const BrowsedPathEntry::SetPathCallback&, &ColorAttribute::browse> BrowseCaller;
+};
+
+
 class ModelAttribute : public EntityAttribute
 {
 CopiedString m_key;
@@ -732,6 +781,8 @@ GtkCheckButton* g_entitySpawnflagsCheck[MAX_FLAGS];
 GtkEntry* g_entityKeyEntry;
 GtkEntry* g_entityValueEntry;
 
+GtkToggleButton* g_focusToggleButton;
+
 GtkListStore* g_entlist_store;
 GtkListStore* g_entprops_store;
 const EntityClass* g_current_flags = 0;
@@ -847,7 +898,34 @@ void SetComment( EntityClass* eclass ){
        g_current_comment = eclass;
 
        GtkTextBuffer* buffer = gtk_text_view_get_buffer( g_entityClassComment );
-       gtk_text_buffer_set_text( buffer, eclass->comments(), -1 );
+       //gtk_text_buffer_set_text( buffer, eclass->comments(), -1 );
+       const char* comment = eclass->comments(), *c;
+       int offset = 0, pattern_start = -1, spaces = 0;
+
+       gtk_text_buffer_set_text( buffer, comment, -1 );
+
+       // Catch patterns like "\nstuff :" used to describe keys and spawnflags, and make them bold for readability.
+
+       for( c = comment; *c; ++c, ++offset ) {
+               if( *c == '\n' ) {
+                       pattern_start = offset;
+                       spaces = 0;
+               }
+               else if( pattern_start >= 0 && ( *c < 'a' || *c > 'z' ) && ( *c < 'A' || *c > 'Z' ) && ( *c < '0' || *c > '9' ) && ( *c != '_' ) ) {
+                       if( *c == ':' && spaces <= 1 ) {
+                               GtkTextIter iter_start, iter_end;
+
+                               gtk_text_buffer_get_iter_at_offset( buffer, &iter_start, pattern_start );
+                               gtk_text_buffer_get_iter_at_offset( buffer, &iter_end, offset );
+                               gtk_text_buffer_apply_tag_by_name( buffer, "bold", &iter_start, &iter_end );
+                       }
+
+                       if( *c == ' ' )
+                               ++spaces;
+                       else
+                               pattern_start = -1;
+               }
+       }
 }
 
 void SurfaceFlags_setEntityClass( EntityClass* eclass ){
@@ -948,7 +1026,7 @@ Creators m_creators;
 public:
 EntityAttributeFactory(){
        m_creators.insert( Creators::value_type( "string", &StatelessAttributeCreator<StringAttribute>::create ) );
-       m_creators.insert( Creators::value_type( "color", &StatelessAttributeCreator<StringAttribute>::create ) );
+       m_creators.insert( Creators::value_type( "color", &StatelessAttributeCreator<ColorAttribute>::create ) );
        m_creators.insert( Creators::value_type( "integer", &StatelessAttributeCreator<StringAttribute>::create ) );
        m_creators.insert( Creators::value_type( "real", &StatelessAttributeCreator<StringAttribute>::create ) );
        m_creators.insert( Creators::value_type( "shader", &StatelessAttributeCreator<ShaderAttribute>::create ) );
@@ -1174,16 +1252,7 @@ void EntityInspector_clearKeyValue(){
 
 static gint EntityInspector_clearKeyValueKB( GtkEntry* widget, GdkEventKey* event, gpointer data ){
        if ( event->keyval == GDK_Delete ) {
-               // Get current selection text
-               StringOutputStream key( 64 );
-               key << gtk_entry_get_text( g_entityKeyEntry );
-
-               if ( strcmp( key.c_str(), "classname" ) != 0 ) {
-                       StringOutputStream command;
-                       command << "entityDeleteKey -key " << key.c_str();
-                       UndoableCommand undo( command.c_str() );
-                       Scene_EntitySetKeyValue_Selected( key.c_str(), "" );
-               }
+               EntityInspector_clearKeyValue();
                return TRUE;
        }
        return FALSE;
@@ -1225,15 +1294,15 @@ static gint EntityClassList_button_press( GtkWidget *widget, GdkEventButton *eve
 }
 
 static gint EntityClassList_keypress( GtkWidget* widget, GdkEventKey* event, gpointer data ){
-       unsigned int code = gdk_keyval_to_upper( event->keyval );
-
        if ( event->keyval == GDK_Return ) {
                EntityClassList_createEntity();
                return TRUE;
        }
 
        // select the entity that starts with the key pressed
-       if ( code <= 'Z' && code >= 'A' ) {
+/*
+       unsigned int code = gdk_keyval_to_upper( event->keyval );
+       if ( code <= 'Z' && code >= 'A' && event->state == 0 ) {
                GtkTreeView* view = g_entityClassList;
                GtkTreeModel* model;
                GtkTreeIter iter;
@@ -1266,6 +1335,7 @@ static gint EntityClassList_keypress( GtkWidget* widget, GdkEventKey* event, gpo
 
                return TRUE;
        }
+*/
        return FALSE;
 }
 
@@ -1295,7 +1365,7 @@ static void SpawnflagCheck_toggled( GtkWidget *widget, gpointer data ){
 static gint EntityEntry_keypress( GtkEntry* widget, GdkEventKey* event, gpointer data ){
        if ( event->keyval == GDK_Return ) {
                if ( widget == g_entityKeyEntry ) {
-                       gtk_entry_set_text( g_entityValueEntry, "" );
+                       //gtk_entry_set_text( g_entityValueEntry, "" );
                        gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( widget ) ) ), GTK_WIDGET( g_entityValueEntry ) );
                }
                else
@@ -1338,13 +1408,29 @@ static gint EntityInspector_hideWindowKB( GtkWidget* widget, GdkEventKey* event,
                gtk_widget_hide( GTK_WIDGET( GroupDialog_getWindow() ) );
                return TRUE;
        }
-       if ( event->keyval == GDK_Tab  ) {
+       /* this doesn't work, if tab is bound (func is not called then) */
+       if ( event->keyval == GDK_Tab ) {
                gtk_window_set_focus( GTK_WINDOW( gtk_widget_get_toplevel( GTK_WIDGET( widget ) ) ), GTK_WIDGET( g_entityKeyEntry ) );
                return TRUE;
        }
        return FALSE;
 }
 
+void EntityInspector_selectTargeting( GtkButton *button, gpointer user_data ){
+       bool focus = gtk_toggle_button_get_active( g_focusToggleButton );
+       Select_ConnectedEntities( true, false, focus );
+}
+
+void EntityInspector_selectTargets( GtkButton *button, gpointer user_data ){
+       bool focus = gtk_toggle_button_get_active( g_focusToggleButton );
+       Select_ConnectedEntities( false, true, focus );
+}
+
+void EntityInspector_selectConnected( GtkButton *button, gpointer user_data ){
+       bool focus = gtk_toggle_button_get_active( g_focusToggleButton );
+       Select_ConnectedEntities( true, true, focus );
+}
+
 GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){
        GtkWidget* vbox = gtk_vbox_new( FALSE, 2 );
        gtk_widget_show( vbox );
@@ -1381,7 +1467,7 @@ GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){
                                        GtkListStore* store = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_POINTER );
 
                                        GtkTreeView* view = GTK_TREE_VIEW( gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) ) );
-                                       gtk_tree_view_set_enable_search( GTK_TREE_VIEW( view ), FALSE );
+                                       //gtk_tree_view_set_enable_search( GTK_TREE_VIEW( view ), FALSE );
                                        gtk_tree_view_set_headers_visible( view, FALSE );
                                        g_signal_connect( G_OBJECT( view ), "button_press_event", G_CALLBACK( EntityClassList_button_press ), 0 );
                                        g_signal_connect( G_OBJECT( view ), "key_press_event", G_CALLBACK( EntityClassList_keypress ), 0 );
@@ -1423,6 +1509,10 @@ GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){
                                        gtk_widget_show( GTK_WIDGET( text ) );
                                        gtk_container_add( GTK_CONTAINER( scr ), GTK_WIDGET( text ) );
                                        g_entityClassComment = text;
+                                       {
+                                               GtkTextBuffer *buffer = gtk_text_view_get_buffer( text );
+                                               gtk_text_buffer_create_tag( buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL );
+                                       }
                                }
                        }
                }
@@ -1549,22 +1639,60 @@ GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){
                                }
 
                                {
-                                       GtkBox* hbox = GTK_BOX( gtk_hbox_new( TRUE, 4 ) );
+                                       GtkBox* hbox = GTK_BOX( gtk_hbox_new( FALSE, 4 ) );
                                        gtk_widget_show( GTK_WIDGET( hbox ) );
                                        gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( hbox ), FALSE, TRUE, 0 );
 
                                        {
                                                GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "Clear All" ) );
+                                               GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
                                                gtk_widget_show( GTK_WIDGET( button ) );
                                                g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_clearAllKeyValues ), 0 );
                                                gtk_box_pack_start( hbox, GTK_WIDGET( button ), TRUE, TRUE, 0 );
                                        }
                                        {
                                                GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "Delete Key" ) );
+                                               GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
                                                gtk_widget_show( GTK_WIDGET( button ) );
                                                g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_clearKeyValue ), 0 );
                                                gtk_box_pack_start( hbox, GTK_WIDGET( button ), TRUE, TRUE, 0 );
                                        }
+                                       {
+                                               GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "<" ) );
+                                               gtk_widget_set_tooltip_text( GTK_WIDGET( button ), "Select targeting entities" );
+                                               GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
+                                               gtk_widget_show( GTK_WIDGET( button ) );
+                                               g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectTargeting ), 0 );
+                                               gtk_box_pack_start( hbox, GTK_WIDGET( button ), FALSE, FALSE, 0 );
+                                       }
+                                       {
+                                               GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( ">" ) );
+                                               gtk_widget_set_tooltip_text( GTK_WIDGET( button ), "Select targets" );
+                                               GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
+                                               gtk_widget_show( GTK_WIDGET( button ) );
+                                               g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectTargets ), 0 );
+                                               gtk_box_pack_start( hbox, GTK_WIDGET( button ), FALSE, FALSE, 0 );
+                                       }
+                                       {
+                                               GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "<->" ) );
+                                               gtk_widget_set_tooltip_text( GTK_WIDGET( button ), "Select connected entities" );
+                                               GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
+                                               gtk_widget_show( GTK_WIDGET( button ) );
+                                               g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectConnected ), 0 );
+                                               gtk_box_pack_start( hbox, GTK_WIDGET( button ), FALSE, FALSE, 0 );
+                                       }
+                                       {
+                                               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 ) );
+                                               gtk_button_set_relief( GTK_BUTTON( button ), GTK_RELIEF_NONE );
+                                               GTK_WIDGET_UNSET_FLAGS( button, GTK_CAN_FOCUS );
+                                               gtk_box_pack_start( hbox, button, FALSE, FALSE, 0 );
+                                               gtk_widget_set_tooltip_text( button, "Focus on Selected" );
+                                               gtk_widget_show( button );
+                                               g_focusToggleButton = GTK_TOGGLE_BUTTON( button );
+                                       }
                                }
                        }