From: Philip Chimento Date: Sat, 12 Dec 2009 19:52:38 +0000 (+0000) Subject: Improve player X-Git-Url: https://git.stderr.nl/gitweb?a=commitdiff_plain;h=4b1516b78e364cd664271d0ada1d2de4777499ef;p=rodin%2Fchimara.git Improve player git-svn-id: http://lassie.dyndns-server.com/svn/gargoyle-gtk@205 ddfedd41-794f-dd11-ae45-00112f111e67 --- diff --git a/player/callbacks.c b/player/callbacks.c index a4c81a1..38629fe 100644 --- a/player/callbacks.c +++ b/player/callbacks.c @@ -35,11 +35,18 @@ #include #include #include +#include #include "error.h" -void -on_open_activate(GtkAction *action, ChimaraGlk *glk) +/* 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)) { @@ -53,13 +60,23 @@ on_open_activate(GtkAction *action, ChimaraGlk *glk) 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; + return FALSE; chimara_glk_stop(glk); chimara_glk_wait(glk); } + return TRUE; +} + +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, @@ -70,8 +87,24 @@ on_open_activate(GtkAction *action, ChimaraGlk *glk) if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { GError *error = NULL; gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - if(!chimara_if_run_game(CHIMARA_IF(glk), filename, &error)) - error_dialog(window, error, _("Could not open game file.")); + 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; + } + + /* 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); @@ -80,7 +113,36 @@ on_open_activate(GtkAction *action, ChimaraGlk *glk) 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); + g_free(uri); + return; + } + + if(!confirm_open_new_game(glk)) { + g_free(filename); + g_free(uri); + return; + } + + if(!chimara_if_run_game(CHIMARA_IF(glk), filename, &error)) { + error_dialog(window, error, _("Could not open game file '%s': "), filename); + g_free(filename); + g_free(uri); + return; + } + g_free(filename); + + /* 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); + + g_free(uri); } void @@ -95,28 +157,31 @@ on_quit_chimara_activate(GtkAction *action, ChimaraGlk *glk) gtk_main_quit(); } -void -on_cut_activate(GtkAction *action, ChimaraGlk *glk) -{ - -} - 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 @@ -152,7 +217,9 @@ on_quit_activate(GtkAction *action, ChimaraGlk *glk) 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 diff --git a/player/chimara.menus b/player/chimara.menus index 3127088..ec43fb9 100644 --- a/player/chimara.menus +++ b/player/chimara.menus @@ -9,7 +9,6 @@ - diff --git a/player/chimara.ui b/player/chimara.ui index ce47531..b008878 100644 --- a/player/chimara.ui +++ b/player/chimara.ui @@ -84,12 +84,6 @@ gtk-media-stop - - Cu_t - Cut the selection - gtk-cut - - _Copy Copy the selection @@ -118,4 +112,280 @@ gtk-about + + 5 + About Chimara + center + dialog + False + Chimara + © 2008–2009 Marijn van Vliet and Philip Chimento + Interactive Fiction Player + Copyright (C) 2008, 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. + + Marijn van Vliet +Philip Chimento + + + + + True + vertical + 2 + + + + + + True + end + + + False + end + 0 + + + + + + + 5 + Chimara Preferences + center + dialog + + + + + True + vertical + 9 + + + True + vertical + 12 + + + True + 0 + none + + + True + 12 + + + True + vertical + 8 + + + _Awesome mode + True + True + False + True + True + + + False + False + 0 + + + + + _Super-awesome mode + True + True + False + True + True + + + False + False + 1 + + + + + _Ludicrous mode + True + True + False + True + True + + + False + False + 2 + + + + + + + + + True + <b>Miscellaneous options</b> + True + + + + + 0 + + + + + True + 0 + none + + + True + 12 + + + True + vertical + + + True + True + automatic + automatic + + + True + True + + + + + 0 + + + + + True + 7 + end + + + gtk-add + True + True + True + True + + + False + False + 0 + + + + + gtk-remove + True + True + True + True + + + False + False + 1 + + + + + 1 + + + + + + + + + True + <b>Styles</b> + True + + + + + 1 + + + + + 1 + + + + + True + end + + + gtk-close + True + True + True + True + + + + False + False + 0 + + + + + False + end + 0 + + + + + + button1 + + diff --git a/player/main.c b/player/main.c index 9827d31..c032849 100644 --- a/player/main.c +++ b/player/main.c @@ -44,11 +44,15 @@ #include #include -/* Global pointers to widgets */ -GtkBuilder *builder = NULL; -GtkUIManager *uimanager = NULL; -GtkWidget *window = NULL; -GtkWidget *glk = NULL; +/* Static global pointers to widgets */ +static GtkBuilder *builder = NULL; +static GtkUIManager *uimanager = NULL; +static GtkWidget *window = NULL; +static GtkWidget *glk = NULL; + +/* Global global pointers */ +GtkWidget *aboutwindow = NULL; +GtkWidget *prefswindow = NULL; static GObject * load_object(const gchar *name) @@ -73,6 +77,8 @@ create_window(void) } 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")); /* Add all the actions to the action group. This for-loop is a temporary fix @@ -91,7 +97,6 @@ create_window(void) "restart", "", "quit", "", "edit", "", - "cut", NULL, "copy", NULL, "paste", NULL, "preferences", "", @@ -102,6 +107,16 @@ create_window(void) const gchar **ptr; for(ptr = actions; *ptr; ptr += 2) gtk_action_group_add_action_with_accel(actiongroup, GTK_ACTION(load_object(ptr[0])), ptr[1]); + 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_SRC_DIR "/chimara.menus", &error) ) {