From: Philip Chimento Date: Sat, 16 Jul 2011 21:58:50 +0000 (+0200) Subject: Merge branch 'master' into browser X-Git-Url: https://git.stderr.nl/gitweb?a=commitdiff_plain;h=6fd0347f330cb24ef6145662023053a1c0f81a64;hp=4a0178d00f3ab8741f5ef10a44a63d49e19d0cd3;p=projects%2Fchimara%2Fchimara.git Merge branch 'master' into browser --- diff --git a/COPYING b/COPYING index eb40986..d1353d4 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 2010, Philip Chimento and Marijn van Vliet. +Copyright (C) 2008, 2009, 2010, 2011 Philip Chimento and Marijn van Vliet. All rights reserved. Chimara is free software copyrighted by Philip Chimento and Marijn van Vliet. diff --git a/configure.ac b/configure.ac index fa284e1..24cd3f8 100644 --- a/configure.ac +++ b/configure.ac @@ -85,18 +85,6 @@ AC_ARG_ENABLE([iliad], [enable_iliad=no]) AM_CONDITIONAL(TARGET_ILIAD, $TEST "x$enable_iliad" = xyes) -### BUILD WITHOUT RECENT FILES MANAGER ######################################### -# (to work around a bug on OS X) -AC_ARG_ENABLE([recent], - [AS_HELP_STRING([--disable-recent], - [Omit recent files menu (to work around a bug on OS X])], - [], - [enable_recent=yes]) -AS_IF([$TEST "x$enable_recent" = "xyes"], - [OPEN_RECENT_MENU_ITEM=""], - [OPEN_RECENT_MENU_ITEM=""]) -AC_SUBST(OPEN_RECENT_MENU_ITEM) - ### RPM CONFIGURATION ########################################################## # --enable-rpm requires rpm and rpmbuild AC_PATH_PROG([RPMBUILD], [rpmbuild], [notfound]) @@ -190,7 +178,6 @@ interpreters/glulxe/Makefile interpreters/git/Makefile tests/Makefile player/Makefile -player/chimara.menus docs/Makefile docs/reference/Makefile docs/reference/version.xml diff --git a/libchimara/chimara-glk.c b/libchimara/chimara-glk.c index 1a8b224..6e1067e 100644 --- a/libchimara/chimara-glk.c +++ b/libchimara/chimara-glk.c @@ -1502,17 +1502,17 @@ chimara_glk_get_tag(ChimaraGlk *glk, ChimaraGlkWindowType window, const gchar *n /** * chimara_glk_get_tag_names: - * @glk: a #ChimaraGlk widget * @num_tags: Return location for the number of tag names retrieved. * - * Retrieves the possible tag names to use in chimara_glk_get_tag(). + * Class method. Retrieves the possible tag names to use in + * chimara_glk_get_tag(). * * Returns: (transfer none) (array length=num_tags) (element-type utf8): * Array of strings containing the tag names. This array is owned by Chimara, * do not free it. */ const gchar ** -chimara_glk_get_tag_names(ChimaraGlk *glk, unsigned int *num_tags) +chimara_glk_get_tag_names(unsigned int *num_tags) { g_return_val_if_fail(num_tags != NULL, NULL); diff --git a/libchimara/chimara-glk.h b/libchimara/chimara-glk.h index 37d2220..743fa84 100644 --- a/libchimara/chimara-glk.h +++ b/libchimara/chimara-glk.h @@ -130,7 +130,7 @@ void chimara_glk_feed_line_input(ChimaraGlk *glk, const gchar *text); gboolean chimara_glk_is_char_input_pending(ChimaraGlk *glk); gboolean chimara_glk_is_line_input_pending(ChimaraGlk *glk); GtkTextTag *chimara_glk_get_tag(ChimaraGlk *glk, ChimaraGlkWindowType window, const gchar *name); -const gchar **chimara_glk_get_tag_names(ChimaraGlk *glk, unsigned int *num_tags); +const gchar **chimara_glk_get_tag_names(unsigned int *num_tags); void chimara_glk_update_style(ChimaraGlk *glk); void chimara_glk_set_resource_load_callback(ChimaraGlk *glk, ChimaraResourceLoadFunc func, gpointer user_data, GDestroyNotify destroy_user_data); diff --git a/libchimara/chimara-if.c b/libchimara/chimara-if.c index 3879a12..9b5d629 100644 --- a/libchimara/chimara-if.c +++ b/libchimara/chimara-if.c @@ -574,7 +574,7 @@ chimara_if_get_preferred_interpreter(ChimaraIF *self, ChimaraIFFormat format) * case @error is set. */ gboolean -chimara_if_run_game(ChimaraIF *self, gchar *gamefile, GError **error) +chimara_if_run_game(ChimaraIF *self, const char *gamefile, GError **error) { g_return_val_if_fail(self && CHIMARA_IS_IF(self), FALSE); g_return_val_if_fail(gamefile, FALSE); @@ -679,7 +679,7 @@ chimara_if_run_game(ChimaraIF *self, gchar *gamefile, GError **error) } /* Game file and external blorb file */ - args = g_slist_prepend(args, gamefile); + args = g_slist_prepend(args, (gpointer)gamefile); if(priv->graphics_file && (interpreter == CHIMARA_IF_INTERPRETER_FROTZ || interpreter == CHIMARA_IF_INTERPRETER_NITFOL) && g_file_test(priv->graphics_file, G_FILE_TEST_EXISTS)) { diff --git a/libchimara/chimara-if.h b/libchimara/chimara-if.h index deda647..c0763ee 100644 --- a/libchimara/chimara-if.h +++ b/libchimara/chimara-if.h @@ -116,7 +116,7 @@ GType chimara_if_get_type(void) G_GNUC_CONST; GtkWidget *chimara_if_new(void); void chimara_if_set_preferred_interpreter(ChimaraIF *self, ChimaraIFFormat format, ChimaraIFInterpreter interpreter); ChimaraIFInterpreter chimara_if_get_preferred_interpreter(ChimaraIF *self, ChimaraIFFormat format); -gboolean chimara_if_run_game(ChimaraIF *self, gchar *gamefile, GError **error); +gboolean chimara_if_run_game(ChimaraIF *self, const char *gamefile, GError **error); ChimaraIFFormat chimara_if_get_format(ChimaraIF *self); ChimaraIFInterpreter chimara_if_get_interpreter(ChimaraIF *self); diff --git a/player/Makefile.am b/player/Makefile.am index 588f183..f6379d6 100644 --- a/player/Makefile.am +++ b/player/Makefile.am @@ -13,10 +13,16 @@ bin_PROGRAMS = chimara_iliad else -dist_pkgdata_DATA = chimara.ui chimara.menus style.css +dist_pkgdata_DATA = chimara.ui browser.menus player.menus style.css bin_PROGRAMS = chimara -chimara_SOURCES = main.c callbacks.c preferences.c preferences.h error.c error.h +chimara_SOURCES = main.c \ + preferences.c preferences.h \ + error.c error.h \ + player.c player.h \ + app.c app.h \ + browser.c browser.h \ + util.c util.h chimara_CPPFLAGS = $(AM_CPPFLAGS) \ -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ -DPACKAGE_SRC_DIR=\""$(srcdir)"\" \ diff --git a/player/app.c b/player/app.c new file mode 100644 index 0000000..bbd79b1 --- /dev/null +++ b/player/app.c @@ -0,0 +1,341 @@ +/* + * Copyright (C) 2008, 2009, 2010, 2011 Philip Chimento and Marijn van Vliet. + * All rights reserved. + * + * Chimara is free software copyrighted by Philip Chimento and Marijn van Vliet. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither of the names Philip Chimento or Marijn van Vliet, nor the name of + * any other contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +/* Use a custom GSettings backend for our preferences file */ +#define G_SETTINGS_ENABLE_BACKEND +#include + +#include +#include +#include "app.h" +#include "browser.h" +#include "error.h" +#include "player.h" +#include "preferences.h" +#include "util.h" + +typedef struct _ChimaraAppPrivate { + /* Action group containing "application actions" */ + GtkActionGroup *action_group; + /* List of currently opened player windows */ + GSList *window_list; +} ChimaraAppPrivate; + +#define CHIMARA_APP_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), CHIMARA_TYPE_APP, ChimaraAppPrivate)) +#define CHIMARA_APP_USE_PRIVATE ChimaraAppPrivate *priv = CHIMARA_APP_PRIVATE(self) + +G_DEFINE_TYPE(ChimaraApp, chimara_app, G_TYPE_OBJECT); + +static void +chimara_app_finalize(GObject *self) +{ + CHIMARA_APP_USE_PRIVATE; + g_object_unref(priv->action_group); + g_slist_free(priv->window_list); + + /* Chain up */ + G_OBJECT_CLASS(chimara_app_parent_class)->finalize(self); +} + +static void +chimara_app_class_init(ChimaraAppClass *klass) +{ + /* Override methods of parent classes */ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + object_class->finalize = chimara_app_finalize; + + /* Private data */ + g_type_class_add_private(klass, sizeof(ChimaraAppPrivate)); +} + +static void +chimara_app_init(ChimaraApp *self) +{ + CHIMARA_APP_USE_PRIVATE; + + /* Create configuration dir ~/.chimara */ + gchar *configdir = g_build_filename(g_get_home_dir(), ".chimara", NULL); + if(!g_file_test(configdir, G_FILE_TEST_IS_DIR) + && g_mkdir(configdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) + g_error(_("Cannot create configuration directory ~/.chimara")); + g_free(configdir); + + /* Initialize settings file; it can be overridden by a "chimara-config" file + in the current directory */ + gchar *keyfile; + if(g_file_test("chimara-config", G_FILE_TEST_IS_REGULAR)) + keyfile = g_strdup("chimara-config"); + else + keyfile = g_build_filename(g_get_home_dir(), ".chimara", "config", NULL); + GSettingsBackend *backend = g_keyfile_settings_backend_new(keyfile, "/org/chimara-if/player/", NULL); + self->prefs_settings = g_settings_new_with_backend("org.chimara-if.player.preferences", backend); + self->state_settings = g_settings_new_with_backend("org.chimara-if.player.state", backend); + g_free(keyfile); + + /* Build user interface */ + char *object_ids[] = { + "app_group", + "aboutwindow", + NULL + }; + GtkBuilder *builder = new_builder_with_objects(object_ids); + + self->aboutwindow = GTK_WIDGET(load_object(builder, "aboutwindow")); + priv->action_group = GTK_ACTION_GROUP(load_object(builder, "app_group")); + g_object_ref(priv->action_group); + + const gchar **ptr; + GtkRecentFilter *filter = gtk_recent_filter_new(); + /* TODO: Use mimetypes and construct the filter dynamically depending on + what plugins are installed */ + const gchar *patterns[] = { + "*.z[1-8]", "*.[zg]lb", "*.[zg]blorb", "*.ulx", "*.blb", "*.blorb", NULL + }; + + for(ptr = patterns; *ptr; ptr++) + gtk_recent_filter_add_pattern(filter, *ptr); + GtkRecentChooser *recent = GTK_RECENT_CHOOSER(load_object(builder, "recent")); + gtk_recent_chooser_add_filter(recent, filter); + + gtk_builder_connect_signals(builder, self); + + g_object_unref(builder); +} + +/* PUBLIC FUNCTIONS */ + +ChimaraApp * +chimara_app_get(void) +{ + static ChimaraApp *theapp = NULL; + + if(G_UNLIKELY(theapp == NULL)) { + theapp = CHIMARA_APP(g_object_new(CHIMARA_TYPE_APP, NULL)); + + /* Create one-per-application windows */ + theapp->prefswindow = chimara_prefs_new(); + theapp->browser_window = chimara_browser_new(); + } + + return theapp; +} + +GtkActionGroup * +chimara_app_get_action_group(ChimaraApp *self) +{ + CHIMARA_APP_USE_PRIVATE; + return priv->action_group; +} + +/* Internal function: See if there is a corresponding graphics file. If so, +return its path. If not, return NULL. */ +static char * +search_for_graphics_file(const char *path) +{ + ChimaraApp *theapp = chimara_app_get(); + + /* First get the name of the story file */ + char *scratch = g_path_get_basename(path); + *(strrchr(scratch, '.')) = '\0'; + + /* Check in the stored resource path, if set */ + char *resource_path; + g_settings_get(theapp->prefs_settings, "resource-path", "ms", &resource_path); + + /* Otherwise check in the current directory */ + if(!resource_path) + resource_path = g_path_get_dirname(path); + + char *blorbfile = g_strconcat(resource_path, "/", scratch, ".blb", NULL); + g_free(scratch); + g_free(resource_path); + + if(g_file_test(blorbfile, G_FILE_TEST_EXISTS)) + return blorbfile; + + g_free(blorbfile); + return NULL; +} + +/* Remove a deleted player window from the list of currently opened windows */ +static gboolean +on_player_delete_event(GtkWidget *player, GdkEvent *event, ChimaraApp *self) +{ + CHIMARA_APP_USE_PRIVATE; + priv->window_list = g_slist_remove(priv->window_list, player); + return FALSE; /* don't block event */ +} + +ChimaraPlayer * +chimara_app_open_game(ChimaraApp *self, const char *path) +{ + CHIMARA_APP_USE_PRIVATE; + GError *error = NULL; + + /* Open a new player window */ + ChimaraPlayer *player = CHIMARA_PLAYER(chimara_player_new()); + gtk_widget_show_all(GTK_WIDGET(player)); + gtk_window_present(GTK_WINDOW(player)); + + gchar *blorbfile = search_for_graphics_file(path); + if(blorbfile) { + g_object_set(player->glk, "graphics-file", blorbfile, NULL); + g_free(blorbfile); + } + if(!chimara_if_run_game(CHIMARA_IF(player->glk), path, &error)) { + error_dialog(GTK_WINDOW(player), error, _("Could not open game file '%s': "), path); + gtk_widget_destroy(GTK_WIDGET(player)); + return NULL; + } + + /* Add the opened game to the list of currently opened windows */ + priv->window_list = g_slist_prepend(priv->window_list, player); + g_signal_connect_after(player, "delete-event", G_CALLBACK(on_player_delete_event), self); + + return player; +} + +void +chimara_app_foreach_game_window(ChimaraApp *self, GFunc func, gpointer data) +{ + CHIMARA_APP_USE_PRIVATE; + g_slist_foreach(priv->window_list, func, data); +} + +/* GLADE CALLBACKS */ + +void +on_open_activate(GtkAction *action, ChimaraApp *theapp) +{ + //if(!confirm_open_new_game(CHIMARA_GLK(player->glk))) + // return; + + GtkWidget *dialog = gtk_file_chooser_dialog_new(_("Open Game"), + GTK_WINDOW(theapp->browser_window), + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); + + /* Get last opened path */ + gchar *path; + g_settings_get(theapp->state_settings, "last-open-path", "ms", &path); + if(path) { + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path); + g_free(path); + } + + if(gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) + goto finally; + + GError *error = NULL; + char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + + if(!chimara_app_open_game(theapp, filename)) + goto finally2; + + path = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)); + if(path) { + g_settings_set(theapp->state_settings, "last-open-path", "ms", path); + g_free(path); + } + + /* Add file to recent files list */ + GtkRecentManager *manager = gtk_recent_manager_get_default(); + gchar *uri; + + if(!(uri = g_filename_to_uri(filename, NULL, &error))) + g_warning(_("Could not convert filename '%s' to URI: %s"), filename, error->message); + else { + if(!gtk_recent_manager_add_item(manager, uri)) + g_warning(_("Could not add URI '%s' to recent files list."), uri); + g_free(uri); + } + +finally2: + g_free(filename); +finally: + gtk_widget_destroy(dialog); +} + +void +on_recent_item_activated(GtkRecentChooser *chooser, ChimaraApp *theapp) +{ + GError *error = NULL; + gchar *uri = gtk_recent_chooser_get_current_uri(chooser); + gchar *filename; + if(!(filename = g_filename_from_uri(uri, NULL, &error))) { + error_dialog(GTK_WINDOW(theapp->browser_window), error, _("Could not open game file '%s': "), uri); + goto finally; + } + + //if(!confirm_open_new_game(CHIMARA_GLK(player->glk))) + // goto finally2; + + if(!chimara_app_open_game(theapp, filename)) + goto finally2; + + /* Add file to recent files list again, this updates it to most recently used */ + GtkRecentManager *manager = gtk_recent_manager_get_default(); + if(!gtk_recent_manager_add_item(manager, uri)) + g_warning(_("Could not add URI '%s' to recent files list."), uri); + +finally2: + g_free(filename); +finally: + g_free(uri); +} + +void +on_quit_chimara_activate(GtkAction *action, ChimaraApp *theapp) +{ + gtk_main_quit(); +} + +void +on_preferences_activate(GtkAction *action, ChimaraApp *theapp) +{ + gtk_window_present(GTK_WINDOW(theapp->prefswindow)); +} + +void +on_about_activate(GtkAction *action, ChimaraApp *theapp) +{ + gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(theapp->aboutwindow), PACKAGE_VERSION); + gtk_window_present(GTK_WINDOW(theapp->aboutwindow)); +} + diff --git a/player/app.h b/player/app.h new file mode 100644 index 0000000..a28061f --- /dev/null +++ b/player/app.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2008, 2009, 2010, 2011 Philip Chimento and Marijn van Vliet. + * All rights reserved. + * + * Chimara is free software copyrighted by Philip Chimento and Marijn van Vliet. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither of the names Philip Chimento or Marijn van Vliet, nor the name of + * any other contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __APP_H__ +#define __APP_H__ + +#include +#include +#include +#include "player.h" + +G_BEGIN_DECLS + +#define CHIMARA_TYPE_APP (chimara_app_get_type()) +#define CHIMARA_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CHIMARA_TYPE_APP, ChimaraApp)) +#define CHIMARA_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CHIMARA_TYPE_APP, ChimaraAppClass)) +#define CHIMARA_IS_APP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CHIMARA_TYPE_APP)) +#define CHIMARA_IS_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CHIMARA_TYPE_APP)) +#define CHIMARA_APP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CHIMARA_TYPE_APP, ChimaraAppClass)) + +typedef struct _ChimaraApp { + GObject parent_instance; + + /* Public pointers */ + GtkWidget *browser_window; + GtkWidget *aboutwindow; + GtkWidget *prefswindow; + /* Public settings */ + GSettings *prefs_settings; + GSettings *state_settings; +} ChimaraApp; + +typedef struct _ChimaraAppClass { + GObjectClass parent_class; +} ChimaraAppClass; + +GType chimara_app_get_type(void) G_GNUC_CONST; +ChimaraApp *chimara_app_get(void); +GtkActionGroup *chimara_app_get_action_group(ChimaraApp *self); +ChimaraPlayer *chimara_app_open_game(ChimaraApp *self, const char *path); +void chimara_app_foreach_game_window(ChimaraApp *self, GFunc func, gpointer data); + +G_END_DECLS + +#endif /* __APP_H__ */ diff --git a/player/browser.c b/player/browser.c new file mode 100644 index 0000000..f63404d --- /dev/null +++ b/player/browser.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2008, 2009, 2010, 2011 Philip Chimento and Marijn van Vliet. + * All rights reserved. + * + * Chimara is free software copyrighted by Philip Chimento and Marijn van Vliet. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither of the names Philip Chimento or Marijn van Vliet, nor the name of + * any other contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "browser.h" +#include "app.h" +#include "util.h" + +typedef struct _ChimaraBrowserPrivate { + GtkActionGroup *action_group; +} ChimaraBrowserPrivate; + +#define CHIMARA_BROWSER_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), CHIMARA_TYPE_BROWSER, ChimaraBrowserPrivate)) +#define CHIMARA_BROWSER_USE_PRIVATE ChimaraBrowserPrivate *priv = CHIMARA_BROWSER_PRIVATE(self) + +G_DEFINE_TYPE(ChimaraBrowser, chimara_browser, GTK_TYPE_WINDOW); + +/* CALLBACKS */ + +static gboolean +on_browser_delete_event(GtkWidget *browser, GdkEvent *event) +{ + gtk_main_quit(); + return TRUE; +} + +/* TYPE SYSTEM */ + +static void +chimara_browser_finalize(GObject *self) +{ + CHIMARA_BROWSER_USE_PRIVATE; + g_object_unref(priv->action_group); + + /* Chain up */ + G_OBJECT_CLASS(chimara_browser_parent_class)->finalize(self); +} + +static void +chimara_browser_class_init(ChimaraBrowserClass *klass) +{ + /* Override methods of parent classes */ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + object_class->finalize = chimara_browser_finalize; + + /* Private data */ + g_type_class_add_private(klass, sizeof(ChimaraBrowserPrivate)); +} + +static void +chimara_browser_init(ChimaraBrowser *self) +{ + CHIMARA_BROWSER_USE_PRIVATE; + ChimaraApp *theapp = chimara_app_get(); + + /* Set own properties */ + g_object_set(self, + "title", _("Chimara"), + NULL); + + /* Build user interface */ + char *object_ids[] = { + "browser_group", + NULL + }; + GtkBuilder *builder = new_builder_with_objects(object_ids); + + priv->action_group = GTK_ACTION_GROUP(load_object(builder, "browser_group")); + g_object_ref(priv->action_group); + + GtkUIManager *uimanager = new_ui_manager("browser.menus"); + + gtk_ui_manager_insert_action_group(uimanager, priv->action_group, 0); + gtk_ui_manager_insert_action_group(uimanager, chimara_app_get_action_group(theapp), 1); + GtkWidget *menubar = gtk_ui_manager_get_widget(uimanager, "/browser_menu"); + GtkWidget *toolbar = gtk_ui_manager_get_widget(uimanager, "/browser_toolbar"); + GtkWidget *vbox = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(self), vbox); + gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0); + + g_signal_connect(self, "delete-event", G_CALLBACK(on_browser_delete_event), NULL); + + g_object_unref(uimanager); + g_object_unref(builder); +} + +/* PUBLIC FUNCTIONS */ + +GtkWidget * +chimara_browser_new(void) +{ + return GTK_WIDGET(g_object_new(CHIMARA_TYPE_BROWSER, + "type", GTK_WINDOW_TOPLEVEL, + NULL)); +} + +/* GLADE CALLBACKS */ + +void +action_add_file(GtkAction *action, ChimaraBrowser *browser) +{ +} + +void +action_add_watched_folder(GtkAction *action, ChimaraBrowser *browser) +{ +} + +void +action_remove_file(GtkAction *action, ChimaraBrowser *browser) +{ +} + +void +action_play(GtkAction *action, ChimaraBrowser *browser) +{ +} + +void +action_more_info(GtkAction *action, ChimaraBrowser *browser) +{ +} diff --git a/player/browser.h b/player/browser.h new file mode 100644 index 0000000..a1392ed --- /dev/null +++ b/player/browser.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2008, 2009, 2010, 2011 Philip Chimento and Marijn van Vliet. + * All rights reserved. + * + * Chimara is free software copyrighted by Philip Chimento and Marijn van Vliet. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither of the names Philip Chimento or Marijn van Vliet, nor the name of + * any other contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __BROWSER_H__ +#define __BROWSER_H__ + +#include +#include + +G_BEGIN_DECLS + +#define CHIMARA_TYPE_BROWSER (chimara_browser_get_type()) +#define CHIMARA_BROWSER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CHIMARA_TYPE_BROWSER, ChimaraBrowser)) +#define CHIMARA_BROWSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CHIMARA_TYPE_BROWSER, ChimaraBrowserClass)) +#define CHIMARA_IS_BROWSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CHIMARA_TYPE_BROWSER)) +#define CHIMARA_IS_BROWSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CHIMARA_TYPE_BROWSER)) +#define CHIMARA_BROWSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CHIMARA_TYPE_BROWSER, ChimaraBrowserClass)) + +typedef struct _ChimaraBrowser { + GtkWindow parent_instance; + + /* Public pointers */ +} ChimaraBrowser; + +typedef struct _ChimaraBrowserClass { + GtkWindowClass parent_class; +} ChimaraBrowserClass; + +GType chimara_browser_get_type(void) G_GNUC_CONST; +GtkWidget *chimara_browser_new(void); + +G_END_DECLS + +#endif /* __BROWSER_H__ */ diff --git a/player/browser.menus b/player/browser.menus new file mode 100644 index 0000000..fc2ccda --- /dev/null +++ b/player/browser.menus @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/player/callbacks.c b/player/callbacks.c deleted file mode 100644 index a4cc173..0000000 --- a/player/callbacks.c +++ /dev/null @@ -1,285 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ -/* - * callbacks.c - * Copyright (C) Philip en Marijn 2008 <> - * - * callbacks.c is free software copyrighted by Philip en Marijn. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name ``Philip en Marijn'' nor the name of any other - * contributor may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * callbacks.c IS PROVIDED BY Philip en Marijn ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Philip en Marijn OR ANY OTHER CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include "error.h" - -/* If a game is running in @glk, warn the user that they will quit the currently -running game if they open a new one. Returns TRUE if no game was running. -Returns FALSE if the user cancelled. Returns TRUE and shuts down the running -game if the user wishes to continue. */ -static gboolean -confirm_open_new_game(ChimaraGlk *glk) -{ - g_return_val_if_fail(glk && CHIMARA_IS_GLK(glk), FALSE); - - GtkWindow *window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(glk))); - - if(chimara_glk_get_running(glk)) { - GtkWidget *dialog = gtk_message_dialog_new(window, - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_CANCEL, - _("Are you sure you want to open a new game?")); - gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), - _("If you open a new game, you will quit the one you are currently playing.")); - gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_OPEN, GTK_RESPONSE_OK); - gint response = gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - - if(response != GTK_RESPONSE_OK) - return FALSE; - - chimara_glk_stop(glk); - chimara_glk_wait(glk); - } - return TRUE; -} - -/* Internal function: See if there is a corresponding graphics file */ -static void -search_for_graphics_file(const char *filename, ChimaraIF *glk) -{ - - extern GSettings *prefs_settings; - - /* First get the name of the story file */ - char *scratch = g_path_get_basename(filename); - *(strrchr(scratch, '.')) = '\0'; - - /* Check in the stored resource path, if set */ - char *resource_path; - g_settings_get(prefs_settings, "resource-path", "ms", &resource_path); - - /* Otherwise check in the current directory */ - if(!resource_path) - resource_path = g_path_get_dirname(filename); - - char *blorbfile = g_strconcat(resource_path, "/", scratch, ".blb", NULL); - if(g_file_test(blorbfile, G_FILE_TEST_EXISTS)) - g_object_set(glk, "graphics-file", blorbfile, NULL); - - g_free(blorbfile); - g_free(scratch); - g_free(resource_path); -} - -void -on_open_activate(GtkAction *action, ChimaraGlk *glk) -{ - GtkWindow *window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(glk))); - - if(!confirm_open_new_game(glk)) - return; - - GtkWidget *dialog = gtk_file_chooser_dialog_new(_("Open Game"), - window, - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL); - - /* Get last opened path */ - extern GSettings *state_settings; - gchar *path; - g_settings_get(state_settings, "last-open-path", "ms", &path); - if(path) { - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path); - g_free(path); - } - - if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - GError *error = NULL; - extern GSettings *prefs_settings; - char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - - search_for_graphics_file(filename, CHIMARA_IF(glk)); - if(!chimara_if_run_game(CHIMARA_IF(glk), filename, &error)) { - error_dialog(window, error, _("Could not open game file '%s': "), filename); - g_free(filename); - gtk_widget_destroy(dialog); - return; - } - - path = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)); - if(path) { - g_settings_set(state_settings, "last-open-path", "ms", path); - g_free(path); - } - - /* Add file to recent files list */ - GtkRecentManager *manager = gtk_recent_manager_get_default(); - gchar *uri; - - if(!(uri = g_filename_to_uri(filename, NULL, &error))) - g_warning(_("Could not convert filename '%s' to URI: %s"), filename, error->message); - else { - if(!gtk_recent_manager_add_item(manager, uri)) - g_warning(_("Could not add URI '%s' to recent files list."), uri); - g_free(uri); - } - g_free(filename); - } - gtk_widget_destroy(dialog); -} - -void -on_recent_item_activated(GtkRecentChooser *chooser, ChimaraGlk *glk) -{ - GError *error = NULL; - GtkWindow *window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(glk))); - gchar *uri = gtk_recent_chooser_get_current_uri(chooser); - gchar *filename; - if(!(filename = g_filename_from_uri(uri, NULL, &error))) { - error_dialog(window, error, _("Could not open game file '%s': "), uri); - goto finally; - } - - if(!confirm_open_new_game(glk)) - goto finally2; - - search_for_graphics_file(filename, CHIMARA_IF(glk)); - if(!chimara_if_run_game(CHIMARA_IF(glk), filename, &error)) { - error_dialog(window, error, _("Could not open game file '%s': "), filename); - goto finally2; - } - - /* Add file to recent files list again, this updates it to most recently used */ - GtkRecentManager *manager = gtk_recent_manager_get_default(); - if(!gtk_recent_manager_add_item(manager, uri)) - g_warning(_("Could not add URI '%s' to recent files list."), uri); - -finally2: - g_free(filename); -finally: - g_free(uri); -} - -void -on_stop_activate(GtkAction *action, ChimaraGlk *glk) -{ - chimara_glk_stop(glk); -} - -void -on_quit_chimara_activate(GtkAction *action, ChimaraGlk *glk) -{ - gtk_main_quit(); -} - -void -on_copy_activate(GtkAction *action, ChimaraGlk *glk) -{ - GtkWindow *toplevel = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(glk))); - GtkWidget *focus = gtk_window_get_focus(toplevel); - /* Call "copy clipboard" on any widget that defines it */ - if(GTK_IS_LABEL(focus) || GTK_IS_ENTRY(focus) || GTK_IS_TEXT_VIEW(focus)) - g_signal_emit_by_name(focus, "copy-clipboard"); -} - -void -on_paste_activate(GtkAction *action, ChimaraGlk *glk) -{ - GtkWindow *toplevel = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(glk))); - GtkWidget *focus = gtk_window_get_focus(toplevel); - /* Call "paste clipboard" on any widget that defines it */ - if(GTK_IS_ENTRY(focus) || GTK_IS_TEXT_VIEW(focus)) - g_signal_emit_by_name(focus, "paste-clipboard"); -} - -void -on_preferences_activate(GtkAction *action, ChimaraGlk *glk) -{ - extern GtkWidget *prefswindow; - gtk_window_present(GTK_WINDOW(prefswindow)); -} - -void -on_toolbar_toggled(GtkToggleAction *action, ChimaraGlk *glk) -{ - extern GtkWidget *toolbar; - - if(gtk_toggle_action_get_active(action)) - gtk_widget_show(toolbar); - else - gtk_widget_hide(toolbar); -} - -void -on_undo_activate(GtkAction *action, ChimaraGlk *glk) -{ - chimara_glk_feed_line_input(glk, "undo"); -} - -void -on_save_activate(GtkAction *action, ChimaraGlk *glk) -{ - chimara_glk_feed_line_input(glk, "save"); -} - -void -on_restore_activate(GtkAction *action, ChimaraGlk *glk) -{ - chimara_glk_feed_line_input(glk, "restore"); -} - -void -on_restart_activate(GtkAction *action, ChimaraGlk *glk) -{ - chimara_glk_feed_line_input(glk, "restart"); -} - -void -on_quit_activate(GtkAction *action, ChimaraGlk *glk) -{ - chimara_glk_feed_line_input(glk, "quit"); -} - -void -on_about_activate(GtkAction *action, ChimaraGlk *glk) -{ - extern GtkWidget *aboutwindow; - gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(aboutwindow), PACKAGE_VERSION); - gtk_window_present(GTK_WINDOW(aboutwindow)); -} - -gboolean -on_window_delete_event(GtkWidget *widget, GdkEvent *event, ChimaraGlk *glk) -{ - gtk_main_quit(); - return TRUE; -} diff --git a/player/chimara.menus.in b/player/chimara.menus.in deleted file mode 100644 index cb383f7..0000000 --- a/player/chimara.menus.in +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - @OPEN_RECENT_MENU_ITEM@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/player/chimara.ui b/player/chimara.ui index 0a80104..36669fd 100644 --- a/player/chimara.ui +++ b/player/chimara.ui @@ -1,24 +1,7 @@ - - + - - - _Game - _Game - - - - - _Open... - _Open - Quit the current game and load a new one - gtk-media-play - - - - _Restore... @@ -38,27 +21,12 @@ - - - _Quit Chimara - _Quit Chimara - Leave the program - gtk-quit - - - _Command _Command - - - _Edit - _Edit - - _Stop Game @@ -68,15 +36,6 @@ - - - Open _Recent - Open _Recent - 10 - mru - - - _Undo @@ -123,6 +82,60 @@ + + + _View + + + + + _Toolbar + Show a toolbar at the top of the window + + + + + + + + _Game + _Game + + + + + _Open... + _Open + Quit the current game and load a new one + gtk-open + + + + + + + _Quit Chimara + _Quit Chimara + Leave the program + gtk-quit + + + + + + _Edit + _Edit + + + + + Open _Recent + Open _Recent + 10 + mru + + + P_references @@ -147,16 +160,56 @@ + + - - _View + + _Add file to library... + Add + Add a single game file to your library + gtk-add + - - _Toolbar - Show a toolbar at the top of the window - + + Add watched _folder to library... + Add folder + Add all the game files in a folder to your library, and keep monitoring the folder to see if any game files are added to it in the future + gtk-directory + + + + + + _Play + Play + Play the game + gtk-media-play + + + + + + More _information... + Info + View information about this game + gtk-info + + + + + + _Remove file + Remove + Remove this game file from your library + gtk-remove + + + + + + _Library @@ -199,15 +252,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Marijn van Vliet Philip Chimento - + - + True False + vertical 2 - + True False end @@ -231,22 +285,6 @@ Philip Chimento - - False - Chimara - 600 - 800 - - - - True - False - - - - - - @@ -255,722 +293,677 @@ Philip Chimento - + + True False - 5 - Chimara Preferences - center - dialog - - - - + + + + + + True + True + + True False - 9 - - + 6 + 6 + + True False - end + 0 + none - - gtk-close + + True + False + 12 + + + Turn on _flepping + True + True + False + Whether to flep or not when gronking a bloop. + False + True + True + + + + + + True - True - True - False - True - + False + <b>General settings</b> + True - - False - False - 0 - False - True - end + False 0 - + + + + + + + + + + True + False + Environment + + + False + + + + + True + False + 6 + 6 + + True - True + False + 2 - + True False - 6 - 6 - - - True - False - 0 - none - - - True - False - 12 - - - Turn on _flepping - True - True - False - Whether to flep or not when gronking a bloop. - False - True - True - - - - - - - True - False - <b>General settings</b> - True - - - - - False - False - 0 - - - - - - - - + 1 + 5 + Load layout from this CSS file: + + GTK_FILL + + + + + 250 + True + False + Select A CSS File + + + + 1 + 2 + - - + + + False + True + 0 + + + + + True + False + + + False + True + 5 + 1 + + + + + True + False + + True False - Environment + 0 + 5 + Select a style to edit: - False + False + True + 0 - + True False - 6 - 6 + 12 - + + 163 True - False - 2 - - - True - False - 1 - 5 - Load layout from this CSS file: - - - GTK_FILL - - + True + never - - 250 + True - False - Select A CSS File - + False + True + style-list + False + False + + + + + + Style Name + True + + + + 0 + + + + - - 1 - 2 - - False + True True 0 - - True - False - - - False - True - 5 - 1 - - - - + True False + 6 - + True False - 0 - 5 - Select a style to edit: + 3 + 2 + 6 + 6 + + + True + False + 0 + Font: + + + GTK_FILL + + + + + True + True + False + + + + 1 + 2 + GTK_FILL + + + + + True + False + 0 + Foreground color: + + + 1 + 2 + GTK_FILL + + + + + 40 + 30 + True + False + True + True + False + #000000000000 + + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + True + False + 0 + Background color: + + + 2 + 3 + GTK_FILL + + + + + 40 + 30 + True + False + True + True + False + #ffffffffffff + + + + 1 + 2 + 2 + 3 + GTK_FILL + + - False + True True 0 - + True False - 12 + 6 + start - - 163 + + gtk-justify-left True + False True - never - automatic - - - True - False - True - style-list - False - False - - - Style Name - True - - - - 0 - - - - - - + False + False + True + top + True + False + - True - True + False + False 0 - + + gtk-justify-center True - False - 6 - - - True - False - 3 - 2 - 6 - 6 - - - True - False - 0 - Font: - - - GTK_FILL - - - - - True - True - False - - - - 1 - 2 - GTK_FILL - - - - - True - False - 0 - Foreground color: - - - 1 - 2 - GTK_FILL - - - - - 40 - 30 - True - False - True - True - False - #000000000000 - - - - 1 - 2 - 1 - 2 - GTK_FILL - - - - - True - False - 0 - Background color: - - - 2 - 3 - GTK_FILL - - - - - 40 - 30 - True - False - True - True - False - #ffffffffffff - - - - 1 - 2 - 2 - 3 - GTK_FILL - - - - - True - True - 0 - - - - - True - False - 6 - start - - - gtk-justify-left - True - False - True - False - False - True - top - True - False - - - - False - False - 0 - - - - - gtk-justify-center - True - False - True - False - False - True - top - False - left - - - - False - False - 1 - - - - - gtk-justify-right - True - False - True - False - False - True - top - False - left - - - - False - False - 2 - - - - - gtk-justify-fill - True - False - True - False - False - True - top - False - left - - - - False - True - 3 - - - - - True - True - 1 - - - - - True - False - 6 - start - - - gtk-bold - True - False - True - False - False - True - top - False - - - - False - False - 0 - - - - - gtk-italic - True - False - True - False - False - True - top - False - - - - False - False - 1 - - - - - gtk-underline - True - False - True - False - False - True - top - False - - - - False - False - 2 - - - - - True - True - 2 - - + False + True + False + False + True + top + False + left + - True - True + False + False 1 + + + gtk-justify-right + True + False + True + False + False + True + top + False + left + + + + False + False + 2 + + + + + gtk-justify-fill + True + False + True + False + False + True + top + False + left + + + + False + True + 3 + + True True - 5 1 + + + True + False + 6 + start + + + gtk-bold + True + False + True + False + False + True + top + False + + + + False + False + 0 + + + + + gtk-italic + True + False + True + False + False + True + top + False + + + + False + False + 1 + + + + + gtk-underline + True + False + True + False + False + True + top + False + + + + False + False + 2 + + + + + True + True + 2 + + True True - 5 - 2 - - - - - 30 - True - False - 0 - 1 - 5 - Example text: - - - False - True - 3 - - - - - 100 - True - True - False - word-char - 10 - 10 - - - True - True - 4 + 1 + True + True + 5 1 - - - True - False - Layout - - - 1 - False - - + + + True + True + 5 + 2 + + + + + 30 + True + False + 0 + 1 + 5 + Example text: + + + False + True + 3 + + + + + 100 + True + True + False + word-char + 10 + 10 + + + True + True + 4 + + + + + 1 + + + + + True + False + Layout + + + 1 + False + + + + + True + False + 6 + 6 + + + True + False + 0 + none - + True False - 6 - 6 + 12 - + True - False - 0 - none + True - + True - False - 12 + True + Which interpreter to use by default for each story format + interpreters + False + True + + + - - True - True - automatic - automatic + + Format + + + + 0 + + + + + + + Interpreter - - True - True - Which interpreter to use by default for each story format - interpreters - False - True - - - Format - - - - 0 - - - - - - - Interpreter - - - True - False - available_interpreters - 0 - - - - 1 - - - - + + True + False + available_interpreters + 0 + + + 1 + - - - True - False - <b>Preferred interpreters</b> - True - - - - True - True - 0 - - - - - True - False - 6 - - - True - False - Look for _resource files in: - True - blorb_file_chooser - - - False - False - 0 - - - - - True - False - Where to look for Blorb resource files containing graphics and sound; normally, these are part of the story file itself, but they are provided as separate files in some older games. - select-folder - - - - True - True - 1 - - - - - False - False - 1 - + + + + True + False + <b>Preferred interpreters</b> + True + + + + + True + True + 0 + + + + + True + False + 6 + + + True + False + Look for _resource files in: + True + blorb_file_chooser + - 2 + False + False + 0 - - + + True False - Interpreters + Where to look for Blorb resource files containing graphics and sound; normally, these are part of the story file itself, but they are provided as separate files in some older games. + select-folder + - 2 - False + True + True + 1 - True - True - 2 + False + False + 1 + + 2 + + + + + True + False + Interpreters + + + 2 + False + - - button-close - diff --git a/player/error.c b/player/error.c index a2df145..c5c971b 100644 --- a/player/error.c +++ b/player/error.c @@ -1,40 +1,53 @@ -/* Copyright 2006 P.F. Chimento - * This file is part of GNOME Inform 7. - * - * GNOME Inform 7 is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. +/* + * Copyright (C) 2008, 2009, 2010, 2011 Philip Chimento and Marijn van Vliet. + * All rights reserved. * - * GNOME Inform 7 is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Chimara is free software copyrighted by Philip Chimento and Marijn van Vliet. * - * You should have received a copy of the GNU General Public License - * along with GNOME Inform 7; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither of the names Philip Chimento or Marijn van Vliet, nor the name of + * any other contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ - -#include -#include +#include +#include +#include #include "error.h" /* Create and display an error dialog box, with parent window parent, and message format string msg. If err is not NULL, tack the error message on to the end of the format string. */ void -error_dialog(GtkWindow *parent, GError *err, const gchar *msg, ...) +error_dialog(GtkWindow *parent, GError *err, const char *msg, ...) { va_list ap; va_start(ap, msg); - gchar buffer[1024]; + char buffer[1024]; g_vsnprintf(buffer, 1024, msg, ap); va_end(ap); - gchar *message; + char *message; if(err) { message = g_strconcat(buffer, err->message, NULL); g_error_free(err); diff --git a/player/error.h b/player/error.h index bb05fbe..f9d7c7a 100644 --- a/player/error.h +++ b/player/error.h @@ -1,27 +1,45 @@ -/* Copyright 2006 P.F. Chimento - * This file is part of GNOME Inform 7. - * - * GNOME Inform 7 is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. +/* + * Copyright (C) 2008, 2009, 2010, 2011 Philip Chimento and Marijn van Vliet. + * All rights reserved. * - * GNOME Inform 7 is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Chimara is free software copyrighted by Philip Chimento and Marijn van Vliet. * - * You should have received a copy of the GNU General Public License - * along with GNOME Inform 7; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither of the names Philip Chimento or Marijn van Vliet, nor the name of + * any other contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ - -#ifndef ERROR_H -#define ERROR_H + +#ifndef __ERROR_H__ +#define __ERROR_H__ #include +#include #include -void error_dialog(GtkWindow *parent, GError *err, const gchar *msg, ...); +G_BEGIN_DECLS + +void error_dialog(GtkWindow *parent, GError *err, const char *msg, ...); + +G_END_DECLS -#endif +#endif /* __ERROR_H__ */ diff --git a/player/main.c b/player/main.c index bd007b4..36473d1 100644 --- a/player/main.c +++ b/player/main.c @@ -1,26 +1,26 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* - * main.c - * Copyright (C) Philip en Marijn 2008 <> - * - * main.c is free software copyrighted by Philip en Marijn. - * + * Copyright (C) 2008, 2009, 2010, 2011 Philip Chimento and Marijn van Vliet. + * All rights reserved. + * + * Chimara is free software copyrighted by Philip Chimento and Marijn van Vliet. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name ``Philip en Marijn'' nor the name of any other - * contributor may be used to endorse or promote products derived + * 3. Neither of the names Philip Chimento or Marijn van Vliet, nor the name of + * any other contributor may be used to endorse or promote products derived * from this software without specific prior written permission. - * - * main.c IS PROVIDED BY Philip en Marijn ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Philip en Marijn OR ANY OTHER CONTRIBUTORS + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR @@ -30,189 +30,13 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include -#include - #include -#include -#include #include - -/* Use a custom GSettings backend for our preferences file */ -#define G_SETTINGS_ENABLE_BACKEND -#include - -#include "error.h" -#include -#include - -#include "preferences.h" - -/* Static global pointers to widgets */ -static GtkUIManager *uimanager = NULL; -static GtkWidget *window = NULL; -static GtkWidget *glk = NULL; - -/* Global global pointers */ -GtkBuilder *builder = NULL; -GtkWidget *aboutwindow = NULL; -GtkWidget *prefswindow = NULL; -GtkWidget *toolbar = NULL; -GSettings *prefs_settings = NULL; -GSettings *state_settings = NULL; - -GObject * -load_object(const gchar *name) -{ - GObject *retval; - if( (retval = gtk_builder_get_object(builder, name)) == NULL) { - error_dialog(NULL, NULL, "Error while getting object '%s'", name); - g_error("Error while getting object '%s'", name); - } - return retval; -} - -static void -change_window_title(ChimaraGlk *glk, GParamSpec *pspec, GtkWindow *window) -{ - gchar *program_name, *story_name, *title; - g_object_get(glk, "program-name", &program_name, "story-name", &story_name, NULL); - if(!program_name) { - gtk_window_set_title(window, "Chimara"); - return; - } - else if(!story_name) - title = g_strdup_printf("%s - Chimara", program_name); - else - title = g_strdup_printf("%s - %s - Chimara", program_name, story_name); - - g_free(program_name); - g_free(story_name); - gtk_window_set_title(window, title); - g_free(title); -} - -static void -create_window(void) -{ - GError *error = NULL; - - builder = gtk_builder_new(); - if( !gtk_builder_add_from_file(builder, PACKAGE_DATA_DIR "/chimara.ui", &error) ) { -#ifdef DEBUG - g_error_free(error); - error = NULL; - if( !gtk_builder_add_from_file(builder, PACKAGE_SRC_DIR "/chimara.ui", &error) ) { -#endif /* DEBUG */ - error_dialog(NULL, error, "Error while building interface: "); - return; -#ifdef DEBUG - } -#endif /* DEBUG */ - } - - window = GTK_WIDGET(load_object("chimara")); - aboutwindow = GTK_WIDGET(load_object("aboutwindow")); - prefswindow = GTK_WIDGET(load_object("prefswindow")); - GtkActionGroup *actiongroup = GTK_ACTION_GROUP(load_object("actiongroup")); - - /* Set the default value of the "View/Toolbar" menu item upon creation of a - new window to the "show-toolbar-default" setting, but bind the setting - one-way only - we don't want toolbars to disappear suddenly */ - GtkToggleAction *toolbar_action = GTK_TOGGLE_ACTION(load_object("toolbar")); - gtk_toggle_action_set_active(toolbar_action, g_settings_get_boolean(state_settings, "show-toolbar-default")); - g_settings_bind(state_settings, "show-toolbar-default", toolbar_action, "active", G_SETTINGS_BIND_SET); - - const gchar **ptr; - GtkRecentFilter *filter = gtk_recent_filter_new(); - /* TODO: Use mimetypes and construct the filter dynamically depending on - what plugins are installed */ - const gchar *patterns[] = { - "*.z[1-8]", "*.[zg]lb", "*.[zg]blorb", "*.ulx", "*.blb", "*.blorb", NULL - }; - - for(ptr = patterns; *ptr; ptr++) - gtk_recent_filter_add_pattern(filter, *ptr); - GtkRecentChooser *recent = GTK_RECENT_CHOOSER(load_object("recent")); - gtk_recent_chooser_add_filter(recent, filter); - - uimanager = gtk_ui_manager_new(); - if( !gtk_ui_manager_add_ui_from_file(uimanager, PACKAGE_DATA_DIR "/chimara.menus", &error) ) { -#ifdef DEBUG - g_error_free(error); - error = NULL; - if( !gtk_ui_manager_add_ui_from_file(uimanager, PACKAGE_SRC_DIR "/chimara.menus", &error) ) { -#endif /* DEBUG */ - error_dialog(NULL, error, "Error while building interface: "); - return; -#ifdef DEBUG - } -#endif /* DEBUG */ - } - - glk = chimara_if_new(); - g_object_set(glk, - "ignore-errors", TRUE, - /*"interpreter-number", CHIMARA_IF_ZMACHINE_TANDY_COLOR,*/ - NULL); - if( !chimara_glk_set_css_from_file(CHIMARA_GLK(glk), PACKAGE_DATA_DIR "/style.css", &error) ) { -#ifdef DEBUG - g_error_free(error); - error = NULL; - if( !chimara_glk_set_css_from_file(CHIMARA_GLK(glk), PACKAGE_SRC_DIR "/style.css", &error) ) { -#endif /* DEBUG */ - error_dialog(NULL, error, "Couldn't open CSS file: "); - return; -#ifdef DEBUG - } -#endif /* DEBUG */ - } - - /* DON'T UNCOMMENT THIS your eyes will burn - but it is a good test of programmatically altering just one style - chimara_glk_set_css_from_string(CHIMARA_GLK(glk), - "buffer.normal { font-family: 'Comic Sans MS'; }");*/ - - GtkBox *vbox = GTK_BOX( gtk_builder_get_object(builder, "vbox") ); - if(vbox == NULL) - { - error_dialog(NULL, NULL, "Could not find vbox"); - return; - } - - gtk_ui_manager_insert_action_group(uimanager, actiongroup, 0); - GtkWidget *menubar = gtk_ui_manager_get_widget(uimanager, "/menubar"); - toolbar = gtk_ui_manager_get_widget(uimanager, "/toolbar"); - gtk_widget_set_no_show_all(toolbar, TRUE); - if(gtk_toggle_action_get_active(toolbar_action)) - gtk_widget_show(toolbar); - else - gtk_widget_hide(toolbar); - - /* Connect the accelerators */ - GtkAccelGroup *accels = gtk_ui_manager_get_accel_group(uimanager); - gtk_window_add_accel_group(GTK_WINDOW(window), accels); - - gtk_box_pack_end(vbox, glk, TRUE, TRUE, 0); - gtk_box_pack_start(vbox, menubar, FALSE, FALSE, 0); - gtk_box_pack_start(vbox, toolbar, FALSE, FALSE, 0); - - gtk_builder_connect_signals(builder, glk); - g_signal_connect(glk, "notify::program-name", G_CALLBACK(change_window_title), window); - g_signal_connect(glk, "notify::story-name", G_CALLBACK(change_window_title), window); - - /* Create preferences window */ - preferences_create(CHIMARA_GLK(glk)); -} +#include "app.h" int main(int argc, char *argv[]) { - GError *error = NULL; - #ifdef ENABLE_NLS bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); @@ -224,48 +48,25 @@ main(int argc, char *argv[]) gdk_threads_init(); gtk_init(&argc, &argv); - /* Create configuration dir ~/.chimara */ - gchar *configdir = g_build_filename(g_get_home_dir(), ".chimara", NULL); - if(!g_file_test(configdir, G_FILE_TEST_IS_DIR) - && g_mkdir(configdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) - g_error(_("Cannot create configuration directory ~/.chimara")); - g_free(configdir); + ChimaraApp *theapp = chimara_app_get(); - /* Initialize settings file; it can be overridden by a "chimara-config" file - in the current directory */ - gchar *keyfile; - if(g_file_test("chimara-config", G_FILE_TEST_IS_REGULAR)) - keyfile = g_strdup("chimara-config"); - else - keyfile = g_build_filename(g_get_home_dir(), ".chimara", "config", NULL); - GSettingsBackend *backend = g_keyfile_settings_backend_new(keyfile, "/org/chimara-if/player/", NULL); - prefs_settings = g_settings_new_with_backend("org.chimara-if.player.preferences", backend); - state_settings = g_settings_new_with_backend("org.chimara-if.player.state", backend); - g_free(keyfile); + //if(argc == 3) { + // g_object_set(glk, "graphics-file", argv[2], NULL); + //} + //if(argc >= 2) { + // if( !chimara_if_run_game(CHIMARA_IF(glk), argv[1], &error) ) { + // error_dialog(GTK_WINDOW(window), error, "Error starting Glk library: "); + // return 1; + // } + //} - create_window(); - gtk_widget_show_all(window); - - g_object_unref( G_OBJECT(uimanager) ); - - if(argc == 3) { - g_object_set(glk, "graphics-file", argv[2], NULL); - } - if(argc >= 2) { - if( !chimara_if_run_game(CHIMARA_IF(glk), argv[1], &error) ) { - error_dialog(GTK_WINDOW(window), error, "Error starting Glk library: "); - return 1; - } - } + gtk_widget_show_all(theapp->browser_window); gdk_threads_enter(); gtk_main(); gdk_threads_leave(); - chimara_glk_stop(CHIMARA_GLK(glk)); - chimara_glk_wait(CHIMARA_GLK(glk)); - - g_object_unref( G_OBJECT(builder) ); + g_object_unref(theapp); return 0; } diff --git a/player/player.c b/player/player.c new file mode 100644 index 0000000..10f45d5 --- /dev/null +++ b/player/player.c @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2008, 2009, 2010, 2011 Philip Chimento and Marijn van Vliet. + * All rights reserved. + * + * Chimara is free software copyrighted by Philip Chimento and Marijn van Vliet. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither of the names Philip Chimento or Marijn van Vliet, nor the name of + * any other contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "player.h" +#include "app.h" +#include "error.h" +#include "util.h" + +typedef struct _ChimaraPlayerPrivate { + int dummy; +} ChimaraPlayerPrivate; + +#define CHIMARA_PLAYER_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), CHIMARA_TYPE_PLAYER, ChimaraPlayerPrivate)) +#define CHIMARA_PLAYER_USE_PRIVATE ChimaraPlayerPrivate *priv = CHIMARA_PLAYER_PRIVATE(self) + +G_DEFINE_TYPE(ChimaraPlayer, chimara_player, GTK_TYPE_WINDOW); + +static void +change_window_title(ChimaraGlk *glk, GParamSpec *pspec, GtkWindow *window) +{ + gchar *program_name, *story_name, *title; + g_object_get(glk, "program-name", &program_name, "story-name", &story_name, NULL); + if(!program_name) { + gtk_window_set_title(window, "Chimara"); + return; + } + else if(!story_name) + title = g_strdup_printf("%s - Chimara", program_name); + else + title = g_strdup_printf("%s - %s - Chimara", program_name, story_name); + + g_free(program_name); + g_free(story_name); + gtk_window_set_title(window, title); + g_free(title); +} + +static void +on_css_changed(GSettings *prefs_settings, char *key, ChimaraPlayer *self) +{ + char *user_css; + g_settings_get(prefs_settings, "css-file", "ms", &user_css); + if(user_css) { + if(!chimara_glk_set_css_from_file(CHIMARA_GLK(self->glk), user_css, NULL)) { + /* If the setting didn't point to a CSS file, fail silently and + null the setting */ + g_settings_set(prefs_settings, "css-file", "ms", NULL); + } + g_free(user_css); + } +} + +static void +chimara_player_dispose(GObject *object) +{ + ChimaraPlayer *self = CHIMARA_PLAYER(object); + if(chimara_glk_get_running(CHIMARA_GLK(self->glk))) { + chimara_glk_stop(CHIMARA_GLK(self->glk)); + chimara_glk_wait(CHIMARA_GLK(self->glk)); + } + + /* Chain up */ + G_OBJECT_CLASS(chimara_player_parent_class)->dispose(object); +} + +static void +chimara_player_finalize(GObject *object) +{ + g_object_unref(CHIMARA_PLAYER(object)->glk); + + /* Chain up */ + G_OBJECT_CLASS(chimara_player_parent_class)->finalize(object); +} + +static void +chimara_player_class_init(ChimaraPlayerClass *klass) +{ + /* Override methods of parent classes */ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + object_class->dispose = chimara_player_dispose; + object_class->finalize = chimara_player_finalize; + + /* Private data */ + g_type_class_add_private(klass, sizeof(ChimaraPlayerPrivate)); +} + +static void +chimara_player_init(ChimaraPlayer *self) +{ + GError *error = NULL; + ChimaraApp *theapp = chimara_app_get(); + + /* Set parent properties */ + g_object_set(self, + "title", _("Chimara"), + "default-width", 600, + "default-height", 800, + NULL); + + /* Construct user interface */ + char *object_ids[] = { + "actiongroup", + "player-vbox", + NULL + }; + GtkBuilder *builder = new_builder_with_objects(object_ids); + + GtkActionGroup *actiongroup = GTK_ACTION_GROUP(load_object(builder, "actiongroup")); + + /* Set the default value of the "View/Toolbar" menu item upon creation of a + new window to the "show-toolbar-default" setting, but bind the setting + one-way only - we don't want toolbars to disappear suddenly */ + GtkToggleAction *toolbar_action = GTK_TOGGLE_ACTION(load_object(builder, "toolbar")); + gtk_toggle_action_set_active(toolbar_action, g_settings_get_boolean(theapp->state_settings, "show-toolbar-default")); + g_settings_bind(theapp->state_settings, "show-toolbar-default", toolbar_action, "active", G_SETTINGS_BIND_SET); + + self->glk = chimara_if_new(); + g_object_set(self->glk, + "ignore-errors", TRUE, + /*"interpreter-number", CHIMARA_IF_ZMACHINE_TANDY_COLOR,*/ + NULL); + + /* Set the CSS styles for the interpreter */ + char *default_css = get_data_file_path("style.css"); + if( !chimara_glk_set_css_from_file(CHIMARA_GLK(self->glk), default_css, &error) ) { + error_dialog(GTK_WINDOW(self), error, "Couldn't open default CSS file: "); + } + g_free(default_css); + on_css_changed(theapp->prefs_settings, "css-file", self); + + /* DON'T UNCOMMENT THIS your eyes will burn + but it is a good test of programmatically altering just one style + chimara_glk_set_css_from_string(CHIMARA_GLK(glk), + "buffer.normal { font-family: 'Comic Sans MS'; }");*/ + + GtkUIManager *uimanager = new_ui_manager("player.menus"); + gtk_ui_manager_insert_action_group(uimanager, actiongroup, 0); + gtk_ui_manager_insert_action_group(uimanager, chimara_app_get_action_group(theapp), 1); + GtkWidget *menubar = gtk_ui_manager_get_widget(uimanager, "/player_menu"); + self->toolbar = gtk_ui_manager_get_widget(uimanager, "/player_toolbar"); + gtk_widget_set_no_show_all(self->toolbar, TRUE); + if(gtk_toggle_action_get_active(toolbar_action)) + gtk_widget_show(self->toolbar); + else + gtk_widget_hide(self->toolbar); + + /* Connect the accelerators */ + GtkAccelGroup *accels = gtk_ui_manager_get_accel_group(uimanager); + gtk_window_add_accel_group(GTK_WINDOW(self), accels); + + GtkBox *vbox = GTK_BOX(load_object(builder, "player-vbox")); + gtk_box_pack_end(vbox, self->glk, TRUE, TRUE, 0); + g_object_ref(self->glk); /* add an extra reference to keep it alive while + the Glk program shuts down */ + gtk_box_pack_start(vbox, menubar, FALSE, FALSE, 0); + gtk_box_pack_start(vbox, self->toolbar, FALSE, FALSE, 0); + gtk_container_add(GTK_CONTAINER(self), GTK_WIDGET(vbox)); + + gtk_builder_connect_signals(builder, self); + g_signal_connect(self->glk, "notify::program-name", G_CALLBACK(change_window_title), self); + g_signal_connect(self->glk, "notify::story-name", G_CALLBACK(change_window_title), self); + g_signal_connect(theapp->prefs_settings, "changed::css-file", G_CALLBACK(on_css_changed), self); + + g_object_unref(builder); + g_object_unref(uimanager); +} + +/* PUBLIC FUNCTIONS */ + +GtkWidget * +chimara_player_new(void) +{ + return GTK_WIDGET(g_object_new(CHIMARA_TYPE_PLAYER, + "type", GTK_WINDOW_TOPLEVEL, + NULL)); +} + +void +chimara_player_set_user_css_file(ChimaraPlayer *self, const char *filename) +{ + chimara_glk_set_css_to_default(CHIMARA_GLK(self->glk)); + chimara_glk_set_css_from_file(CHIMARA_GLK(self->glk), filename, NULL); +} + +/* GLADE CALLBACKS */ + +#if 0 +/* If a game is running in @glk, warn the user that they will quit the currently +running game if they open a new one. Returns TRUE if no game was running. +Returns FALSE if the user cancelled. Returns TRUE and shuts down the running +game if the user wishes to continue. */ +static gboolean +confirm_open_new_game(ChimaraGlk *glk) +{ + g_return_val_if_fail(glk && CHIMARA_IS_GLK(glk), FALSE); + + GtkWindow *window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(glk))); + + if(chimara_glk_get_running(glk)) { + GtkWidget *dialog = gtk_message_dialog_new(window, + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_CANCEL, + _("Are you sure you want to open a new game?")); + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), + _("If you open a new game, you will quit the one you are currently playing.")); + gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_OPEN, GTK_RESPONSE_OK); + gint response = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + + if(response != GTK_RESPONSE_OK) + return FALSE; + + chimara_glk_stop(glk); + chimara_glk_wait(glk); + } + return TRUE; +} +#endif + +void +on_stop_activate(GtkAction *action, ChimaraPlayer *player) +{ + chimara_glk_stop(CHIMARA_GLK(player->glk)); +} + +void +on_copy_activate(GtkAction *action, ChimaraPlayer *player) +{ + GtkWidget *focus = gtk_window_get_focus(GTK_WINDOW(player)); + /* Call "copy clipboard" on any widget that defines it */ + if(GTK_IS_LABEL(focus) || GTK_IS_ENTRY(focus) || GTK_IS_TEXT_VIEW(focus)) + g_signal_emit_by_name(focus, "copy-clipboard"); +} + +void +on_paste_activate(GtkAction *action, ChimaraPlayer *player) +{ + GtkWidget *focus = gtk_window_get_focus(GTK_WINDOW(player)); + /* Call "paste clipboard" on any widget that defines it */ + if(GTK_IS_ENTRY(focus) || GTK_IS_TEXT_VIEW(focus)) + g_signal_emit_by_name(focus, "paste-clipboard"); +} + +void +on_toolbar_toggled(GtkToggleAction *action, ChimaraPlayer *player) +{ + if(gtk_toggle_action_get_active(action)) + gtk_widget_show(player->toolbar); + else + gtk_widget_hide(player->toolbar); +} + +void +on_undo_activate(GtkAction *action, ChimaraPlayer *player) +{ + chimara_glk_feed_line_input(CHIMARA_GLK(player->glk), "undo"); +} + +void +on_save_activate(GtkAction *action, ChimaraPlayer *player) +{ + chimara_glk_feed_line_input(CHIMARA_GLK(player->glk), "save"); +} + +void +on_restore_activate(GtkAction *action, ChimaraPlayer *player) +{ + chimara_glk_feed_line_input(CHIMARA_GLK(player->glk), "restore"); +} + +void +on_restart_activate(GtkAction *action, ChimaraPlayer *player) +{ + chimara_glk_feed_line_input(CHIMARA_GLK(player->glk), "restart"); +} + +void +on_quit_activate(GtkAction *action, ChimaraPlayer *player) +{ + chimara_glk_feed_line_input(CHIMARA_GLK(player->glk), "quit"); +} + diff --git a/player/player.h b/player/player.h new file mode 100644 index 0000000..f777b87 --- /dev/null +++ b/player/player.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008, 2009, 2010, 2011 Philip Chimento and Marijn van Vliet. + * All rights reserved. + * + * Chimara is free software copyrighted by Philip Chimento and Marijn van Vliet. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither of the names Philip Chimento or Marijn van Vliet, nor the name of + * any other contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PLAYER_H__ +#define __PLAYER_H__ + +#include +#include + +G_BEGIN_DECLS + +#define CHIMARA_TYPE_PLAYER (chimara_player_get_type()) +#define CHIMARA_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CHIMARA_TYPE_PLAYER, ChimaraPlayer)) +#define CHIMARA_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CHIMARA_TYPE_PLAYER, ChimaraPlayerClass)) +#define CHIMARA_IS_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CHIMARA_TYPE_PLAYER)) +#define CHIMARA_IS_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CHIMARA_TYPE_PLAYER)) +#define CHIMARA_PLAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CHIMARA_TYPE_PLAYER, ChimaraPlayerClass)) + +typedef struct _ChimaraPlayer { + GtkWindow parent_instance; + + /* Public pointers to widgets */ + GtkWidget *glk, *toolbar; +} ChimaraPlayer; + +typedef struct _ChimaraPlayerClass { + GtkWindowClass parent_class; +} ChimaraPlayerClass; + +GType chimara_player_get_type(void) G_GNUC_CONST; +GtkWidget *chimara_player_new(void); +void chimara_player_set_user_css_file(ChimaraPlayer *player, const char *filename); + +G_END_DECLS + +#endif /* __PLAYER_H__ */ diff --git a/player/player.menus b/player/player.menus new file mode 100644 index 0000000..3d80345 --- /dev/null +++ b/player/player.menus @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/player/preferences.c b/player/preferences.c index 9154f4e..df1edc6 100644 --- a/player/preferences.c +++ b/player/preferences.c @@ -1,26 +1,26 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ /* - * callbacks.c - * Copyright (C) Philip en Marijn 2008 <> - * - * preferences.c is free software copyrighted by Philip en Marijn. - * + * Copyright (C) 2008, 2009, 2010, 2011 Philip Chimento and Marijn van Vliet. + * All rights reserved. + * + * Chimara is free software copyrighted by Philip Chimento and Marijn van Vliet. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name ``Philip en Marijn'' nor the name of any other - * contributor may be used to endorse or promote products derived + * 3. Neither of the names Philip Chimento or Marijn van Vliet, nor the name of + * any other contributor may be used to endorse or promote products derived * from this software without specific prior written permission. - * - * preferences.c IS PROVIDED BY Philip en Marijn ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Philip en Marijn OR ANY OTHER CONTRIBUTORS + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR @@ -30,20 +30,48 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include +#include #include #include #include #include -#include #include "error.h" +#include "app.h" +#include "preferences.h" +#include "util.h" + +typedef struct _ChimaraPrefsPrivate { + int dummy; +} ChimaraPrefsPrivate; + +#define CHIMARA_PREFS_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), CHIMARA_TYPE_PREFS, ChimaraPrefsPrivate)) +#define CHIMARA_PREFS_USE_PRIVATE ChimaraPrefsPrivate *priv = CHIMARA_PREFS_PRIVATE(self) + +G_DEFINE_TYPE(ChimaraPrefs, chimara_prefs, GTK_TYPE_DIALOG); -GObject *load_object(const gchar *name); static GtkTextTag *current_tag; static GtkListStore *preferred_list; -static void style_tree_select_callback(GtkTreeSelection *selection, ChimaraGlk *glk); +static void style_tree_select_callback(GtkTreeSelection *selection); + +static void +chimara_prefs_finalize(GObject *self) +{ + /* Chain up */ + G_OBJECT_CLASS(chimara_prefs_parent_class)->finalize(self); +} + +static void +chimara_prefs_class_init(ChimaraPrefsClass *klass) +{ + /* Override methods of parent classes */ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + object_class->finalize = chimara_prefs_finalize; + + /* Private data */ + g_type_class_add_private(klass, sizeof(ChimaraPrefsPrivate)); +} /* Internal functions to convert from human-readable names in the config file to enums and back. Later: replace with plugin functions. */ @@ -135,11 +163,38 @@ interpreter_to_display_string(ChimaraIFInterpreter interp) } /* Create the preferences dialog. */ -void -preferences_create(ChimaraGlk *glk) +static void +chimara_prefs_init(ChimaraPrefs *self) { + ChimaraApp *theapp = chimara_app_get(); + + /* Set parent properties */ + g_object_set(self, + "title", _("Chimara Preferences"), + "window-position", GTK_WIN_POS_CENTER, + "type-hint", GDK_WINDOW_TYPE_HINT_DIALOG, + "border-width", 6, + NULL); + gtk_dialog_add_buttons(GTK_DIALOG(self), + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, + NULL); + + /* Build user interface */ + char *object_ids[] = { + "prefs-notebook", + "available_interpreters", + "interpreters", + "style-list", + NULL + }; + GtkBuilder *builder = new_builder_with_objects(object_ids); + + GtkWidget *notebook = GTK_WIDGET( load_object(builder, "prefs-notebook") ); + GtkWidget *content_area = gtk_dialog_get_content_area( GTK_DIALOG(self) ); + gtk_container_add( GTK_CONTAINER(content_area), notebook ); + /* Initialize the tree of style names */ - GtkTreeStore *style_list = GTK_TREE_STORE( load_object("style-list") ); + GtkTreeStore *style_list = GTK_TREE_STORE( load_object(builder, "style-list") ); GtkTreeIter buffer, grid, buffer_child, grid_child; gtk_tree_store_append(style_list, &buffer, NULL); @@ -149,7 +204,7 @@ preferences_create(ChimaraGlk *glk) int i; unsigned int num_tags; - const gchar **tag_names = chimara_glk_get_tag_names(glk, &num_tags); + const gchar **tag_names = chimara_glk_get_tag_names(&num_tags); for(i=0; iprefs_settings, "flep", flep, "active", G_SETTINGS_BIND_DEFAULT); + GtkFileChooser *blorb_chooser = GTK_FILE_CHOOSER( load_object(builder, "blorb_file_chooser") ); + GtkFileChooser *css_chooser = GTK_FILE_CHOOSER( load_object(builder, "css-filechooser") ); char *filename; - g_settings_get(prefs_settings, "resource-path", "ms", &filename); + g_settings_get(theapp->prefs_settings, "resource-path", "ms", &filename); if(filename) { gtk_file_chooser_set_filename(blorb_chooser, filename); g_free(filename); } - g_settings_get(prefs_settings, "css-file", "ms", &filename); + + g_settings_get(theapp->prefs_settings, "css-file", "ms", &filename); if(filename) { - if(!chimara_glk_set_css_from_file(glk, filename, NULL)) { - /* If the setting didn't point to a CSS file, fail silently and - null the setting */ - g_settings_set(prefs_settings, "css-file", "ms", NULL); - } else { - gtk_file_chooser_set_filename(css_chooser, filename); - } + gtk_file_chooser_set_filename(css_chooser, filename); g_free(filename); } /* Populate the list of available interpreters */ - GtkListStore *interp_list = GTK_LIST_STORE( load_object("available_interpreters") ); + GtkListStore *interp_list = GTK_LIST_STORE( load_object(builder, "available_interpreters") ); unsigned int count; GtkTreeIter tree_iter; for(count = 0; count < CHIMARA_IF_NUM_INTERPRETERS; count++) { @@ -199,33 +248,51 @@ preferences_create(ChimaraGlk *glk) } /* Get the list of preferred interpreters from the preferences */ - GVariantIter *iter; - char *format, *plugin; - g_settings_get(prefs_settings, "preferred-interpreters", "a{ss}", &iter); - while(g_variant_iter_loop(iter, "{ss}", &format, &plugin)) { - ChimaraIFFormat format_num = parse_format(format); - if(format_num == CHIMARA_IF_FORMAT_NONE) - continue; - ChimaraIFInterpreter interp_num = parse_interpreter(plugin); - if(interp_num == CHIMARA_IF_INTERPRETER_NONE) - continue; - chimara_if_set_preferred_interpreter(CHIMARA_IF(glk), format_num, interp_num); - } - g_variant_iter_free(iter); + //GVariantIter *iter; + //char *format, *plugin; + //g_settings_get(prefs_settings, "preferred-interpreters", "a{ss}", &iter); + //while(g_variant_iter_loop(iter, "{ss}", &format, &plugin)) { + // ChimaraIFFormat format_num = parse_format(format); + // if(format_num == CHIMARA_IF_FORMAT_NONE) + // continue; + // ChimaraIFInterpreter interp_num = parse_interpreter(plugin); + // if(interp_num == CHIMARA_IF_INTERPRETER_NONE) + // continue; + // chimara_if_set_preferred_interpreter(CHIMARA_IF(glk), format_num, interp_num); + //} + //g_variant_iter_free(iter); /* Display it all in the list */ - preferred_list = GTK_LIST_STORE( load_object("interpreters") ); - for(count = 0; count < CHIMARA_IF_NUM_FORMATS; count++) { - gtk_list_store_append(preferred_list, &tree_iter); - gtk_list_store_set(preferred_list, &tree_iter, - 0, format_to_display_string(count), - 1, interpreter_to_display_string(chimara_if_get_preferred_interpreter(CHIMARA_IF(glk), count)), - -1); - } + //preferred_list = GTK_LIST_STORE( load_object(builder, "interpreters") ); + //for(count = 0; count < CHIMARA_IF_NUM_FORMATS; count++) { + // gtk_list_store_append(preferred_list, &tree_iter); + // gtk_list_store_set(preferred_list, &tree_iter, + // 0, format_to_display_string(count), + // 1, interpreter_to_display_string(chimara_if_get_preferred_interpreter(CHIMARA_IF(glk), count)), + // -1); + //} + + gtk_builder_connect_signals(builder, self); + g_object_unref(builder); + + /* Connect own signals */ + g_signal_connect(self, "response", G_CALLBACK(gtk_widget_hide), NULL); + g_signal_connect(self, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); } +/* PUBLIC FUNCTIONS */ +GtkWidget * +chimara_prefs_new(void) +{ + return GTK_WIDGET(g_object_new(CHIMARA_TYPE_PREFS, + "type", GTK_WINDOW_TOPLEVEL, + NULL)); +} + +/* GLADE CALLBACKS */ + static void -style_tree_select_callback(GtkTreeSelection *selection, ChimaraGlk *glk) +style_tree_select_callback(GtkTreeSelection *selection) { GtkTreeIter child, parent; gchar *child_name, *parent_name; @@ -240,10 +307,10 @@ style_tree_select_callback(GtkTreeSelection *selection, ChimaraGlk *glk) return; gtk_tree_model_get(model, &parent, 0, &parent_name, -1); - if( !strcmp(parent_name, "Text buffer") ) - current_tag = chimara_glk_get_tag(glk, CHIMARA_GLK_TEXT_BUFFER, child_name); - else - current_tag = chimara_glk_get_tag(glk, CHIMARA_GLK_TEXT_GRID, child_name); + //if( !strcmp(parent_name, "Text buffer") ) + // current_tag = chimara_glk_get_tag(glk, CHIMARA_GLK_TEXT_BUFFER, child_name); + //else + // current_tag = chimara_glk_get_tag(glk, CHIMARA_GLK_TEXT_GRID, child_name); } void @@ -339,58 +406,52 @@ on_font_set(GtkFontButton *button, ChimaraGlk *glk) void on_css_filechooser_file_set(GtkFileChooserButton *button, ChimaraGlk *glk) { - GError *error = NULL; - extern GSettings *prefs_settings; + ChimaraApp *theapp = chimara_app_get(); char *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(button) ); - if(!chimara_glk_set_css_from_file(glk, filename, &error)) { - error_dialog(NULL, error, "There was a problem reading the CSS file: "); - g_settings_set(prefs_settings, "css-file", "ms", NULL); - } else { - g_settings_set(prefs_settings, "css-file", "ms", filename); - } + g_settings_set(theapp->prefs_settings, "css-file", "ms", filename); g_free(filename); } void on_resource_file_set(GtkFileChooserButton *button, ChimaraGlk *glk) { - extern GSettings *prefs_settings; + ChimaraApp *theapp = chimara_app_get(); char *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(button) ); - g_settings_set(prefs_settings, "resource-path", "ms", filename); + g_settings_set(theapp->prefs_settings, "resource-path", "ms", filename); g_free(filename); } void on_interpreter_cell_changed(GtkCellRendererCombo *combo, char *path_string, GtkTreeIter *new_iter, ChimaraGlk *glk) { - unsigned int format, interpreter; - format = (unsigned int)strtol(path_string, NULL, 10); - GtkTreeModel *combo_model; - g_object_get(combo, "model", &combo_model, NULL); - char *combo_string = gtk_tree_model_get_string_from_iter(combo_model, new_iter); - interpreter = (unsigned int)strtol(combo_string, NULL, 10); - g_free(combo_string); + //unsigned int format, interpreter; + //format = (unsigned int)strtol(path_string, NULL, 10); + //GtkTreeModel *combo_model; + //g_object_get(combo, "model", &combo_model, NULL); + //char *combo_string = gtk_tree_model_get_string_from_iter(combo_model, new_iter); + //interpreter = (unsigned int)strtol(combo_string, NULL, 10); + //g_free(combo_string); - chimara_if_set_preferred_interpreter(CHIMARA_IF(glk), format, interpreter); + //chimara_if_set_preferred_interpreter(CHIMARA_IF(glk), format, interpreter); /* Display the new setting in the list */ - GtkTreeIter iter; - GtkTreePath *path = gtk_tree_path_new_from_string(path_string); - gtk_tree_model_get_iter(GTK_TREE_MODEL(preferred_list), &iter, path); - gtk_tree_path_free(path); - gtk_list_store_set(preferred_list, &iter, - 1, interpreter_to_display_string(interpreter), - -1); + //GtkTreeIter iter; + //GtkTreePath *path = gtk_tree_path_new_from_string(path_string); + //gtk_tree_model_get_iter(GTK_TREE_MODEL(preferred_list), &iter, path); + //gtk_tree_path_free(path); + //gtk_list_store_set(preferred_list, &iter, + // 1, interpreter_to_display_string(interpreter), + // -1); /* Save the new settings in the preferences file */ - extern GSettings *prefs_settings; - GVariantBuilder *builder = g_variant_builder_new( G_VARIANT_TYPE("a{ss}") ); - unsigned int count; - for(count = 0; count < CHIMARA_IF_NUM_FORMATS; count++) { - g_variant_builder_add(builder, "{ss}", - format_to_string(count), - interpreter_to_string(chimara_if_get_preferred_interpreter(CHIMARA_IF(glk), count))); - } - g_settings_set(prefs_settings, "preferred-interpreters", "a{ss}", builder); - g_variant_builder_unref(builder); + //ChimaraApp *theapp = chimara_app_get(); + //GVariantBuilder *builder = g_variant_builder_new( G_VARIANT_TYPE("a{ss}") ); + //unsigned int count; + //for(count = 0; count < CHIMARA_IF_NUM_FORMATS; count++) { + // g_variant_builder_add(builder, "{ss}", + // format_to_string(count), + // interpreter_to_string(chimara_if_get_preferred_interpreter(CHIMARA_IF(glk), count))); + //} + //g_settings_set(theapp->prefs_settings, "preferred-interpreters", "a{ss}", builder); + //g_variant_builder_unref(builder); } diff --git a/player/preferences.h b/player/preferences.h index 9a1fad0..243de18 100644 --- a/player/preferences.h +++ b/player/preferences.h @@ -1,9 +1,62 @@ -#ifndef PREFERENCES_H -#define PREFERENCES_H +/* + * Copyright (C) 2008, 2009, 2010, 2011 Philip Chimento and Marijn van Vliet. + * All rights reserved. + * + * Chimara is free software copyrighted by Philip Chimento and Marijn van Vliet. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither of the names Philip Chimento or Marijn van Vliet, nor the name of + * any other contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __PREFERENCES_H__ +#define __PREFERENCES_H__ + +#include #include -#include -G_GNUC_INTERNAL void preferences_create(ChimaraGlk *glk); +G_BEGIN_DECLS + +#define CHIMARA_TYPE_PREFS (chimara_prefs_get_type()) +#define CHIMARA_PREFS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CHIMARA_TYPE_PREFS, ChimaraPrefs)) +#define CHIMARA_PREFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CHIMARA_TYPE_PREFS, ChimaraPrefsClass)) +#define CHIMARA_IS_PREFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CHIMARA_TYPE_PREFS)) +#define CHIMARA_IS_PREFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CHIMARA_TYPE_PREFS)) +#define CHIMARA_PREFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CHIMARA_TYPE_PREFS, ChimaraPrefsClass)) + +typedef struct _ChimaraPrefs { + GtkDialog parent_instance; + + /* Public pointers */ +} ChimaraPrefs; + +typedef struct _ChimaraPrefsClass { + GtkDialogClass parent_class; +} ChimaraPrefsClass; + +GType chimara_prefs_get_type(void) G_GNUC_CONST; +GtkWidget *chimara_prefs_new(void); + +G_END_DECLS -#endif +#endif /* __PREFERENCES_H__ */ diff --git a/player/util.c b/player/util.c new file mode 100644 index 0000000..70d1ed5 --- /dev/null +++ b/player/util.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2008, 2009, 2010, 2011 Philip Chimento and Marijn van Vliet. + * All rights reserved. + * + * Chimara is free software copyrighted by Philip Chimento and Marijn van Vliet. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither of the names Philip Chimento or Marijn van Vliet, nor the name of + * any other contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include "util.h" +#include "error.h" + +char * +get_data_file_path(const char *filename) +{ + char *path = g_build_filename(PACKAGE_DATA_DIR, filename, NULL); + if(g_file_test(path, G_FILE_TEST_EXISTS)) + return path; +#ifdef DEBUG + g_free(path); + path = g_build_filename(PACKAGE_SRC_DIR, filename, NULL); + if(g_file_test(path, G_FILE_TEST_EXISTS)) + return path; +#endif /* DEBUG */ + g_error("Could not find data file: %s", filename); +} + +GtkBuilder * +new_builder_with_objects(char **object_ids) +{ + GError *error = NULL; + GtkBuilder *builder = gtk_builder_new(); + + if( !gtk_builder_add_objects_from_file(builder, PACKAGE_DATA_DIR "/chimara.ui", object_ids, &error) ) { +#ifdef DEBUG + g_error_free(error); + error = NULL; + if( !gtk_builder_add_objects_from_file(builder, PACKAGE_SRC_DIR "/chimara.ui", object_ids, &error) ) +#endif /* DEBUG */ + goto fail; + } + return builder; + +fail: + error_dialog(NULL, error, _("Error while building interface: ")); + return NULL; +} + +GObject * +load_object(GtkBuilder *builder, const char *name) +{ + GObject *retval; + if( (retval = gtk_builder_get_object(builder, name)) == NULL) { + error_dialog(NULL, NULL, "Error while getting object '%s'", name); + g_error("Error while getting object '%s'", name); + } + return retval; +} + +GtkUIManager * +new_ui_manager(const char *filename) +{ + GError *error = NULL; + GtkUIManager *uimanager = gtk_ui_manager_new(); + char *path = g_build_filename(PACKAGE_DATA_DIR, filename, NULL); + + if( !gtk_ui_manager_add_ui_from_file(uimanager, path, &error) ) { +#ifdef DEBUG + g_free(path); + path = g_build_filename(PACKAGE_SRC_DIR, filename, NULL); + g_error_free(error); + error = NULL; + if( !gtk_ui_manager_add_ui_from_file(uimanager, path, &error) ) +#endif /* DEBUG */ + goto fail; + } + return uimanager; + +fail: + error_dialog(NULL, error, _("Error while building interface: ")); + return NULL; +} + diff --git a/player/util.h b/player/util.h new file mode 100644 index 0000000..73bed8c --- /dev/null +++ b/player/util.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008, 2009, 2010, 2011 Philip Chimento and Marijn van Vliet. + * All rights reserved. + * + * Chimara is free software copyrighted by Philip Chimento and Marijn van Vliet. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither of the names Philip Chimento or Marijn van Vliet, nor the name of + * any other contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include +#include + +G_BEGIN_DECLS + +char *get_data_file_path(const char *filename); +GtkBuilder *new_builder_with_objects(char **object_ids); +GObject *load_object(GtkBuilder *builder, const char *name); +GtkUIManager *new_ui_manager(const char *filename); + +G_END_DECLS + +#endif /* __UTIL_H__ */