From b397495e945570aaacee0eb8fa25704d03761401 Mon Sep 17 00:00:00 2001 From: rodin Date: Sun, 23 May 2010 10:48:12 +0000 Subject: [PATCH] Showing off dynamic styles: started work on preferences dialog. New appearance cannot be saved or loaded yet. --- libchimara/chimara-glk.c | 97 ++++++++ libchimara/chimara-glk.h | 9 + libchimara/style.c | 27 +- libchimara/style.h | 4 + player/Makefile.am | 4 +- player/chimara.ui | 514 +++++++++++++++++++++++++++++++-------- player/main.c | 28 ++- player/preferences.c | 237 ++++++++++++++++++ player/preferences.h | 9 + 9 files changed, 813 insertions(+), 116 deletions(-) create mode 100644 player/preferences.c create mode 100644 player/preferences.h diff --git a/libchimara/chimara-glk.c b/libchimara/chimara-glk.c index 6254602..497f862 100644 --- a/libchimara/chimara-glk.c +++ b/libchimara/chimara-glk.c @@ -22,6 +22,7 @@ #include "glkunix.h" #include "init.h" #include "magic.h" +#include "style.h" #define CHIMARA_GLK_MIN_WIDTH 0 #define CHIMARA_GLK_MIN_HEIGHT 0 @@ -1372,3 +1373,99 @@ chimara_glk_feed_line_input(ChimaraGlk *glk, const gchar *text) g_async_queue_push(priv->line_input_queue, g_strdup(text)); event_throw(glk, evtype_ForcedLineInput, NULL, 0, 0); } + +/** + * chimara_glk_get_tag: + * @glk: a #ChimarGlk widget + * @window: The type of window to retrieve the tag for + * @name: The name of the tag to retrieve + * + * Use this function to get a #GtkTextTag so style properties can be changed. + * See also #chimara_glk_set_css_from_string. + * + * The layout of the text in Chimara is controlled by two sets of tags: one set + * describing the style in text buffers and one for text grids. See also the + * GLK specification for the difference between the two. The main narrative of + * a game is usually rendered in text buffers, whereas text grids are mostly + * used for status bars and in game menus. + * + * The following tag names are supported: + * + * normal + * emphasized + * preformatted + * header + * subheader + * alert + * note + * block-quote + * input + * user1 + * user2 + * hyperlink + * pager + * + */ +GtkTextTag* +chimara_glk_get_tag(ChimaraGlk *glk, ChimaraGlkWindowType window, const gchar *name) +{ + CHIMARA_GLK_USE_PRIVATE(glk, priv); + + switch(window) { + case CHIMARA_GLK_TEXT_BUFFER: + return GTK_TEXT_TAG( g_hash_table_lookup(priv->styles->text_buffer, name) ); + break; + case CHIMARA_GLK_TEXT_GRID: + return GTK_TEXT_TAG( g_hash_table_lookup(priv->styles->text_grid, name) ); + break; + default: + ILLEGAL_PARAM("Unknown window type: %u", window); + return NULL; + } +} + +/** + * chimara_glk_get_tag: + * @glk: a #ChimarGlk widget + * + * Retrieves the possible tag names to use in #chimara_glk_get_tag. + */ +const gchar** +chimara_glk_get_tag_names(ChimaraGlk *glk) +{ + return style_get_tag_names(); +} + +/** + * chimara_glk_get_num_tag_names: + * @glk: a #ChimaraGlk widget + * + * Retrieves the number of style tags returned by #chimara_glk_get_tag_names. + */ +gint +chimara_glk_get_num_tag_names(ChimaraGlk *glk) +{ + return CHIMARA_NUM_STYLES; +} + +/** + * chimara_glk_update_style: + * @glk: a #ChimaraGlk widget + * + * Processes style updates and updates the widget to reflect the new style. + * Call this every time you change a property of a #GtkTextTag retrieved by + * #chimara_glk_get_tag. + */ +void +chimara_glk_update_style(ChimaraGlk *glk) +{ + CHIMARA_GLK_USE_PRIVATE(glk, priv); + style_update(glk); + + /* Schedule a redraw */ + g_mutex_lock(priv->arrange_lock); + priv->needs_rearrange = TRUE; + priv->ignore_next_arrange_event = TRUE; + g_mutex_unlock(priv->arrange_lock); + gtk_widget_queue_resize( GTK_WIDGET(priv->self) ); +} diff --git a/libchimara/chimara-glk.h b/libchimara/chimara-glk.h index 8eca95f..df6aaef 100644 --- a/libchimara/chimara-glk.h +++ b/libchimara/chimara-glk.h @@ -39,6 +39,11 @@ typedef struct _ChimaraGlkClass { void(* iliad_screen_update) (ChimaraGlk *self, gboolean typing); } ChimaraGlkClass; +typedef enum { + CHIMARA_GLK_TEXT_BUFFER, + CHIMARA_GLK_TEXT_GRID +} ChimaraGlkWindowType; + /** * ChimaraError: * @CHIMARA_LOAD_MODULE_ERROR: There was an error opening the plugin containing @@ -86,6 +91,10 @@ void chimara_glk_wait(ChimaraGlk *glk); gboolean chimara_glk_get_running(ChimaraGlk *glk); void chimara_glk_feed_char_input(ChimaraGlk *glk, guint32 keyval); void chimara_glk_feed_line_input(ChimaraGlk *glk, const gchar *text); +GtkTextTag *chimara_glk_get_tag(ChimaraGlk *glk, ChimaraGlkWindowType window, const gchar *name); +const gchar **chimara_glk_get_tag_names(ChimaraGlk *glk); +gint chimara_glk_get_num_tag_names(ChimaraGlk *glk); +void chimara_glk_update_style(ChimaraGlk *glk); G_END_DECLS diff --git a/libchimara/style.c b/libchimara/style.c index 14ca359..a466cdd 100644 --- a/libchimara/style.c +++ b/libchimara/style.c @@ -38,7 +38,6 @@ glk_set_style(glui32 styl) glk_set_style_stream(glk_data->current_stream, styl); } -#define NUM_STYLES 13 static const gchar* TAG_NAMES[] = { "normal", "emphasized", @@ -69,11 +68,17 @@ static const gchar* GLK_TAG_NAMES[] = { "glk-user2" }; +const gchar** +style_get_tag_names() +{ + return TAG_NAMES; +} + /* Internal function: mapping from style enum to tag name */ -static gchar* +static const gchar* get_tag_name(glui32 style) { - if(style >= NUM_STYLES) { + if(style >= CHIMARA_NUM_STYLES) { WARNING("Unsupported style"); return "normal"; } else { @@ -82,7 +87,7 @@ get_tag_name(glui32 style) } /* Internal function: mapping from glk style enum to tag name */ -static gchar* +static const gchar* get_glk_tag_name(glui32 style) { if(style >= style_NUMSTYLES) { @@ -106,8 +111,8 @@ glk_set_style_stream(strid_t str, glui32 styl) { return; flush_window_buffer(str->window); - str->style = get_tag_name(styl); - str->glk_style = get_glk_tag_name(styl); + str->style = (gchar*) get_tag_name(styl); + str->glk_style = (gchar*) get_glk_tag_name(styl); } /* Internal function: call this to initialize the layout of the 'more' prompt. */ @@ -1120,3 +1125,13 @@ text_tag_to_attr_list(GtkTextTag *tag, PangoAttrList *list) ); } } + +/* Update pager and reverse video tags */ +void +style_update(ChimaraGlk *glk) +{ + CHIMARA_GLK_USE_PRIVATE(glk, priv); + + GtkTextTag *pager_tag = GTK_TEXT_TAG( g_hash_table_lookup(priv->styles->text_buffer, "pager") ); + text_tag_to_attr_list(pager_tag, priv->pager_attr_list); +} diff --git a/libchimara/style.h b/libchimara/style.h index ea27c9a..5766f84 100644 --- a/libchimara/style.h +++ b/libchimara/style.h @@ -10,6 +10,8 @@ G_GNUC_INTERNAL void style_init_textbuffer(GtkTextBuffer *buffer); G_GNUC_INTERNAL void style_init_textgrid(GtkTextBuffer *buffer); G_GNUC_INTERNAL void style_init_more_prompt(winid_t win); G_GNUC_INTERNAL void style_init(ChimaraGlk *glk); +G_GNUC_INTERNAL void style_update(ChimaraGlk *glk); +G_GNUC_INTERNAL const gchar** style_get_tag_names(); G_GNUC_INTERNAL void reset_default_styles(ChimaraGlk *glk); /*G_GNUC_INTERNAL void copy_default_styles_to_current_styles(ChimaraGlk *glk);*/ G_GNUC_INTERNAL GScanner *create_css_file_scanner(void); @@ -23,4 +25,6 @@ typedef struct StyleSet { GHashTable *text_buffer; } StyleSet; +#define CHIMARA_NUM_STYLES 13 + #endif diff --git a/player/Makefile.am b/player/Makefile.am index dc446e7..ebc4c93 100644 --- a/player/Makefile.am +++ b/player/Makefile.am @@ -5,7 +5,7 @@ PLUGIN_LIBTOOL_FLAGS=-module -avoid-version -export-symbols-regex "^glk_main$$" if TARGET_ILIAD -chimara_iliad_SOURCES = iliad.c +chimara_iliad_SOURCES = iliad.c xepdmgrclient.c xepdmgrclient.h chimara_iliad_CFLAGS = @TEST_CFLAGS@ $(AM_CFLAGS) chimara_iliad_LDADD = @TEST_LIBS@ $(top_builddir)/libchimara/libchimara.la @@ -16,7 +16,7 @@ else dist_pkgdata_DATA = chimara.ui chimara.menus style.css bin_PROGRAMS = chimara -chimara_SOURCES = main.c callbacks.c error.c error.h +chimara_SOURCES = main.c callbacks.c preferences.c preferences.h error.c error.h chimara_CPPFLAGS = $(AM_CPPFLAGS) \ -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ -DPACKAGE_SRC_DIR=\""$(srcdir)"\" \ diff --git a/player/chimara.ui b/player/chimara.ui index b008878..b7176c9 100644 --- a/player/chimara.ui +++ b/player/chimara.ui @@ -1,6 +1,6 @@ - + Chimara @@ -10,7 +10,6 @@ True - vertical @@ -62,8 +61,8 @@ Open _Recent - 10 mru + 10 @@ -156,7 +155,6 @@ Philip Chimento True - vertical 2 @@ -185,111 +183,101 @@ Philip Chimento True - vertical 9 - + True - vertical - 12 + True + + + True + + + + + True + Environment + + + False + + - + True - 0 - none - + True - 12 + 2 - + 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 - - + 1 + 5 + Load layout from this CSS file: + + + GTK_FILL + + + + + 250 + True + Select A CSS File + + 1 + 2 + + + False + 0 + - - + + True - <b>Miscellaneous options</b> - True + + False + 5 + 1 + - - - 0 - - - - - True - 0 - none - + True - 12 - + + True + 0 + 5 + Select a style to edit: + + + False + 0 + + + + True - vertical + 163 True True - automatic + never automatic - + True True + False + False @@ -298,35 +286,213 @@ Philip Chimento - + True - 7 - end - - gtk-add + True - True - True - True + + + True + Font: + + + False + 5 + 0 + + + + + True + True + True + + + + 1 + + False - False 0 - - gtk-remove + + 130 True - True - True - True + + + 40 + 30 + True + True + True + #000000000000 + + + + 125 + 10 + + + + + True + 5 + Foreground color: + + + 4 + 17 + + + + + True + Background color: + + + 6 + 52 + + + + + 40 + 30 + True + True + True + #ffffffffffff + + + + 125 + 45 + + + + + 283 + 50 + True + icons + + + True + align-left + True + Align _left + True + gtk-justify-left + + + False + True + + + + + True + align-center + Align _center + True + gtk-justify-center + + + False + True + + + + + True + align-right + True + Align _right + True + gtk-justify-right + + + False + True + + + + + True + align-justify + True + Align _justify + True + gtk-justify-fill + + + False + True + + + + + True + + + False + True + + + + + True + bold + True + _Bold + True + gtk-bold + + + False + True + + + + + True + italic + True + _Italic + True + gtk-italic + + + False + True + + + + + True + underline + True + _Underline + True + gtk-underline + + + False + True + + + + + 86 + + - False - False 1 @@ -336,24 +502,90 @@ Philip Chimento + + 5 + 1 + + + 5 + 2 + + + + + 30 + True + 0 + 1 + 5 + Example text: + + + False + 3 + - - + + + 100 True - <b>Styles</b> - True + True + False + word-char + 10 + 10 + + 4 + 1 + + + True + Layout + + + 1 + False + + + + + True + + + + + + + + + + + + 2 + + + + + True + Interpreters + + + 2 + False + + - 1 + 2 @@ -362,6 +594,33 @@ Philip Chimento end + gtk-save + True + True + True + True + + + False + False + 0 + + + + + Reset + True + True + True + + + False + False + 1 + + + + gtk-close True True @@ -372,7 +631,7 @@ Philip Chimento False False - 0 + 2 @@ -386,6 +645,55 @@ Philip Chimento button1 + button2 + button-close + + + Align _left + Align _left + Align text to the left + gtk-justify-left + + + + Align _justify + Align _justify + Justify the text + gtk-justify-fill + + + + Align _right + Align _right + Align text to the right + gtk-justify-right + + + + _Bold + _Bold + Make the text bold + gtk-bold + + + + _Italic + _Italic + Print the text in italics + gtk-italic + + + + _Underline + _Underline + Underline the text + gtk-underline + + + + gtk-justify-center + + diff --git a/player/main.c b/player/main.c index 962ca30..3586ca1 100644 --- a/player/main.c +++ b/player/main.c @@ -44,17 +44,19 @@ #include #include +#include "preferences.h" + /* Static global pointers to widgets */ -static GtkBuilder *builder = NULL; static GtkUIManager *uimanager = NULL; static GtkWidget *window = NULL; static GtkWidget *glk = NULL; /* Global global pointers */ +GtkBuilder *builder = NULL; GtkWidget *aboutwindow = NULL; GtkWidget *prefswindow = NULL; -static GObject * +GObject * load_object(const gchar *name) { GObject *retval; @@ -108,6 +110,7 @@ create_window(void) aboutwindow = GTK_WIDGET(load_object("aboutwindow")); prefswindow = GTK_WIDGET(load_object("prefswindow")); GtkActionGroup *actiongroup = GTK_ACTION_GROUP(load_object("actiongroup")); + GtkActionGroup *style_actiongroup = GTK_ACTION_GROUP(load_object("style-actiongroup")); /* Add all the actions to the action group. This for-loop is a temporary fix and can be removed once Glade supports adding actions and accelerators to an @@ -132,9 +135,20 @@ create_window(void) "about", "", NULL }; + const gchar *style_actions[] = { + "align-left", + "align-justify", + "align-right", + "bold", + "italic", + "underline", + NULL + }; 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]); + for(ptr = style_actions; *ptr; ptr ++) + gtk_action_group_add_action(style_actiongroup, GTK_ACTION(load_object(*ptr))); GtkRecentFilter *filter = gtk_recent_filter_new(); /* TODO: Use mimetypes and construct the filter dynamically depending on what plugins are installed */ @@ -189,15 +203,18 @@ create_window(void) gtk_ui_manager_insert_action_group(uimanager, actiongroup, 0); GtkWidget *menubar = gtk_ui_manager_get_widget(uimanager, "/menubar"); - GtkWidget *toolbar = gtk_ui_manager_get_widget(uimanager, "/toolbar"); + //GtkWidget *toolbar = gtk_ui_manager_get_widget(uimanager, "/toolbar"); 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_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)); } int @@ -219,7 +236,6 @@ main(int argc, char *argv[]) create_window(); gtk_widget_show_all(window); - g_object_unref( G_OBJECT(builder) ); g_object_unref( G_OBJECT(uimanager) ); if(argc >= 2) { @@ -236,5 +252,7 @@ main(int argc, char *argv[]) chimara_glk_stop(CHIMARA_GLK(glk)); chimara_glk_wait(CHIMARA_GLK(glk)); + g_object_unref( G_OBJECT(builder) ); + return 0; } diff --git a/player/preferences.c b/player/preferences.c new file mode 100644 index 0000000..b7cc3ad --- /dev/null +++ b/player/preferences.c @@ -0,0 +1,237 @@ +/* -*- 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. + * + * 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. + * + * 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 + * 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" + +GObject *load_object(const gchar *name); +static GtkTextTag *current_tag; + +static void style_tree_select_callback(GtkTreeSelection *selection, ChimaraGlk *glk); + +/* Create the preferences dialog. */ +void +preferences_create(ChimaraGlk *glk) +{ + /* Initialize the tree of style names */ + GtkTreeStore *style_list = gtk_tree_store_new(1, G_TYPE_STRING); + GtkTreeIter buffer, grid, buffer_child, grid_child; + + gtk_tree_store_append(style_list, &buffer, NULL); + gtk_tree_store_append(style_list, &grid, NULL); + gtk_tree_store_set(style_list, &buffer, 0, "Text buffer", -1); + gtk_tree_store_set(style_list, &grid, 0, "Text grid", -1); + + int i; + gint num_tags = chimara_glk_get_num_tag_names(glk); + const gchar **tag_names = chimara_glk_get_tag_names(glk); + for(i=0; i +#include + +G_GNUC_INTERNAL void preferences_create(ChimaraGlk *glk); + +#endif -- 2.30.2