From 18285193ab891014089227a459cfab7c2560af02 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sat, 21 May 2011 23:42:16 +0200 Subject: Add slide rendering machinery --- Makefile.am | 5 +++-- src/mainwindow.c | 40 ++++++++++++++++++++++++++++++++++++++-- src/presentation.c | 38 ++++++++++++++++++++++++++++++++++++++ src/presentation.h | 42 ++++++++++++++++++++++++++++++++++++++---- src/slide_render.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/slide_render.h | 36 ++++++++++++++++++++++++++++++++++++ 6 files changed, 207 insertions(+), 8 deletions(-) create mode 100644 src/slide_render.c create mode 100644 src/slide_render.h diff --git a/Makefile.am b/Makefile.am index 16462c2..d8cf801 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,11 +8,12 @@ AM_CFLAGS = -Wall AM_CPPFLAGS = -DDATADIR=\""$(datadir)"\" -I$(top_builddir)/lib -I$(top_srcdir)/lib LDADD = $(top_builddir)/lib/libgnu.a @IGNORE_UNUSED_LIBRARIES_CFLAGS@ -src_colloquium_SOURCES = src/colloquium.c src/presentation.c src/mainwindow.c +src_colloquium_SOURCES = src/colloquium.c src/presentation.c src/mainwindow.c \ + src/slide_render.c INCLUDES = "-I$(top_srcdir)/data" -EXTRA_DIST += src/presentation.h src/mainwindow.h +EXTRA_DIST += src/presentation.h src/mainwindow.h src/slide_render.h colloquiumdir = $(datadir)/colloquium colloquium_DATA = data/colloquium.ui diff --git a/src/mainwindow.c b/src/mainwindow.c index b118328..289a096 100644 --- a/src/mainwindow.c +++ b/src/mainwindow.c @@ -28,9 +28,11 @@ #include #include #include +#include #include "presentation.h" #include "mainwindow.h" +#include "slide_render.h" static void add_ui_sig(GtkUIManager *ui, GtkWidget *widget, @@ -136,6 +138,15 @@ static gint close_sig(GtkWidget *window, struct presentation *p) } +static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event, + struct presentation *p) +{ + printf("%f %f\n", event->x - p->border_offs_x, + event->y - p->border_offs_y); + return 0; +} + + static gboolean expose_sig(GtkWidget *da, GdkEventExpose *event, struct presentation *p) { @@ -155,10 +166,15 @@ static gboolean expose_sig(GtkWidget *da, GdkEventExpose *event, gtk_widget_get_allocation(da, &allocation); xoff = (allocation.width - p->slide_width)/2.0; yoff = (allocation.height - p->slide_height)/2.0; + p->border_offs_x = xoff; p->border_offs_y = yoff; cairo_translate(cr, xoff, yoff); - cairo_rectangle(cr, 0.0, 0.0, p->slide_width, p->slide_height); - cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + + /* Draw the slide from the cache */ + cairo_rectangle(cr, event->area.x, event->area.y, + event->area.width, event->area.height); + cairo_set_source_surface(cr, p->slides[p->view_slide]->render_cache, + 0.0, 0.0); cairo_fill(cr); cairo_destroy(cr); @@ -167,6 +183,15 @@ static gboolean expose_sig(GtkWidget *da, GdkEventExpose *event, } +static void check_redraw_slide(struct presentation *p, int n) +{ + /* Update necessary? */ + if ( p->slides[n]->object_seq <= p->slides[n]->render_cache_seq ) return; + + render_slide(p->slides[n]); +} + + int open_mainwindow(struct presentation *p) { GtkWidget *window; @@ -205,12 +230,23 @@ int open_mainwindow(struct presentation *p) p->slide_width + 20, p->slide_height + 20); + gtk_widget_set_can_focus(GTK_WIDGET(p->drawingarea), TRUE); + gtk_widget_add_events(GTK_WIDGET(p->drawingarea), + GDK_POINTER_MOTION_HINT_MASK + | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); + g_signal_connect(GTK_OBJECT(p->drawingarea), "button-press-event", + G_CALLBACK(button_press_sig), p); + g_signal_connect(GTK_OBJECT(p->drawingarea), "expose-event", G_CALLBACK(expose_sig), p); gtk_window_set_default_size(GTK_WINDOW(p->window), 1024+100, 768+100); gtk_window_set_resizable(GTK_WINDOW(p->window), TRUE); + assert(p->num_slides > 0); + check_redraw_slide(p, p->view_slide); + gtk_widget_show_all(window); return 0; } diff --git a/src/presentation.c b/src/presentation.c index 8a5dca7..b67c8fd 100644 --- a/src/presentation.c +++ b/src/presentation.c @@ -29,6 +29,38 @@ #include #include "presentation.h" +#include "slide_render.h" + + +int add_slide(struct presentation *p) +{ + struct slide **try; + struct slide *new; + + try = realloc(p->slides, p->num_slides*sizeof(struct slide **)); + if ( try == NULL ) return 1; + p->slides = try; + + new = malloc(sizeof(struct slide)); + if ( new == NULL ) return 1; + /* Doesn't matter that p->slides now has some excess space - + * it'll get corrected the next time a slide is added or deleted. */ + + /* No objects to start with */ + new->n_objects = 0; + new->object_seq = 0; + new->objects = NULL; + + new->slide_width = p->slide_width; + new->slide_height = p->slide_height; + + new->render_cache_seq = 0; + new->render_cache = NULL; + render_slide(new); /* Render nothing, just to make the surface exist */ + + p->slides[p->num_slides++] = new; + return 0; +} struct presentation *new_presentation() @@ -47,5 +79,11 @@ struct presentation *new_presentation() new->slide_width = 1024.0; new->slide_height = 768.0; + new->num_slides = 0; + new->slides = NULL; + add_slide(new); + + new->view_slide = 0; + return new; } diff --git a/src/presentation.h b/src/presentation.h index 14829c7..5b219a2 100644 --- a/src/presentation.h +++ b/src/presentation.h @@ -31,18 +31,52 @@ #include +enum objtype +{ + RECTANGLE, +}; + + +struct object +{ + enum objtype type; +}; + + +struct slide +{ + cairo_surface_t *render_cache; + int render_cache_seq; + + int n_objects; + struct object *objects; + int object_seq; + + double slide_width; + double slide_height; +}; + + struct presentation { - char *titlebar; - char *filename; + char *titlebar; + char *filename; GtkWidget *window; GtkWidget *drawingarea; GtkUIManager *ui; GtkActionGroup *action_group; - double slide_width; - double slide_height; + double slide_width; + double slide_height; + double border_offs_x; + double border_offs_y; + + /* The slide currently being displayed */ + unsigned int view_slide; + + unsigned int num_slides; + struct slide **slides; }; diff --git a/src/slide_render.c b/src/slide_render.c new file mode 100644 index 0000000..1966fe7 --- /dev/null +++ b/src/slide_render.c @@ -0,0 +1,54 @@ +/* + * slide_render.c + * + * Colloquium - A tiny presentation program + * + * Copyright (c) 2011 Thomas White + * + * This program 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 "slide_render.h" +#include "presentation.h" + + +int render_slide(struct slide *s) +{ + cairo_surface_t *surf; + cairo_t *cr; + + surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, + s->slide_width, s->slide_height); + + cr = cairo_create(surf); + + cairo_rectangle(cr, 0.0, 0.0, s->slide_width, s->slide_height); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_fill(cr); + + cairo_destroy(cr); + + if ( s->render_cache != NULL ) cairo_surface_destroy(s->render_cache); + s->render_cache = surf; + + return 0; +} diff --git a/src/slide_render.h b/src/slide_render.h new file mode 100644 index 0000000..500a3ed --- /dev/null +++ b/src/slide_render.h @@ -0,0 +1,36 @@ +/* + * slide_render.h + * + * Colloquium - A tiny presentation program + * + * Copyright (c) 2011 Thomas White + * + * This program 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 SLIDE_RENDER_H +#define SLIDE_RENDER_H + +#ifdef HAVE_CONFIG_H +#include +#endif + + +#include "presentation.h" + +extern int render_slide(struct slide *s); + + +#endif /* SLIDE_RENDER_H */ -- cgit v1.2.3