Switch to new Stylesheet type
authorThomas White <taw@bitwiz.me.uk>
Wed, 17 Oct 2018 12:50:28 +0000 (14:50 +0200)
committerThomas White <taw@bitwiz.me.uk>
Wed, 17 Oct 2018 12:50:28 +0000 (14:50 +0200)
meson.build
src/narrative_window.c
src/presentation.c
src/presentation.h
src/render.c
src/render.h
src/sc_editor.c
src/sc_editor.h
src/stylesheet.c [new file with mode: 0644]
src/stylesheet.h [new file with mode: 0644]
src/stylesheet_editor.c

index 818c34d..52b9243 100644 (file)
@@ -45,6 +45,7 @@ executable('colloquium',
             'src/print.c',
             'src/sc_parse.c',
             'src/utils.c',
+            'src/stylesheet.c',
             'src/stylesheet_editor.c',
            ],
            gresources,
index 1631f2f..7a19562 100644 (file)
@@ -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"));
                }
index b3676b5..c3f0d07 100644 (file)
@@ -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);
index ed8a188..ea3780e 100644 (file)
@@ -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);
index 0228a7b..041f812 100644 (file)
@@ -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)
index aadb033..0cfae26 100644 (file)
@@ -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,
index 999f919..0431b7b 100644 (file)
@@ -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;
index adbbaf2..35557d4 100644 (file)
@@ -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 (file)
index 0000000..51cce6e
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * stylesheet.c
+ *
+ * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <json-glib/json-glib.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#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 (file)
index 0000000..59afa7d
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * stylesheet.h
+ *
+ * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef STYLESHEET_H
+#define STYLESHEET_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#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 */
index 508ee6a..2b9d21e 100644 (file)
@@ -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;