X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=interpreters%2Fchimara-frotz-plugin.c;h=3a9cb34e72742070dd82c478b795fc0c7498b32d;hb=7be6e96b194be20f139e5a0beb4de8e668c4b393;hp=705b12c38a63bca3e3cac78637f81734f3dacbb2;hpb=9543f384fef0a1ceaa719c910e02fac80624c437;p=projects%2Fchimara%2Fchimara.git diff --git a/interpreters/chimara-frotz-plugin.c b/interpreters/chimara-frotz-plugin.c index 705b12c..3a9cb34 100644 --- a/interpreters/chimara-frotz-plugin.c +++ b/interpreters/chimara-frotz-plugin.c @@ -16,7 +16,6 @@ typedef struct _ChimaraFrotzPluginPrivate { #define CHIMARA_FROTZ_PLUGIN_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), CHIMARA_TYPE_FROTZ_PLUGIN, ChimaraFrotzPluginPrivate)) #define CHIMARA_FROTZ_PLUGIN_USE_PRIVATE ChimaraFrotzPluginPrivate *priv = CHIMARA_FROTZ_PLUGIN_PRIVATE(self) - static void chimara_frotz_plugin_configurable_init(PeasGtkConfigurableInterface *); static GtkWidget *chimara_frotz_plugin_create_configure_widget(PeasGtkConfigurable *); @@ -44,6 +43,27 @@ peas_register_types(PeasObjectModule *module) peas_object_module_register_extension_type(module, PEAS_GTK_TYPE_CONFIGURABLE, CHIMARA_TYPE_FROTZ_PLUGIN); } +GType +chimara_frotz_debug_flags_get_type(void) +{ + static volatile size_t g_define_type_id__volatile = 0; + + if(g_once_init_enter(&g_define_type_id__volatile)) { + static const GFlagsValue values[] = { + { CHIMARA_FROTZ_DEBUG_NONE, "CHIMARA_FROTZ_DEBUG_NONE", "none" }, + { CHIMARA_FROTZ_DEBUG_ATTRIBUTE_SETTING, "CHIMARA_FROTZ_DEBUG_ATTRIBUTE_SETTING", "attribute-setting" }, + { CHIMARA_FROTZ_DEBUG_ATTRIBUTE_TESTING, "CHIMARA_FROTZ_DEBUG_ATTRIBUTE_TESTING", "attribute-testing" }, + { CHIMARA_FROTZ_DEBUG_OBJECT_MOVEMENT, "CHIMARA_FROTZ_DEBUG_OBJECT_MOVEMENT", "object-movement" }, + { CHIMARA_FROTZ_DEBUG_OBJECT_LOCATING, "CHIMARA_FROTZ_DEBUG_OBJECT_LOCATING", "object-locating" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = g_flags_register_static(g_intern_static_string("ChimaraFrotzDebugFlags"), values); + g_once_init_leave(&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} + static void chimara_frotz_plugin_init(ChimaraFrotzPlugin *self) { @@ -62,7 +82,7 @@ chimara_frotz_plugin_set_property(GObject *self, unsigned prop_id, const GValue switch(prop_id) { case PROP_DEBUG_MESSAGES: { - unsigned flags = g_value_get_uint(value); + unsigned flags = g_value_get_flags(value); option_attribute_assignment = PROCESS_FLAG(CHIMARA_FROTZ_DEBUG_ATTRIBUTE_SETTING); option_attribute_testing = PROCESS_FLAG(CHIMARA_FROTZ_DEBUG_ATTRIBUTE_TESTING); option_object_movement = PROCESS_FLAG(CHIMARA_FROTZ_DEBUG_OBJECT_MOVEMENT); @@ -125,7 +145,7 @@ chimara_frotz_plugin_get_property(GObject *self, unsigned prop_id, GValue *value | option_attribute_testing << 1 | option_object_movement << 2 | option_object_locating << 3; - g_value_set_uint(value, flags); + g_value_set_flags(value, flags); break; } case PROP_IGNORE_ERRORS: @@ -177,12 +197,11 @@ chimara_frotz_plugin_class_init(ChimaraFrotzPluginClass *klass) * Set of flags to control which debugging messages, if any, Frotz prints * while interpreting the story. See #ChimaraFrotzDebugFlags. */ - /* TODO: register a flags type and use g_param_spec_flags() */ g_object_class_install_property(object_class, PROP_DEBUG_MESSAGES, - g_param_spec_uint("debug-messages", _("Kinds of debugging messages"), + g_param_spec_flags("debug-messages", _("Kinds of debugging messages"), _("Control which kinds of debugging messages to print"), - 0, 255, CHIMARA_FROTZ_DEBUG_NONE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS)); + CHIMARA_TYPE_FROTZ_DEBUG_FLAGS, CHIMARA_FROTZ_DEBUG_NONE, /** * ChimaraFrotzPlugin:ignore-errors: * @@ -320,8 +339,101 @@ chimara_frotz_plugin_configurable_init(PeasGtkConfigurableInterface *iface) iface->create_configure_widget = chimara_frotz_plugin_create_configure_widget; } +/* Helper function to transform flags value to boolean; @data contains the +GINT_TO_POINTER()'ed but position (0=LSB). */ +static gboolean +debug_message_flags_transform_to(GBinding *binding, const GValue *source, GValue *target, gpointer data) +{ + int bit_shift = GPOINTER_TO_INT(data); + unsigned flags = g_value_get_flags(source); + g_value_set_boolean(target, flags & (1 << bit_shift)); + return TRUE; /* success */ +} + +/* Reverse of debug_message_flags_transform_to(). */ +static gboolean +debug_message_flags_transform_from(GBinding *binding, const GValue *source, GValue *target, gpointer data) +{ + int bit_shift = GPOINTER_TO_INT(data); + unsigned flags = g_value_get_flags(target); + int new_value = g_value_get_boolean(source)? 1 : 0; + g_value_set_uint(target, flags & (new_value << bit_shift)); + return TRUE; /* success */ +} + static GtkWidget * chimara_frotz_plugin_create_configure_widget(PeasGtkConfigurable *self) { - return gtk_label_new("Configure Widget"); + GError *error = NULL; + const char *datadir = peas_plugin_info_get_data_dir(peas_engine_get_plugin_info(peas_engine_get_default(), "frotz")); + char *glade_file = g_build_filename(datadir, "chimara-frotz-plugin.glade", NULL); + GtkBuilder *builder = gtk_builder_new(); + if(!gtk_builder_add_from_file(builder, glade_file, &error)) { + g_free(glade_file); + g_critical("Error building Frotz configuration dialog: %s\n", error->message); + return NULL; + } + g_free(glade_file); + GObject *retval = gtk_builder_get_object(builder, "frotz-configure-widget"); + + /* Bind GUI widget properties to this plugin's configuration properties */ + g_object_bind_property_full(self, "debug-messages", + gtk_builder_get_object(builder, "attribute-setting-button"), "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL, + debug_message_flags_transform_to, + debug_message_flags_transform_from, + GINT_TO_POINTER(0), NULL); + g_object_bind_property_full(self, "debug-messages", + gtk_builder_get_object(builder, "attribute-testing-button"), "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL, + debug_message_flags_transform_to, + debug_message_flags_transform_from, + GINT_TO_POINTER(1), NULL); + g_object_bind_property_full(self, "debug-messages", + gtk_builder_get_object(builder, "object-movement-button"), "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL, + debug_message_flags_transform_to, + debug_message_flags_transform_from, + GINT_TO_POINTER(2), NULL); + g_object_bind_property_full(self, "debug-messages", + gtk_builder_get_object(builder, "object-location-button"), "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL, + debug_message_flags_transform_to, + debug_message_flags_transform_from, + GINT_TO_POINTER(3), NULL); + g_object_bind_property(self, "ignore-errors", + gtk_builder_get_object(builder, "ignore-errors-button"), "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); + g_object_bind_property(self, "piracy-mode", + gtk_builder_get_object(builder, "piracy-button"), "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); + g_object_bind_property(self, "quetzal-save-format", + gtk_builder_get_object(builder, "quetzal-button"), "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); + g_object_bind_property(self, "tandy-bit", + gtk_builder_get_object(builder, "tandy-button"), "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); + g_object_bind_property(self, "expand-abbreviations", + gtk_builder_get_object(builder, "expand-abbreviations-button"), "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); + g_object_bind_property(self, "random-seed", + gtk_builder_get_object(builder, "random-seed-adjustment"), "value", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); + g_object_bind_property(self, "random-seed-set", + gtk_builder_get_object(builder, "random-seed-set-button"), "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); + g_object_bind_property(self, "random-seed-set", + gtk_builder_get_object(builder, "random-seed-button"), "sensitive", + G_BINDING_SYNC_CREATE); + g_object_bind_property(self, "transcript-columns", + gtk_builder_get_object(builder, "columns-adjustment"), "value", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); + g_object_bind_property(self, "undo-slots", + gtk_builder_get_object(builder, "undo-adjustment"), "value", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); + + /* Make sure the widget is returned with only one reference */ + g_object_ref_sink(G_OBJECT(retval)); + g_object_unref(builder); + return GTK_WIDGET(retval); }