Put styles in submenus
authorThomas White <taw@bitwiz.org.uk>
Tue, 11 Sep 2012 18:02:46 +0000 (20:02 +0200)
committerThomas White <taw@bitwiz.org.uk>
Tue, 11 Sep 2012 18:02:46 +0000 (20:02 +0200)
src/mainwindow.c
src/presentation.c
src/presentation.h
src/stylesheet.c
src/stylesheet.h

index 8419e1e..a4221a6 100644 (file)
@@ -529,14 +529,69 @@ static gint add_furniture(GtkWidget *widget, struct presentation *p)
 }
 
 
+static void update_style_menus(struct presentation *p)
+{
+       GtkWidget *menu;
+       GtkWidget *item;
+       struct slide_template *t;
+       TemplateIterator *iter;
+       int i, j, n;
+
+       for ( i=0; i<p->n_menu_rebuild; i++ ) {
+               gtk_widget_destroy(p->menu_rebuild_list[i]);
+       }
+       free(p->menu_rebuild_list);
+
+       /* Add the styles to the "Insert" menu */
+       menu = gtk_ui_manager_get_widget(p->ui, "/displaywindow/insert");
+       menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu));
+       item = gtk_separator_menu_item_new();
+       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+
+       n = 0;
+       for ( t = template_first(p->ss, &iter);
+             t != NULL;
+             t = template_next(p->ss, iter) )
+       {
+               n += t->n_styles;
+               n += 1;  /* The top level */
+       }
+
+       p->menu_rebuild_list = calloc(n, sizeof(GtkWidget *));
+       if ( p->menu_rebuild_list == NULL ) return;
+
+       j = 0;
+       for ( t = template_first(p->ss, &iter);
+             t != NULL;
+             t = template_next(p->ss, iter) )
+       {
+               GtkWidget *submenu;
+
+               submenu = gtk_menu_new();
+               item = gtk_menu_item_new_with_label(t->name);
+               gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+                       gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
+               p->menu_rebuild_list[j++] = item;
+
+               for ( i=0; i<t->n_styles; i++ ) {
+
+                       struct style *s = t->styles[i];
+
+                       item = gtk_menu_item_new_with_label(s->name);
+                       gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item);
+                       p->menu_rebuild_list[j++] = item;
+                       g_signal_connect(G_OBJECT(item), "activate",
+                                        G_CALLBACK(add_furniture), p);
+
+               }
+       }
+}
+
+
 static void add_menu_bar(struct presentation *p, GtkWidget *vbox)
 {
        GError *error = NULL;
        GtkWidget *toolbar;
-       GtkWidget *menu;
-       GtkWidget *item;
-       struct style *s;
-       StyleIterator *iter;
 
        GtkActionEntry entries[] = {
 
@@ -625,22 +680,7 @@ static void add_menu_bar(struct presentation *p, GtkWidget *vbox)
        gtk_toolbar_insert(GTK_TOOLBAR(toolbar),
                           gtk_separator_tool_item_new(), -1);
 
-       /* Add the styles to the "Insert" menu */
-       menu = gtk_ui_manager_get_widget(p->ui, "/displaywindow/insert");
-       menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu));
-       item = gtk_separator_menu_item_new();
-       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-
-       for ( s = style_first(p->ss, &iter);
-             s != NULL;
-             s = style_next(p->ss, iter) )
-       {
-               item = gtk_menu_item_new_with_label(s->name);
-               gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-               g_signal_connect(G_OBJECT(item), "activate",
-                                G_CALLBACK(add_furniture), p);
-       }
-
+       update_style_menus(p);
        update_toolbar(p);
 }
 
index a94b220..ec918a6 100644 (file)
@@ -224,6 +224,9 @@ struct presentation *new_presentation()
        new->ss = new_stylesheet();
        default_stylesheet(new->ss);
 
+       new->n_menu_rebuild = 0;
+       new->menu_rebuild_list = NULL;
+
        return new;
 }
 
index f255636..72a1512 100644 (file)
@@ -89,6 +89,8 @@ struct presentation
        GtkUIManager     *ui;
        GtkActionGroup   *action_group;
        GtkIMContext     *im_context;
+       GtkWidget       **menu_rebuild_list;
+       int               n_menu_rebuild;
 
        /* Pointers to the current "editing" and "projection" slides */
        struct slide     *cur_edit_slide;
index 8852b3e..0f49d26 100644 (file)
@@ -347,3 +347,36 @@ struct style *style_next(StyleSheet *ss, StyleIterator *iter)
 
        return ss->styles[iter->n];
 }
+
+
+struct _templateiterator
+{
+       int n;
+};
+
+struct slide_template *template_first(StyleSheet *ss, TemplateIterator **piter)
+{
+       TemplateIterator *iter;
+
+       if ( ss->n_templates == 0 ) return NULL;
+
+       iter = calloc(1, sizeof(TemplateIterator));
+       if ( iter == NULL ) return NULL;
+
+       iter->n = 0;
+       *piter = iter;
+
+       return ss->templates[0];
+}
+
+
+struct slide_template *template_next(StyleSheet *ss, TemplateIterator *iter)
+{
+       iter->n++;
+       if ( iter->n == ss->n_templates ) {
+               free(iter);
+               return NULL;
+       }
+
+       return ss->templates[iter->n];
+}
index 49e3b77..82f198d 100644 (file)
@@ -74,8 +74,13 @@ extern StyleSheet *tree_to_stylesheet(struct ds_node *root);
 extern void write_stylesheet(StyleSheet *ss, struct serializer *ser);
 
 typedef struct _styleiterator StyleIterator;
-
 extern struct style *style_first(StyleSheet *ss, StyleIterator **piter);
 extern struct style *style_next(StyleSheet *ss, StyleIterator *iter);
 
+typedef struct _templateiterator TemplateIterator;
+extern struct slide_template *template_first(StyleSheet *ss,
+                                             TemplateIterator **piter);
+extern struct slide_template *template_next(StyleSheet *ss,
+                                            TemplateIterator *iter);
+
 #endif /* STYLESHEET_H */