8bfd8b352133ff823b81f11bcc712c737d26578b
[colloquium.git] / src / slide_window.c
1 /*
2  * slide_window.c
3  *
4  * Copyright © 2013-2019 Thomas White <taw@bitwiz.org.uk>
5  *
6  * This file is part of Colloquium.
7  *
8  * Colloquium is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <gtk/gtk.h>
31 #include <assert.h>
32 #include <gdk/gdkkeysyms.h>
33 #include <gdk-pixbuf/gdk-pixbuf.h>
34 #include <math.h>
35
36 #include <narrative.h>
37 #include <slide.h>
38 #include <gtkslideview.h>
39
40 #include "colloquium.h"
41 #include "slide_window.h"
42 #include "narrative_window.h"
43
44
45 struct _slidewindow
46 {
47         GtkWidget           *window;
48         Narrative           *n;
49         Slide               *slide;
50         GtkWidget           *sv;
51         NarrativeWindow     *parent;
52 };
53
54
55 static void insert_slidetitle_sig(GSimpleAction *action, GVariant *parameter,
56                                   gpointer vp)
57 {
58         SlideWindow *sw = vp;
59         char **text = malloc(sizeof(char *));
60         *text = strdup("Slide title");
61         slide_add_slidetitle(sw->slide, text, 1);
62         gtk_slide_view_set_slide(sw->sv, sw->slide);
63 }
64
65
66 static void paste_sig(GSimpleAction *action, GVariant *parameter,
67                       gpointer vp)
68 {
69         //SlideWindow *sw = vp;
70         //sc_editor_paste(sw->sceditor);
71 }
72
73
74 static void copy_frame_sig(GSimpleAction *action, GVariant *parameter,
75                              gpointer vp)
76 {
77         //SlideWindow *sw = vp;
78         //sc_editor_copy_selected_frame(sw->sceditor);
79 }
80
81
82 static void delete_frame_sig(GSimpleAction *action, GVariant *parameter,
83                              gpointer vp)
84 {
85         //SlideWindow *sw = vp;
86         //sc_editor_delete_selected_frame(sw->sceditor);
87 }
88
89
90 /* Change the editor's slide to "np" */
91 static void change_edit_slide(SlideWindow *sw, Slide *np)
92 {
93         gtk_slide_view_set_slide(sw->sv, np);
94         sw->slide = np;
95         slide_window_update_titlebar(sw);
96 }
97
98
99 static void change_slide_first(SlideWindow *sw)
100 {
101         Slide *s = narrative_get_slide_by_number(sw->n, 0);
102         if ( s != NULL ) change_edit_slide(sw, s);
103 }
104
105
106 static void change_slide_backwards(SlideWindow *sw)
107 {
108         int slide_n = narrative_get_slide_number_for_slide(sw->n, sw->slide);
109         if ( slide_n > 0 ) {
110                 Slide *s = narrative_get_slide_by_number(sw->n, slide_n-1);
111                 change_edit_slide(sw, s);
112         }
113 }
114
115
116 static void change_slide_forwards(SlideWindow *sw)
117 {
118         int slide_n = narrative_get_slide_number_for_slide(sw->n, sw->slide);
119         Slide *s = narrative_get_slide_by_number(sw->n, slide_n+1);
120         if ( s != NULL ) change_edit_slide(sw, s);
121 }
122
123
124 static void change_slide_last(SlideWindow *sw)
125 {
126         int slide_n = narrative_get_num_slides(sw->n);
127         Slide *s = narrative_get_slide_by_number(sw->n, slide_n);
128         if ( s != NULL ) change_edit_slide(sw, s);
129 }
130
131
132 static void first_slide_sig(GSimpleAction *action, GVariant *parameter,
133                            gpointer vp)
134 {
135         SlideWindow *sw = vp;
136         change_slide_first(sw);
137 }
138
139
140 static void prev_slide_sig(GSimpleAction *action, GVariant *parameter,
141                            gpointer vp)
142 {
143         SlideWindow *sw = vp;
144         change_slide_backwards(sw);
145 }
146
147
148 static void next_slide_sig(GSimpleAction *action, GVariant *parameter,
149                            gpointer vp)
150 {
151         SlideWindow *sw = vp;
152         change_slide_forwards(sw);
153 }
154
155
156 static void last_slide_sig(GSimpleAction *action, GVariant *parameter,
157                            gpointer vp)
158 {
159         SlideWindow *sw = vp;
160         change_slide_last(sw);
161 }
162
163
164 static gboolean sw_close_sig(GtkWidget *w, SlideWindow *sw)
165 {
166         narrative_window_sw_closed(sw->parent, sw);
167         return FALSE;
168 }
169
170
171 static gboolean sw_key_press_sig(GtkWidget *da, GdkEventKey *event,
172                                  SlideWindow *sw)
173 {
174         switch ( event->keyval ) {
175
176                 case GDK_KEY_Page_Up :
177                 change_slide_backwards(sw);
178                 break;
179
180                 case GDK_KEY_Page_Down :
181                 change_slide_forwards(sw);
182                 break;
183
184         }
185
186         return FALSE;
187 }
188
189
190 static void about_sig(GSimpleAction *action, GVariant *parameter, gpointer vp)
191 {
192         SlideWindow *sw = vp;
193         open_about_dialog(sw->window);
194 }
195
196
197 GActionEntry sw_entries[] = {
198
199         { "about", about_sig, NULL, NULL, NULL },
200         { "paste", paste_sig, NULL, NULL, NULL },
201         { "copyframe", copy_frame_sig, NULL, NULL, NULL },
202         { "deleteframe", delete_frame_sig, NULL, NULL, NULL },
203         { "first", first_slide_sig, NULL, NULL, NULL },
204         { "prev", prev_slide_sig, NULL, NULL, NULL },
205         { "next", next_slide_sig, NULL, NULL, NULL },
206         { "last", last_slide_sig, NULL, NULL, NULL },
207         { "slidetitle", insert_slidetitle_sig, NULL, NULL, NULL },
208 };
209
210
211 SlideWindow *slide_window_open(Narrative *n, Slide *slide,
212                                NarrativeWindow *nw, GApplication *papp)
213 {
214         GtkWidget *window;
215         SlideWindow *sw;
216         double w, h;
217         Colloquium *app = COLLOQUIUM(papp);
218
219         sw = calloc(1, sizeof(SlideWindow));
220         if ( sw == NULL ) return NULL;
221
222         window = gtk_application_window_new(GTK_APPLICATION(app));
223         gtk_window_set_role(GTK_WINDOW(window), "slide");
224         sw->window = window;
225         sw->n = n;
226         sw->slide = slide;
227         sw->parent = nw;
228
229         slide_window_update_titlebar(sw);
230
231         g_action_map_add_action_entries(G_ACTION_MAP(window), sw_entries,
232                                         G_N_ELEMENTS(sw_entries), sw);
233
234         g_signal_connect(G_OBJECT(window), "destroy",
235                          G_CALLBACK(sw_close_sig), sw);
236
237         sw->sv = gtk_slide_view_new(n, slide);
238
239         g_signal_connect(G_OBJECT(sw->sv), "key-press-event",
240                          G_CALLBACK(sw_key_press_sig), sw);
241
242         slide_get_logical_size(slide, narrative_get_stylesheet(n), &w, &h);
243         gtk_window_set_default_size(GTK_WINDOW(window), w, h);
244
245         gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(sw->sv));
246
247         gtk_window_set_resizable(GTK_WINDOW(sw->window), TRUE);
248
249         gtk_widget_show_all(window);
250
251         return sw;
252 }
253
254
255 void slide_window_update(SlideWindow *sw)
256 {
257         gint w, h;
258         w = gtk_widget_get_allocated_width(GTK_WIDGET(sw->sv));
259         h = gtk_widget_get_allocated_height(GTK_WIDGET(sw->sv));
260         gtk_widget_queue_draw_area(GTK_WIDGET(sw->sv), 0, 0, w, h);
261 }
262
263
264 void slide_window_update_titlebar(SlideWindow *sw)
265 {
266         char title[1026];
267         char *filename;
268
269         filename = narrative_window_get_filename(sw->parent);
270         snprintf(title, 1024, "%s (slide %i) - Colloquium", filename,
271                  1+narrative_get_slide_number_for_slide(sw->n, sw->slide));
272         if ( narrative_get_unsaved(sw->n) ) strcat(title, " *");
273
274         gtk_window_set_title(GTK_WINDOW(sw->window), title);
275 }
276
277
278 void slide_window_destroy(SlideWindow *sw)
279 {
280         gtk_widget_destroy(sw->window);
281 }