aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2014-09-28 13:43:34 +0200
committerThomas White <taw@bitwiz.org.uk>2014-09-28 13:43:34 +0200
commitbee5e2fd263d81b7dc8180e831cbc96500cece1f (patch)
tree2d8ec810a21707fb4013b26b7e49ea4f1bfc6294 /src
parentab6af6b34c9e5fdfa8cff44fa0f78f9c34ed28ef (diff)
SCEditor, part II
Diffstat (limited to 'src')
-rw-r--r--src/colloquium.c134
-rw-r--r--src/narrative_window.c114
-rw-r--r--src/notes.c1
-rw-r--r--src/presentation.c1
-rw-r--r--src/sc_editor.c48
-rw-r--r--src/slide_window.c2
6 files changed, 269 insertions, 31 deletions
diff --git a/src/colloquium.c b/src/colloquium.c
index ce23be5..51b60c9 100644
--- a/src/colloquium.c
+++ b/src/colloquium.c
@@ -32,12 +32,79 @@
#include "narrative_window.h"
+typedef struct
+{
+ GtkApplication parent_instance;
+} Colloquium;
+
+
+typedef GtkApplicationClass ColloquiumClass;
+
+
+G_DEFINE_TYPE(Colloquium, colloquium, GTK_TYPE_APPLICATION)
+
+
static void colloquium_activate(GApplication *app)
{
printf("activate!\n");
}
+static void new_sig(GSimpleAction *action, GVariant *parameter, gpointer vp)
+{
+ GApplication *app = vp;
+ g_application_activate(app);
+}
+
+
+static void about_sig(GSimpleAction *action, GVariant *parameter, gpointer vp)
+{
+ GtkWidget *window;
+
+ const gchar *authors[] = {
+ "Thomas White <taw@bitwiz.org.uk>",
+ NULL
+ };
+
+ window = gtk_about_dialog_new();
+
+ gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(window),
+ "Colloquium");
+ gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(window),
+ PACKAGE_VERSION);
+ gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(window),
+ "© 2013 Thomas White <taw@bitwiz.org.uk>");
+ gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(window),
+ "A tiny presentation program");
+ gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(window),
+ "© 2013 Thomas White <taw@bitwiz.org.uk>\n");
+ gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(window),
+ "http://www.bitwiz.org.uk/");
+ gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(window), authors);
+
+ g_signal_connect(window, "response", G_CALLBACK(gtk_widget_destroy),
+ NULL);
+
+ gtk_widget_show_all(window);
+}
+
+
+static void quit_sig(GSimpleAction *action, GVariant *parameter, gpointer vp)
+{
+ GApplication *app = vp;
+ g_application_quit(app);
+}
+
+
+GActionEntry app_entries[] = {
+
+ { "new", new_sig, NULL, NULL, NULL },
+ { "about", about_sig, NULL, NULL, NULL },
+ { "quit", quit_sig, NULL, NULL, NULL },
+
+};
+
+
static void colloquium_open(GApplication *app, GFile **files, gint n_files,
const gchar *hint)
{
@@ -46,7 +113,6 @@ static void colloquium_open(GApplication *app, GFile **files, gint n_files,
for ( i = 0; i<n_files; i++ ) {
struct presentation *p;
char *uri = g_file_get_path(files[i]);
- printf("open %s\n", uri);
p = new_presentation();
load_presentation(p, uri);
narrative_window_new(p, app);
@@ -54,14 +120,6 @@ static void colloquium_open(GApplication *app, GFile **files, gint n_files,
}
}
-typedef struct
-{
- GtkApplication parent_instance;
-} Colloquium;
-
-typedef GtkApplicationClass ColloquiumClass;
-
-G_DEFINE_TYPE(Colloquium, colloquium, GTK_TYPE_APPLICATION)
static void colloquium_finalize(GObject *object)
{
@@ -71,7 +129,65 @@ static void colloquium_finalize(GObject *object)
static void colloquium_startup(GApplication *app)
{
+ GtkBuilder *builder;
+
G_APPLICATION_CLASS(colloquium_parent_class)->startup(app);
+
+ g_action_map_add_action_entries(G_ACTION_MAP(app), app_entries,
+ G_N_ELEMENTS(app_entries), app);
+
+ builder = gtk_builder_new();
+ gtk_builder_add_from_string(builder,
+ "<interface>"
+
+ " <menu id='app-menu'>"
+ " <section>"
+ " <item>"
+ " <attribute name='label'>_New</attribute>"
+ " <attribute name='action'>app.new</attribute>"
+ " <attribute name='accel'>&lt;Primary&gt;n</attribute>"
+ " </item>"
+ " </section>"
+ " <section>"
+ " <item>"
+ " <attribute name='label'>_About</attribute>"
+ " <attribute name='action'>app.about</attribute>"
+ " </item>"
+ " </section>"
+ " <section>"
+ " <item>"
+ " <attribute name='label'>_Quit</attribute>"
+ " <attribute name='action'>app.quit</attribute>"
+ " <attribute name='accel'>&lt;Primary&gt;q</attribute>"
+ " </item>"
+ " </section>"
+ " </menu>"
+
+ " <menu id='menubar'>"
+ " <submenu>"
+ " <attribute name='label' translatable='yes'>File</attribute>"
+ " <section>"
+ " <item>"
+ " <attribute name='label'>_Save</attribute>"
+ " <attribute name='action'>file.save</attribute>"
+ " <attribute name='accel'>&lt;Primary&gt;s</attribute>"
+ " </item>"
+ " <item>"
+ " <attribute name='label'>Export PDF</attribute>"
+ " <attribute name='action'>file.exportpdf</attribute>"
+ " </item>"
+ " </section>"
+ " </submenu>"
+ " </menu>"
+
+ "</interface>", -1, NULL);
+
+ gtk_application_set_app_menu(GTK_APPLICATION(app),
+ G_MENU_MODEL(gtk_builder_get_object(builder, "app-menu")));
+ gtk_application_set_menubar(GTK_APPLICATION(app),
+ G_MENU_MODEL(gtk_builder_get_object(builder, "menubar")));
+
+ g_object_unref(builder);
}
diff --git a/src/narrative_window.c b/src/narrative_window.c
index 7fd51a3..f529f29 100644
--- a/src/narrative_window.c
+++ b/src/narrative_window.c
@@ -36,12 +36,98 @@
struct _narrative_window
{
GtkWidget *window;
+ GtkWidget *drawingarea; /* FIXME: Should be an SCEditor */
+ GApplication *app;
+ struct presentation *p;
};
+static void save_sig(GSimpleAction *action, GVariant *parameter, gpointer vp)
+{
+}
+
+
+static void exportpdf_sig(GSimpleAction *action, GVariant *parameter,
+ gpointer vp)
+{
+}
+
+
+GActionEntry nw_entries[] = {
+
+ { "save", save_sig, NULL, NULL, NULL, },
+ { "exportpdf", exportpdf_sig, NULL, NULL, NULL },
+
+#if 0
+ { "EditAction", NULL, "_Edit", NULL, NULL, NULL },
+ { "SorterAction", NULL, "_Open Slide Sorter...",
+ NULL, NULL, G_CALLBACK(open_slidesorter_sig) },
+ { "UndoAction", GTK_STOCK_UNDO, "_Undo",
+ NULL, NULL, NULL },
+ { "RedoAction", GTK_STOCK_REDO, "_Redo",
+ NULL, NULL, NULL },
+ { "CutAction", GTK_STOCK_CUT, "Cut",
+ NULL, NULL, NULL },
+ { "CopyAction", GTK_STOCK_COPY, "Copy",
+ NULL, NULL, NULL },
+ { "PasteAction", GTK_STOCK_PASTE, "Paste",
+ NULL, NULL, NULL },
+ { "DeleteFrameAction", GTK_STOCK_DELETE, "Delete Frame",
+ NULL, NULL, G_CALLBACK(delete_frame_sig) },
+// { "EditStyleAction", NULL, "Stylesheet...",
+// NULL, NULL, G_CALLBACK(open_stylesheet_sig) },
+
+ { "InsertAction", NULL, "_Insert", NULL, NULL, NULL },
+ { "NewSlideAction", GTK_STOCK_ADD, "_New Slide",
+ NULL, NULL, G_CALLBACK(add_slide_sig) },
+
+ { "ToolsAction", NULL, "_Tools", NULL, NULL, NULL },
+ { "TSlideshowAction", GTK_STOCK_FULLSCREEN, "_Start Slideshow",
+ "F5", NULL, G_CALLBACK(start_slideshow_sig) },
+ { "NotesAction", NULL, "_Open slide notes",
+ "F8", NULL, G_CALLBACK(open_notes_sig) },
+ { "ClockAction", NULL, "_Open presentation clock",
+ "F9", NULL, G_CALLBACK(open_clock_sig) },
+ { "PrefsAction", GTK_STOCK_PREFERENCES, "_Preferences",
+ NULL, NULL, NULL },
+
+ { "HelpAction", NULL, "_Help", NULL, NULL, NULL },
+ { "AboutAction", GTK_STOCK_ABOUT, "_About...",
+ NULL, NULL, G_CALLBACK(about_sig) },
+
+ { "SlideshowAction", GTK_STOCK_FULLSCREEN, "Start Presentation",
+ NULL, NULL, G_CALLBACK(start_slideshow_sig) },
+ { "AddSlideAction", GTK_STOCK_ADD, "Add Slide",
+ NULL, NULL, G_CALLBACK(add_slide_sig) },
+ { "ButtonFirstSlideAction", GTK_STOCK_GOTO_FIRST, "First Slide",
+ NULL, NULL, G_CALLBACK(first_slide_sig) },
+ { "ButtonPrevSlideAction", GTK_STOCK_GO_BACK, "Previous Slide",
+ NULL, NULL, G_CALLBACK(prev_slide_sig) },
+ { "ButtonNextSlideAction", GTK_STOCK_GO_FORWARD, "Next Slide",
+ NULL, NULL, G_CALLBACK(next_slide_sig) },
+ { "ButtonLastSlideAction", GTK_STOCK_GOTO_LAST, "Last Slide",
+ NULL, NULL, G_CALLBACK(last_slide_sig) },
+#endif
+
+};
+
+
+static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event,
+ NarrativeWindow *nw)
+{
+ if ( event->type == GDK_2BUTTON_PRESS ) {
+ nw->p->slidewindow = slide_window_open(nw->p, nw->app);
+ }
+
+ return 0;
+}
+
+
NarrativeWindow *narrative_window_new(struct presentation *p, GApplication *app)
{
NarrativeWindow *nw;
+ GtkWidget *vbox;
+ GtkWidget *scroll;
if ( p->narrative_window != NULL ) {
fprintf(stderr, "Narrative window is already open!\n");
@@ -51,11 +137,39 @@ NarrativeWindow *narrative_window_new(struct presentation *p, GApplication *app)
nw = calloc(1, sizeof(NarrativeWindow));
if ( nw == NULL ) return NULL;
+ nw->app = app;
+ nw->p = p;
+
nw->window = gtk_application_window_new(GTK_APPLICATION(app));
p->narrative_window = nw;
+ g_action_map_add_action_entries(G_ACTION_MAP(nw->window), nw_entries,
+ G_N_ELEMENTS(nw_entries), nw->window);
+
// update_titlebar(nw);
+ vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+ gtk_container_add(GTK_CONTAINER(nw->window), vbox);
+
+ nw->drawingarea = gtk_drawing_area_new();
+ scroll = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll),
+ GTK_WIDGET(nw->drawingarea));
+
+ g_signal_connect(G_OBJECT(nw->drawingarea), "button-press-event",
+ G_CALLBACK(button_press_sig), nw);
+ gtk_widget_set_can_focus(GTK_WIDGET(nw->drawingarea), TRUE);
+ gtk_widget_add_events(GTK_WIDGET(nw->drawingarea),
+ GDK_POINTER_MOTION_HINT_MASK
+ | GDK_BUTTON1_MOTION_MASK
+ | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
+
+ gtk_box_pack_start(GTK_BOX(vbox), scroll, TRUE, TRUE, 0);
+
gtk_widget_show_all(nw->window);
return nw;
diff --git a/src/notes.c b/src/notes.c
index 2210f55..5c884df 100644
--- a/src/notes.c
+++ b/src/notes.c
@@ -94,6 +94,7 @@ void grab_current_notes(struct presentation *p)
void notify_notes_slide_changed(struct presentation *p, struct slide *np)
{
+ if ( p->notes == NULL ) return;
grab_current_notes(p);
p->notes->slide = np;
update_notes(p);
diff --git a/src/presentation.c b/src/presentation.c
index 8cd39ce..e565edf 100644
--- a/src/presentation.c
+++ b/src/presentation.c
@@ -234,6 +234,7 @@ struct presentation *new_presentation()
new->num_slides = 0;
new->slides = NULL;
+ add_slide(new, 0);
new->completely_empty = 1;
new->stylesheet = NULL;
diff --git a/src/sc_editor.c b/src/sc_editor.c
index 3a398c5..780c58d 100644
--- a/src/sc_editor.c
+++ b/src/sc_editor.c
@@ -398,24 +398,26 @@ static void draw_overlay(cairo_t *cr, SCEditor *e)
{
double x, y, w, h;
- draw_editing_box(cr, e->selection);
- x = e->selection->x;
- y = e->selection->y;
- w = e->selection->w;
- h = e->selection->h;
+ if ( e->selection != NULL ) {
- /* Draw resize handles */
- /* FIXME: Not if this frame can't be resized */
- draw_resize_handle(cr, x, y+h-20.0);
- draw_resize_handle(cr, x+w-20.0, y);
- draw_resize_handle(cr, x, y);
- draw_resize_handle(cr, x+w-20.0, y+h-20.0);
+ draw_editing_box(cr, e->selection);
+
+ x = e->selection->x;
+ y = e->selection->y;
+ w = e->selection->w;
+ h = e->selection->h;
+
+ /* Draw resize handles */
+ /* FIXME: Not if this frame can't be resized */
+ draw_resize_handle(cr, x, y+h-20.0);
+ draw_resize_handle(cr, x+w-20.0, y);
+ draw_resize_handle(cr, x, y);
+ draw_resize_handle(cr, x+w-20.0, y+h-20.0);
- /* If only one frame is selected, draw the caret */
- if ( e->selection != NULL ) {
draw_caret(cr, e->cursor_frame, e->cursor_line, e->cursor_box,
e->cursor_pos);
+
}
if ( (e->drag_status == DRAG_STATUS_DRAGGING)
@@ -473,9 +475,8 @@ static gboolean draw_sig(GtkWidget *da, cairo_t *cr,
e->border_offs_x = xoff; e->border_offs_y = yoff;
/* Draw the slide from the cache */
- if ( e->cur_slide->rendered_edit != NULL ) {
- cairo_set_source_surface(cr, e->cur_slide->rendered_edit,
- xoff, yoff);
+ if ( e->surface != NULL ) {
+ cairo_set_source_surface(cr, e->surface, xoff, yoff);
cairo_paint(cr);
} else {
fprintf(stderr, "Current slide not rendered yet!\n");
@@ -1402,7 +1403,10 @@ SCEditor *sc_editor_new(struct presentation *p)
sceditor = calloc(1, sizeof(SCEditor));
if ( sceditor == NULL ) return NULL;
+ sceditor->p = p;
sceditor->drawingarea = gtk_drawing_area_new();
+ sceditor->cur_slide = p->slides[0]; /* FIXME */
+ sceditor->surface = NULL;
gtk_widget_set_size_request(GTK_WIDGET(sceditor->drawingarea),
p->slide_width + 20,
@@ -1426,13 +1430,13 @@ SCEditor *sc_editor_new(struct presentation *p)
gtk_drag_dest_set(sceditor->drawingarea, 0, targets, 1,
GDK_ACTION_PRIVATE);
g_signal_connect(sceditor->drawingarea, "drag-data-received",
- G_CALLBACK(dnd_receive), p);
+ G_CALLBACK(dnd_receive), sceditor);
g_signal_connect(sceditor->drawingarea, "drag-motion",
- G_CALLBACK(dnd_motion), p);
+ G_CALLBACK(dnd_motion), sceditor);
g_signal_connect(sceditor->drawingarea, "drag-drop",
- G_CALLBACK(dnd_drop), p);
+ G_CALLBACK(dnd_drop), sceditor);
g_signal_connect(sceditor->drawingarea, "drag-leave",
- G_CALLBACK(dnd_leave), p);
+ G_CALLBACK(dnd_leave), sceditor);
gtk_widget_set_can_focus(GTK_WIDGET(sceditor->drawingarea), TRUE);
gtk_widget_add_events(GTK_WIDGET(sceditor->drawingarea),
@@ -1442,11 +1446,11 @@ SCEditor *sc_editor_new(struct presentation *p)
| GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
g_signal_connect(G_OBJECT(sceditor->drawingarea), "draw",
- G_CALLBACK(draw_sig), p);
+ G_CALLBACK(draw_sig), sceditor);
gtk_widget_grab_focus(GTK_WIDGET(sceditor->drawingarea));
gtk_widget_show(sceditor->drawingarea);
- return 0;
+ return sceditor;
}
diff --git a/src/slide_window.c b/src/slide_window.c
index bd64538..9163c69 100644
--- a/src/slide_window.c
+++ b/src/slide_window.c
@@ -591,6 +591,8 @@ SlideWindow *slide_window_open(struct presentation *p, GApplication *app)
window = gtk_application_window_new(GTK_APPLICATION(app));
sw->window = window;
+ sw->p = p;
+ sw->cur_slide = p->slides[0];
update_titlebar(p);