From 2b2a139a94c932d50a5ad5a5ab91f997493e5b5a Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 17 Oct 2018 14:50:28 +0200 Subject: Switch to new Stylesheet type --- meson.build | 1 + src/narrative_window.c | 36 +++----- src/presentation.c | 56 +----------- src/presentation.h | 5 +- src/render.c | 6 +- src/render.h | 4 +- src/sc_editor.c | 4 +- src/sc_editor.h | 7 +- src/stylesheet.c | 91 ++++++++++++++++++++ src/stylesheet.h | 36 ++++++++ src/stylesheet_editor.c | 224 ++---------------------------------------------- 11 files changed, 160 insertions(+), 310 deletions(-) create mode 100644 src/stylesheet.c create mode 100644 src/stylesheet.h diff --git a/meson.build b/meson.build index 818c34d..52b9243 100644 --- a/meson.build +++ b/meson.build @@ -45,6 +45,7 @@ executable('colloquium', 'src/print.c', 'src/sc_parse.c', 'src/utils.c', + 'src/stylesheet.c', 'src/stylesheet_editor.c', ], gresources, diff --git a/src/narrative_window.c b/src/narrative_window.c index 1631f2f..7a19562 100644 --- a/src/narrative_window.c +++ b/src/narrative_window.c @@ -185,7 +185,7 @@ static void delete_slide_sig(GSimpleAction *action, GVariant *parameter, } -static struct template_id *get_templates(SCBlock *ss, int *n) +static struct template_id *get_templates(Stylesheet *ss, int *n) { /* FIXME: From JSON stylesheet */ *n = 0; @@ -210,7 +210,7 @@ static void update_template_menus(NarrativeWindow *nw) } -static SCBlock *get_slide_template(SCBlock *ss) +static SCBlock *get_slide_template(Stylesheet *ss) { struct template_id *templates; int i, n_templates; @@ -244,36 +244,20 @@ static gint load_ss_response_sig(GtkWidget *d, gint response, if ( response == GTK_RESPONSE_ACCEPT ) { char *filename; - char *stext; + Stylesheet *new_ss; filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d)); - printf("Loading %s\n",filename); - stext = load_everything(filename); - if ( stext != NULL ) { + new_ss = stylesheet_load(filename); + if ( new_ss != NULL ) { - SCBlock *bl; - SCBlock *ss; - bl = sc_parse(stext); - free(stext); - ss = find_stylesheet(bl); + stylesheet_free(nw->p->stylesheet); + nw->p->stylesheet = new_ss; + sc_editor_set_stylesheet(nw->sceditor, new_ss); - if ( ss != NULL ) { + /* Full rerender */ + sc_editor_set_scblock(nw->sceditor, nw->dummy_top); - /* Substitute the style sheet in - * presentation Storycode */ - replace_stylesheet(nw->p, ss); - - sc_editor_set_stylesheet(nw->sceditor, ss); - - /* Full rerender, first block may have - * changed */ - sc_editor_set_scblock(nw->sceditor, - nw->dummy_top); - - } else { - fprintf(stderr, _("Not a style sheet\n")); - } } else { fprintf(stderr, _("Failed to load\n")); } diff --git a/src/presentation.c b/src/presentation.c index b3676b5..c3f0d07 100644 --- a/src/presentation.c +++ b/src/presentation.c @@ -226,59 +226,6 @@ SCBlock *prev_slide(struct presentation *p, SCBlock *sl) } -int replace_stylesheet(struct presentation *p, SCBlock *ss) -{ - /* Create style sheet from union of old and new, - * preferring items from the new one */ - - /* If there was no stylesheet before, add a dummy one */ - if ( p->stylesheet == NULL ) { - p->stylesheet = sc_block_append_end(p->scblocks, - "stylesheet", NULL, NULL); - } - - /* Cut the old stylesheet out of the presentation, - * and put in the new one */ - sc_block_substitute(&p->scblocks, p->stylesheet, ss); - p->stylesheet = ss; - - return 0; -} - - -SCBlock *find_stylesheet(SCBlock *bl) -{ - while ( bl != NULL ) { - - const char *name = sc_block_name(bl); - - if ( (name != NULL) && (strcmp(name, "stylesheet") == 0) ) { - return bl; - } - - bl = sc_block_next(bl); - - } - - return NULL; -} - - -static void install_stylesheet(struct presentation *p) -{ - if ( p->stylesheet != NULL ) { - fprintf(stderr, _("Duplicate style sheet!\n")); - return; - } - - p->stylesheet = find_stylesheet(p->scblocks); - - if ( p->stylesheet == NULL ) { - fprintf(stderr, _("No style sheet.\n")); - } -} - - static void set_slide_size_from_stylesheet(struct presentation *p) { /* FIXME: From JSON */ @@ -310,7 +257,8 @@ int load_presentation(struct presentation *p, GFile *file) return r; /* Error */ } - install_stylesheet(p); + p->stylesheet = stylesheet_load("stylesheet.json"); /* FIXME: ! */ + set_slide_size_from_stylesheet(p); assert(p->uri == NULL); diff --git a/src/presentation.h b/src/presentation.h index ed8a188..ea3780e 100644 --- a/src/presentation.h +++ b/src/presentation.h @@ -34,6 +34,7 @@ struct presentation; #include "slideshow.h" #include "narrative_window.h" #include "slide_window.h" +#include "stylesheet.h" struct menu_pl; @@ -56,15 +57,13 @@ struct presentation double slide_width; double slide_height; - SCBlock *stylesheet; SCBlock *scblocks; + Stylesheet *stylesheet; }; extern struct presentation *new_presentation(const char *imagestore); -extern SCBlock *find_stylesheet(SCBlock *bl); -extern int replace_stylesheet(struct presentation *p, SCBlock *ss); extern void free_presentation(struct presentation *p); extern char *get_titlebar_string(struct presentation *p); diff --git a/src/render.c b/src/render.c index 0228a7b..041f812 100644 --- a/src/render.c +++ b/src/render.c @@ -176,7 +176,7 @@ int recursive_wrap(struct frame *fr, PangoContext *pc) } -struct frame *interp_and_shape(SCBlock *scblocks, SCBlock *stylesheet, +struct frame *interp_and_shape(SCBlock *scblocks, Stylesheet *stylesheet, SCCallbackList *cbl, ImageStore *is, int slide_number, PangoContext *pc, double w, double h, @@ -227,7 +227,7 @@ struct frame *interp_and_shape(SCBlock *scblocks, SCBlock *stylesheet, static struct frame *render_sc_with_context(SCBlock *scblocks, cairo_t *cr, double log_w, double log_h, - SCBlock *stylesheet, SCCallbackList *cbl, + Stylesheet *stylesheet, SCCallbackList *cbl, ImageStore *is, int slide_number, PangoLanguage *lang, PangoContext *pc) @@ -251,7 +251,7 @@ static struct frame *render_sc_with_context(SCBlock *scblocks, cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h, double log_w, double log_h, - SCBlock *stylesheet, SCCallbackList *cbl, + Stylesheet *stylesheet, SCCallbackList *cbl, ImageStore *is, int slide_number, struct frame **ptop, PangoLanguage *lang) diff --git a/src/render.h b/src/render.h index aadb033..0cfae26 100644 --- a/src/render.h +++ b/src/render.h @@ -35,7 +35,7 @@ /* Convienience function to run the entire pipeline */ extern cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h, double log_w, double log_h, - SCBlock *stylesheet, SCCallbackList *cbl, + Stylesheet *stylesheet, SCCallbackList *cbl, ImageStore *is, int slide_number, struct frame **ptop, PangoLanguage *lang); @@ -44,7 +44,7 @@ extern cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h, * Needs to be followed by: wrap_contents() (recursively) * recursive_draw() */ -extern struct frame *interp_and_shape(SCBlock *scblocks, SCBlock *stylesheet, +extern struct frame *interp_and_shape(SCBlock *scblocks, Stylesheet *stylesheet, SCCallbackList *cbl, ImageStore *is, int slide_number, PangoContext *pc, diff --git a/src/sc_editor.c b/src/sc_editor.c index 999f919..0431b7b 100644 --- a/src/sc_editor.c +++ b/src/sc_editor.c @@ -2033,7 +2033,7 @@ void sc_editor_set_top_frame_editable(SCEditor *e, int top_frame_editable) } -void sc_editor_set_stylesheet(SCEditor *e, SCBlock *stylesheet) +void sc_editor_set_stylesheet(SCEditor *e, Stylesheet *stylesheet) { e->stylesheet = stylesheet; } @@ -2125,7 +2125,7 @@ void sc_editor_set_imagestore(SCEditor *e, ImageStore *is) } -SCEditor *sc_editor_new(SCBlock *scblocks, SCBlock *stylesheet, +SCEditor *sc_editor_new(SCBlock *scblocks, Stylesheet *stylesheet, PangoLanguage *lang, const char *storename) { SCEditor *sceditor; diff --git a/src/sc_editor.h b/src/sc_editor.h index adbbaf2..35557d4 100644 --- a/src/sc_editor.h +++ b/src/sc_editor.h @@ -32,6 +32,7 @@ #include "frame.h" #include "sc_interp.h" +#include "stylesheet.h" struct presentation; @@ -94,7 +95,7 @@ struct _sceditor double log_w; /* Size of surface in "SC units" */ double log_h; SCBlock *scblocks; - SCBlock *stylesheet; + Stylesheet *stylesheet; ImageStore *is; SCCallbackList *cbl; struct frame *top; @@ -168,10 +169,10 @@ typedef struct _sceditor SCEditor; typedef struct _sceditorclass SCEditorClass; extern void sc_editor_set_scblock(SCEditor *e, SCBlock *scblocks); -extern void sc_editor_set_stylesheet(SCEditor *e, SCBlock *stylesheet); +extern void sc_editor_set_stylesheet(SCEditor *e, Stylesheet *stylesheet); extern SCBlock *sc_editor_get_scblock(SCEditor *e); extern GtkWidget *sc_editor_get_widget(SCEditor *e); -extern SCEditor *sc_editor_new(SCBlock *scblocks, SCBlock *stylesheet, +extern SCEditor *sc_editor_new(SCBlock *scblocks, Stylesheet *stylesheet, PangoLanguage *lang, const char *storename); extern void sc_editor_set_size(SCEditor *e, int w, int h); extern void sc_editor_set_logical_size(SCEditor *e, double w, double h); diff --git a/src/stylesheet.c b/src/stylesheet.c new file mode 100644 index 0000000..51cce6e --- /dev/null +++ b/src/stylesheet.c @@ -0,0 +1,91 @@ +/* + * stylesheet.c + * + * Copyright © 2013-2018 Thomas White + * + * This file is part of Colloquium. + * + * Colloquium 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 3 of the License, or + * (at your option) any later version. + * + * This program 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "stylesheet.h" + + +struct _stylesheet { + JsonNode *root; +}; + + +Stylesheet *stylesheet_load(const char *filename) +{ + JsonParser *parser; + gboolean r; + GError *err = NULL; + Stylesheet *ss; + + ss = calloc(1, sizeof(Stylesheet)); + if ( ss == NULL ) return NULL; + + parser = json_parser_new(); + + r = json_parser_load_from_file(parser, filename, &err); + if ( r == FALSE ) { + fprintf(stderr, "Failed to load style sheet: '%s'\n", err->message); + return NULL; + } + + ss->root = json_parser_steal_root(parser); + g_object_unref(parser); + + return ss; +} + + +char *stylesheet_lookup(Stylesheet *ss, const char *path) +{ + JsonNode *node; + JsonArray *array; + GError *err = NULL; + char *ret; + const gchar *v; + + node = json_path_query(path, ss->root, &err); + array = json_node_get_array(node); + + v = json_array_get_string_element(array, 0); + if ( v == NULL ) return NULL; + + ret = strdup(v); + json_node_unref(node); + return ret; +} + + +void stylesheet_free(Stylesheet *ss) +{ + g_object_unref(ss->root); + free(ss); +} + diff --git a/src/stylesheet.h b/src/stylesheet.h new file mode 100644 index 0000000..59afa7d --- /dev/null +++ b/src/stylesheet.h @@ -0,0 +1,36 @@ +/* + * stylesheet.h + * + * Copyright © 2013-2018 Thomas White + * + * This file is part of Colloquium. + * + * Colloquium 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 3 of the License, or + * (at your option) any later version. + * + * This program 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef STYLESHEET_H +#define STYLESHEET_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +typedef struct _stylesheet Stylesheet; + +extern Stylesheet *stylesheet_load(const char *filename); +extern char *stylesheet_lookup(Stylesheet *ss, const char *path); +extern void stylesheet_free(Stylesheet *ss); + +#endif /* STYLESHEET_H */ diff --git a/src/stylesheet_editor.c b/src/stylesheet_editor.c index 508ee6a..2b9d21e 100644 --- a/src/stylesheet_editor.c +++ b/src/stylesheet_editor.c @@ -38,7 +38,6 @@ G_DEFINE_TYPE_WITH_CODE(StylesheetEditor, stylesheet_editor, GTK_TYPE_DIALOG, NULL) -static void set_values_from_presentation(StylesheetEditor *se); struct _sspriv { @@ -46,176 +45,16 @@ struct _sspriv }; -static SCBlock *find_block(SCBlock *bl, const char *find) -{ - while ( bl != NULL ) { - - const char *name = sc_block_name(bl); - if ( (name != NULL) && (strcmp(name, find)==0) ) { - return bl; - } - - bl = sc_block_next(bl); - - } - - return NULL; -} - - -static void find_replace(SCBlock *parent, const char *find, const char *seti) -{ - SCBlock *bl = find_block(sc_block_child(parent), find); - - if ( bl != NULL ) { - - printf("replacing '%s' with '%s'\n", sc_block_options(bl), seti); - sc_block_set_options(bl, strdup(seti)); - - } else { - - /* Block not found -> create it */ - sc_block_append_inside(parent, strdup(find), strdup(seti), NULL); - - } -} - - -static SCBlock *find_or_create_style(struct presentation *p, const char *style_name) -{ - SCBlock *bl; - const char *name; - - /* If no stylesheet yet, create one now */ - if ( p->stylesheet == NULL ) { - p->stylesheet = sc_parse("\\stylesheet"); - if ( p->stylesheet == NULL ) { - fprintf(stderr, "WARNING: Couldn't create stylesheet\n"); - return NULL; - } - sc_block_append_p(p->stylesheet, p->scblocks); - p->scblocks = p->stylesheet; - } - bl = p->stylesheet; - - name = sc_block_name(bl); - if ( (name != NULL) && (strcmp(name, "stylesheet")==0) ) { - bl = sc_block_child(bl); - } - - while ( bl != NULL ) { - - const char *name = sc_block_name(bl); - const char *options = sc_block_options(bl); - if ( (name != NULL) && (strcmp(name, "style")==0) - && (strcmp(options, style_name)==0) ) - { - return bl; - } - - bl = sc_block_next(bl); - - } - - /* Not found -> add style */ - return sc_block_append_inside(p->stylesheet, strdup("style"), - strdup(style_name), NULL); -} - - -static void set_ss(struct presentation *p, const char *style_name, - const char *find, const char *seti) -{ - SCBlock *bl = find_or_create_style(p, style_name); - if ( bl == NULL ) { - fprintf(stderr, "WARNING: Couldn't find style\n"); - return; - } - find_replace(bl, find, seti); -} - - -static void set_ss_bg_block(SCBlock *bl, GradientType bggrad, - GdkRGBA col1, GdkRGBA col2) -{ - char tmp[64]; - - switch ( bggrad ) { - - case GRAD_NONE : - sc_block_set_name(bl, strdup("bgcol")); - snprintf(tmp, 63, "#%.2x%.2x%.2x", - (int)(col1.red*255), (int)(col1.green*255), (int)(col1.blue*255)); - sc_block_set_options(bl, strdup(tmp)); - break; - - case GRAD_VERT : - sc_block_set_name(bl, strdup("bggradv")); - snprintf(tmp, 63, "#%.2x%.2x%.2x,#%.2x%.2x%.2x", - (int)(col1.red*255), (int)(col1.green*255), (int)(col1.blue*255), - (int)(col2.red*255), (int)(col2.green*255), (int)(col2.blue*255)); - sc_block_set_options(bl, strdup(tmp)); - break; - - case GRAD_HORIZ : - sc_block_set_name(bl, strdup("bggradh")); - snprintf(tmp, 63, "#%.2x%.2x%.2x,#%.2x%.2x%.2x", - (int)(col1.red*255), (int)(col1.green*255), (int)(col1.blue*255), - (int)(col2.red*255), (int)(col2.green*255), (int)(col2.blue*255)); - sc_block_set_options(bl, strdup(tmp)); - break; - - case GRAD_NOBG : - printf("no bg\n"); - sc_block_set_name(bl, NULL); - sc_block_set_options(bl, NULL); - sc_block_set_contents(bl, NULL); - break; - - } -} - - -static int try_set_block(SCBlock **parent, const char *name, - GradientType bggrad, GdkRGBA col1, GdkRGBA col2) +static void set_values_from_presentation(StylesheetEditor *se) { - SCBlock *ibl; - - ibl = find_block(sc_block_child(*parent), name); - if ( ibl != NULL ) { - if ( bggrad != GRAD_NOBG ) { - set_ss_bg_block(ibl, bggrad, col1, col2); - return 1; - } else { - sc_block_delete(parent, ibl); - return 1; - } - } - - return 0; + /* FIXME: From JSON */ } static void update_bg(struct presentation *p, const char *style_name, GradientType bggrad, GdkRGBA col1, GdkRGBA col2) { - int done; - SCBlock *bl; - - bl = find_or_create_style(p, style_name); - if ( bl == NULL ) { - fprintf(stderr, "WARNING: Couldn't find style\n"); - return; - } - - /* FIXME: What if there are two of these? */ - done = try_set_block(&bl, "bgcol", bggrad, col1, col2); - if ( !done ) done = try_set_block(&bl, "bggradv", bggrad, col1, col2); - if ( !done ) done = try_set_block(&bl, "bggradh", bggrad, col1, col2); - if ( !done && bggrad != GRAD_NOBG ) { - SCBlock *ibl = sc_block_append_inside(bl, NULL, NULL, NULL); - set_ss_bg_block(ibl, bggrad, col1, col2); - } + /* FIXME: set in JSON */ } @@ -239,9 +78,9 @@ static GradientType id_to_gradtype(const gchar *id) static void set_font(GtkFontButton *widget, StylesheetEditor *se, const char *style_name) { - const gchar *font; - font = gtk_font_button_get_font_name(GTK_FONT_BUTTON(widget)); - set_ss(se->priv->p, style_name, "font", font); +// const gchar *font; +// font = gtk_font_button_get_font_name(GTK_FONT_BUTTON(widget)); + /* FIXME: set in JSON */ set_values_from_presentation(se); g_signal_emit_by_name(se, "changed"); } @@ -254,7 +93,7 @@ static void set_col(GtkColorButton *widget, StylesheetEditor *se, gchar *col; gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget), &rgba); col = gdk_rgba_to_string(&rgba); - set_ss(se->priv->p, style_name, col_name, col); + /* FIXME: Set in JSON */ g_free(col); set_values_from_presentation(se); g_signal_emit_by_name(se, "changed"); @@ -446,55 +285,6 @@ void stylesheet_editor_class_init(StylesheetEditorClass *klass) } -static void set_from_interp_col(double *col, GtkWidget *w) -{ - GdkRGBA rgba; - - rgba.red = col[0]; - rgba.green = col[1]; - rgba.blue = col[2]; - rgba.alpha = col[3]; - gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(w), &rgba); -} - - -static void set_from_interp_bggrad(SCInterpreter *scin, GtkWidget *w) -{ - GradientType grad; - const gchar *id; - - grad = sc_interp_get_bggrad(scin); - - switch ( grad ) { - case GRAD_NONE : id = "flat"; break; - case GRAD_HORIZ : id = "horiz"; break; - case GRAD_VERT : id = "vert"; break; - case GRAD_NOBG : id = "none"; break; - default : id = NULL; break; - } - - gtk_combo_box_set_active_id(GTK_COMBO_BOX(w), id); -} - - -static void set_from_interp_font(SCInterpreter *scin, GtkWidget *w) -{ - char *fontname; - PangoFontDescription *fontdesc; - - fontdesc = sc_interp_get_fontdesc(scin); - fontname = pango_font_description_to_string(fontdesc); - gtk_font_button_set_font_name(GTK_FONT_BUTTON(w), fontname); - g_free(fontname); -} - - -static void set_values_from_presentation(StylesheetEditor *se) -{ - /* FIXME: From JSON */ -} - - StylesheetEditor *stylesheet_editor_new(struct presentation *p) { StylesheetEditor *se; -- cgit v1.2.3