]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/commands.cpp
Introduce Property<T> to simplify preferences system
[xonotic/netradiant.git] / radiant / commands.cpp
index f463503e04ac95878256a8ab6550cb856f783f6c..93823894f3c480f7c917eb89511122c6c58d2b07 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "commands.h"
 
+#include "gtk/gtk.h"
 #include "debugging/debugging.h"
 #include "warnings.h"
 
@@ -28,7 +29,6 @@
 #include "string/string.h"
 #include "versionlib.h"
 #include "gtkutil/messagebox.h"
-#include <gtk/gtk.h>
 #include "gtkmisc.h"
 
 typedef std::pair<Accelerator, int> ShortcutValue; // accelerator, isRegistered
@@ -71,7 +71,7 @@ typedef std::map<CopiedString, Command> Commands;
 
 Commands g_commands;
 
-void GlobalCommands_insert( const char* name, const Callback& callback, const Accelerator& accelerator ){
+void GlobalCommands_insert( const char* name, const Callback<void()>& callback, const Accelerator& accelerator ){
        bool added = g_commands.insert( Commands::value_type( name, Command( callback, GlobalShortcuts_insert( name, accelerator ) ) ) ).second;
        ASSERT_MESSAGE( added, "command already registered: " << makeQuoted( name ) );
 }
@@ -87,7 +87,7 @@ typedef std::map<CopiedString, Toggle> Toggles;
 
 Toggles g_toggles;
 
-void GlobalToggles_insert( const char* name, const Callback& callback, const BoolExportCallback& exportCallback, const Accelerator& accelerator ){
+void GlobalToggles_insert( const char* name, const Callback<void()>& callback, const Callback<void(const Callback<void(bool)> &)>& exportCallback, const Accelerator& accelerator ){
        bool added = g_toggles.insert( Toggles::value_type( name, Toggle( callback, GlobalShortcuts_insert( name, accelerator ), exportCallback ) ) ).second;
        ASSERT_MESSAGE( added, "toggle already registered: " << makeQuoted( name ) );
 }
@@ -102,7 +102,7 @@ typedef std::map<CopiedString, KeyEvent> KeyEvents;
 
 KeyEvents g_keyEvents;
 
-void GlobalKeyEvents_insert( const char* name, const Accelerator& accelerator, const Callback& keyDown, const Callback& keyUp ){
+void GlobalKeyEvents_insert( const char* name, const Accelerator& accelerator, const Callback<void()>& keyDown, const Callback<void()>& keyUp ){
        bool added = g_keyEvents.insert( KeyEvents::value_type( name, KeyEvent( GlobalShortcuts_insert( name, accelerator ), keyDown, keyUp ) ) ).second;
        ASSERT_MESSAGE( added, "command already registered: " << makeQuoted( name ) );
 }
@@ -165,25 +165,25 @@ struct command_list_dialog_t : public ModalDialog
        }
        ModalDialogButton m_close_button;
 
-       GtkTreeView *m_list;
+       ui::TreeView m_list;
        GtkTreeIter m_command_iter;
-       GtkTreeModel *m_model;
+       ui::TreeModel m_model;
        bool m_waiting_for_key;
 };
 
-void accelerator_clear_button_clicked( GtkButton *btn, gpointer dialogptr ){
+void accelerator_clear_button_clicked( ui::Button btn, gpointer dialogptr ){
        command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr;
 
        if ( dialog.m_waiting_for_key ) {
                // just unhighlight, user wanted to cancel
                dialog.m_waiting_for_key = false;
-               gtk_list_store_set( GTK_LIST_STORE( dialog.m_model ), &dialog.m_command_iter, 2, false, -1 );
-               gtk_widget_set_sensitive( GTK_WIDGET( dialog.m_list ), true );
-               dialog.m_model = NULL;
+               gtk_list_store_set( ui::ListStore::from( dialog.m_model ), &dialog.m_command_iter, 2, false, -1 );
+               gtk_widget_set_sensitive( dialog.m_list , true );
+               dialog.m_model = ui::TreeModel(ui::null);
                return;
        }
 
-       GtkTreeSelection *sel = gtk_tree_view_get_selection( dialog.m_list );
+       auto sel = gtk_tree_view_get_selection( dialog.m_list );
        GtkTreeModel *model;
        GtkTreeIter iter;
        if ( !gtk_tree_selection_get_selected( sel, &model, &iter ) ) {
@@ -192,7 +192,7 @@ void accelerator_clear_button_clicked( GtkButton *btn, gpointer dialogptr ){
 
        GValue val;
        memset( &val, 0, sizeof( val ) );
-       gtk_tree_model_get_value( GTK_TREE_MODEL( model ), &iter, 0, &val );
+       gtk_tree_model_get_value(model, &iter, 0, &val );
        const char *commandName = g_value_get_string( &val );;
 
        // clear the ACTUAL accelerator too!
@@ -204,35 +204,35 @@ void accelerator_clear_button_clicked( GtkButton *btn, gpointer dialogptr ){
        }
        thisShortcutIterator->second.first = accelerator_null();
 
-       gtk_list_store_set( GTK_LIST_STORE( model ), &iter, 1, "", -1 );
+       gtk_list_store_set( ui::ListStore::from( model ), &iter, 1, "", -1 );
 
        g_value_unset( &val );
 }
 
-void accelerator_edit_button_clicked( GtkButton *btn, gpointer dialogptr ){
+void accelerator_edit_button_clicked( ui::Button btn, gpointer dialogptr ){
        command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr;
 
        // 1. find selected row
-       GtkTreeSelection *sel = gtk_tree_view_get_selection( dialog.m_list );
+       auto sel = gtk_tree_view_get_selection( dialog.m_list );
        GtkTreeModel *model;
        GtkTreeIter iter;
        if ( !gtk_tree_selection_get_selected( sel, &model, &iter ) ) {
                return;
        }
        dialog.m_command_iter = iter;
-       dialog.m_model = model;
+       dialog.m_model = ui::TreeModel(model);
 
        // 2. disallow changing the row
-       //gtk_widget_set_sensitive(GTK_WIDGET(dialog.m_list), false);
+       //gtk_widget_set_sensitive(dialog.m_list, false);
 
        // 3. highlight the row
-       gtk_list_store_set( GTK_LIST_STORE( model ), &iter, 2, true, -1 );
+       gtk_list_store_set( ui::ListStore::from( model ), &iter, 2, true, -1 );
 
        // 4. grab keyboard focus
        dialog.m_waiting_for_key = true;
 }
 
-bool accelerator_window_key_press( ui::Widget widget, GdkEventKey *event, gpointer dialogptr ){
+bool accelerator_window_key_press( ui::Window widget, GdkEventKey *event, gpointer dialogptr ){
        command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr;
 
        if ( !dialog.m_waiting_for_key ) {
@@ -269,12 +269,12 @@ bool accelerator_window_key_press( ui::Widget widget, GdkEventKey *event, gpoint
        // 7. find the name of the accelerator
        GValue val;
        memset( &val, 0, sizeof( val ) );
-       gtk_tree_model_get_value( GTK_TREE_MODEL( dialog.m_model ), &dialog.m_command_iter, 0, &val );
+       gtk_tree_model_get_value(dialog.m_model, &dialog.m_command_iter, 0, &val );
        const char *commandName = g_value_get_string( &val );;
        Shortcuts::iterator thisShortcutIterator = g_shortcuts.find( commandName );
        if ( thisShortcutIterator == g_shortcuts.end() ) {
-               gtk_list_store_set( GTK_LIST_STORE( dialog.m_model ), &dialog.m_command_iter, 2, false, -1 );
-               gtk_widget_set_sensitive( GTK_WIDGET( dialog.m_list ), true );
+               gtk_list_store_set( ui::ListStore::from( dialog.m_model ), &dialog.m_command_iter, 2, false, -1 );
+               gtk_widget_set_sensitive( dialog.m_list , true );
                return true;
        }
 
@@ -287,10 +287,10 @@ bool accelerator_window_key_press( ui::Widget widget, GdkEventKey *event, gpoint
        const char *commandName;
        const Accelerator &newAccel;
        ui::Widget widget;
-       GtkTreeModel *model;
+       ui::TreeModel model;
 public:
        bool allow;
-       VerifyAcceleratorNotTaken( const char *name, const Accelerator &accelerator, ui::Widget w, GtkTreeModel *m ) : commandName( name ), newAccel( accelerator ), widget( w ), model( m ), allow( true ){
+       VerifyAcceleratorNotTaken( const char *name, const Accelerator &accelerator, ui::Widget w, ui::TreeModel m ) : commandName( name ), newAccel( accelerator ), widget( w ), model( m ), allow( true ){
        }
        void visit( const char* name, Accelerator& accelerator ){
                if ( !strcmp( name, commandName ) ) {
@@ -306,7 +306,7 @@ public:
                        StringOutputStream msg;
                        msg << "The command " << name << " is already assigned to the key " << accelerator << ".\n\n"
                                << "Do you want to unassign " << name << " first?";
-                       auto r = widget.alert( msg.c_str(), "Key already used", ui::alert_type::YESNOCANCEL );
+                       auto r = widget.window().alert( msg.c_str(), "Key already used", ui::alert_type::YESNOCANCEL );
                        if ( r == ui::alert_response::YES ) {
                                // clear the ACTUAL accelerator too!
                                disconnect_accelerator( name );
@@ -314,18 +314,18 @@ public:
                                accelerator = accelerator_null();
                                // empty the cell of the key binds dialog
                                GtkTreeIter i;
-                               if ( gtk_tree_model_get_iter_first( GTK_TREE_MODEL( model ), &i ) ) {
+                               if ( gtk_tree_model_get_iter_first(model, &i ) ) {
                                        for (;; )
                                        {
                                                GValue val;
                                                memset( &val, 0, sizeof( val ) );
-                                               gtk_tree_model_get_value( GTK_TREE_MODEL( model ), &i, 0, &val );
+                                               gtk_tree_model_get_value(model, &i, 0, &val );
                                                const char *thisName = g_value_get_string( &val );;
                                                if ( !strcmp( thisName, name ) ) {
-                                                       gtk_list_store_set( GTK_LIST_STORE( model ), &i, 1, "", -1 );
+                                                       gtk_list_store_set( ui::ListStore::from( model ), &i, 1, "", -1 );
                                                }
                                                g_value_unset( &val );
-                                               if ( !gtk_tree_model_iter_next( GTK_TREE_MODEL( model ), &i ) ) {
+                                               if ( !gtk_tree_model_iter_next(model, &i ) ) {
                                                        break;
                                                }
                                        }
@@ -340,8 +340,8 @@ public:
        } verify_visitor( commandName, newAccel, widget, dialog.m_model );
        GlobalShortcuts_foreach( verify_visitor );
 
-       gtk_list_store_set( GTK_LIST_STORE( dialog.m_model ), &dialog.m_command_iter, 2, false, -1 );
-       gtk_widget_set_sensitive( GTK_WIDGET( dialog.m_list ), true );
+       gtk_list_store_set( ui::ListStore::from( dialog.m_model ), &dialog.m_command_iter, 2, false, -1 );
+       gtk_widget_set_sensitive( dialog.m_list , true );
 
        if ( verify_visitor.allow ) {
                // clear the ACTUAL accelerator first
@@ -352,7 +352,7 @@ public:
                // write into the cell
                StringOutputStream modifiers;
                modifiers << newAccel;
-               gtk_list_store_set( GTK_LIST_STORE( dialog.m_model ), &dialog.m_command_iter, 1, modifiers.c_str(), -1 );
+               gtk_list_store_set( ui::ListStore::from( dialog.m_model ), &dialog.m_command_iter, 1, modifiers.c_str(), -1 );
 
                // set the ACTUAL accelerator too!
                connect_accelerator( commandName );
@@ -360,7 +360,7 @@ public:
 
        g_value_unset( &val );
 
-       dialog.m_model = NULL;
+       dialog.m_model = ui::TreeModel(ui::null);
 
        return true;
 }
@@ -369,9 +369,9 @@ public:
     GtkTreeIter row;
     GValue val;
     if(!model) {g_error("Unable to get model from cell renderer");}
-    gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(model), &row, path_string);
+    gtk_tree_model_get_iter_from_string(model, &row, path_string);
 
-    gtk_tree_model_get_value(GTK_TREE_MODEL(model), &row, 0, &val);
+    gtk_tree_model_get_value(model, &row, 0, &val);
     const char *name = g_value_get_string(&val);
     Shortcuts::iterator i = g_shortcuts.find(name);
     if(i != g_shortcuts.end())
@@ -379,7 +379,7 @@ public:
         accelerator_parse(i->second.first, new_text);
         StringOutputStream modifiers;
         modifiers << i->second.first;
-        gtk_list_store_set(GTK_LIST_STORE(model), &row, 1, modifiers.c_str(), -1);
+        gtk_list_store_set(ui::ListStore::from(model), &row, 1, modifiers.c_str(), -1);
     }
    };
  */
@@ -389,41 +389,41 @@ void DoCommandListDlg(){
 
        ui::Window window = MainFrame_getWindow().create_modal_dialog_window("Mapped Commands", dialog, -1, 400);
        window.on_key_press([](ui::Widget widget, GdkEventKey *event, gpointer dialogptr) {
-               return accelerator_window_key_press(widget, event, dialogptr);
+               return accelerator_window_key_press(ui::Window::from(widget), event, dialogptr);
        }, &dialog);
 
-       GtkAccelGroup* accel = ui::AccelGroup();
-       gtk_window_add_accel_group( window, accel );
+       auto accel = ui::AccelGroup(ui::New);
+       window.add_accel_group( accel );
 
-       GtkHBox* hbox = create_dialog_hbox( 4, 4 );
-       gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( hbox ) );
+       auto hbox = create_dialog_hbox( 4, 4 );
+       window.add(hbox);
 
        {
-               GtkScrolledWindow* scr = create_scrolled_window( GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC );
-               gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( scr ), TRUE, TRUE, 0 );
+               auto scr = create_scrolled_window( ui::Policy::NEVER, ui::Policy::AUTOMATIC );
+               hbox.pack_start( scr, TRUE, TRUE, 0 );
 
                {
-                       GtkListStore* store = gtk_list_store_new( 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INT );
+                       ui::ListStore store = ui::ListStore(gtk_list_store_new( 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INT ));
 
-                       ui::Widget view = ui::TreeView(ui::TreeModel(GTK_TREE_MODEL(store)));
-                       dialog.m_list = GTK_TREE_VIEW( view );
+                       auto view = ui::TreeView(ui::TreeModel(store));
+                       dialog.m_list = view;
 
-                       gtk_tree_view_set_enable_search( GTK_TREE_VIEW( view ), false ); // annoying
+                       gtk_tree_view_set_enable_search(view, false ); // annoying
 
                        {
-                               auto renderer = ui::CellRendererText();
-                               GtkTreeViewColumn* column = ui::TreeViewColumn( "Command", renderer, {{"text", 0}, {"weight-set", 2}, {"weight", 3}} );
-                               gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column );
+                               auto renderer = ui::CellRendererText(ui::New);
+                               auto column = ui::TreeViewColumn( "Command", renderer, {{"text", 0}, {"weight-set", 2}, {"weight", 3}} );
+                               gtk_tree_view_append_column(view, column );
                        }
 
                        {
-                               auto renderer = ui::CellRendererText();
-                               GtkTreeViewColumn* column = ui::TreeViewColumn( "Key", renderer, {{"text", 1}, {"weight-set", 2}, {"weight", 3}} );
-                               gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column );
+                               auto renderer = ui::CellRendererText(ui::New);
+                               auto column = ui::TreeViewColumn( "Key", renderer, {{"text", 1}, {"weight-set", 2}, {"weight", 3}} );
+                               gtk_tree_view_append_column(view, column );
                        }
 
-                       gtk_widget_show( view );
-                       gtk_container_add( GTK_CONTAINER( scr ), view );
+                       view.show();
+                       scr.add(view);
 
                        {
                                // Initialize dialog
@@ -433,19 +433,15 @@ void DoCommandListDlg(){
                                class BuildCommandList : public CommandVisitor
                                {
                                TextFileOutputStream m_commandList;
-                               GtkListStore* m_store;
+                               ui::ListStore m_store;
 public:
-                               BuildCommandList( const char* filename, GtkListStore* store ) : m_commandList( filename ), m_store( store ){
+                               BuildCommandList( const char* filename, ui::ListStore store ) : m_commandList( filename ), m_store( store ){
                                }
                                void visit( const char* name, Accelerator& accelerator ){
                                        StringOutputStream modifiers;
                                        modifiers << accelerator;
 
-                                       {
-                                               GtkTreeIter iter;
-                                               gtk_list_store_append( m_store, &iter );
-                                               gtk_list_store_set( m_store, &iter, 0, name, 1, modifiers.c_str(), 2, false, 3, 800, -1 );
-                                       }
+                                       m_store.append(0, name, 1, modifiers.c_str(), 2, false, 3, 800);
 
                                        if ( !m_commandList.failed() ) {
                                                int l = strlen( name );
@@ -460,33 +456,33 @@ public:
                                GlobalShortcuts_foreach( visitor );
                        }
 
-                       g_object_unref( G_OBJECT( store ) );
+                       store.unref();
                }
        }
 
-       GtkVBox* vbox = create_dialog_vbox( 4 );
-       gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), TRUE, TRUE, 0 );
+       auto vbox = create_dialog_vbox( 4 );
+       hbox.pack_start( vbox, TRUE, TRUE, 0 );
        {
-               GtkButton* editbutton = create_dialog_button( "Edit", (GCallback) accelerator_edit_button_clicked, &dialog );
-               gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( editbutton ), FALSE, FALSE, 0 );
-
-               GtkButton* clearbutton = create_dialog_button( "Clear", (GCallback) accelerator_clear_button_clicked, &dialog );
-               gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( clearbutton ), FALSE, FALSE, 0 );
-
-               ui::Widget spacer = ui::Image();
-               gtk_widget_show( spacer );
-               gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( spacer ), TRUE, TRUE, 0 );
-
-               GtkButton* button = create_modal_dialog_button( "Close", dialog.m_close_button );
-               gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 );
-               widget_make_default( GTK_WIDGET( button ) );
-               gtk_widget_grab_default( GTK_WIDGET( button ) );
-               gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_Return, (GdkModifierType)0, (GtkAccelFlags)0 );
-               gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_Escape, (GdkModifierType)0, (GtkAccelFlags)0 );
+               auto editbutton = create_dialog_button( "Edit", (GCallback) accelerator_edit_button_clicked, &dialog );
+               vbox.pack_start( editbutton, FALSE, FALSE, 0 );
+
+               auto clearbutton = create_dialog_button( "Clear", (GCallback) accelerator_clear_button_clicked, &dialog );
+               vbox.pack_start( clearbutton, FALSE, FALSE, 0 );
+
+               ui::Widget spacer = ui::Image(ui::New);
+               spacer.show();
+               vbox.pack_start( spacer, TRUE, TRUE, 0 );
+
+               auto button = create_modal_dialog_button( "Close", dialog.m_close_button );
+               vbox.pack_start( button, FALSE, FALSE, 0 );
+               widget_make_default( button );
+               gtk_widget_grab_default( button  );
+               gtk_widget_add_accelerator( button , "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 );
+               gtk_widget_add_accelerator( button , "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 );
        }
 
        modal_dialog_show( window, dialog );
-       gtk_widget_destroy( GTK_WIDGET( window ) );
+       window.destroy();
 }
 
 #include "profile/profile.h"