aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2011-10-17 22:13:51 +0100
committerThomas White <taw@bitwiz.org.uk>2011-10-17 22:13:51 +0100
commita11196f4e47c312ff787d3990e0aa8edefa3e395 (patch)
treeb43a99972750dc62aae39380e3bbdc2e9b856984 /src
parentc124f153354b6f63aa5f40dbe8e99b6b23cb416b (diff)
New slide redraw logic
This way is much more straightforward, and allows rendering in many different sizes
Diffstat (limited to 'src')
-rw-r--r--src/mainwindow.c52
-rw-r--r--src/objects.c3
-rw-r--r--src/presentation.c21
-rw-r--r--src/presentation.h43
-rw-r--r--src/slide_render.c63
-rw-r--r--src/slide_render.h3
-rw-r--r--src/slideshow.c28
-rw-r--r--src/tool_image.c5
-rw-r--r--src/tool_select.c6
-rw-r--r--src/tool_text.c15
10 files changed, 152 insertions, 87 deletions
diff --git a/src/mainwindow.c b/src/mainwindow.c
index 56b0e0c..3a3ee1c 100644
--- a/src/mainwindow.c
+++ b/src/mainwindow.c
@@ -228,6 +228,7 @@ static gint about_sig(GtkWidget *widget, struct presentation *p)
static void update_toolbar(struct presentation *p)
{
GtkWidget *d;
+ int cur_slide_number;
d = gtk_ui_manager_get_widget(p->ui, "/ui/displaywindowtoolbar/first");
gtk_widget_set_sensitive(GTK_WIDGET(d), TRUE);
@@ -238,7 +239,8 @@ static void update_toolbar(struct presentation *p)
d = gtk_ui_manager_get_widget(p->ui, "/ui/displaywindowtoolbar/last");
gtk_widget_set_sensitive(GTK_WIDGET(d), TRUE);
- if ( p->view_slide_number == 0 ) {
+ cur_slide_number = slide_number(p, p->cur_edit_slide);
+ if ( cur_slide_number == 0 ) {
d = gtk_ui_manager_get_widget(p->ui,
"/ui/displaywindowtoolbar/first");
@@ -249,7 +251,7 @@ static void update_toolbar(struct presentation *p)
}
- if ( p->view_slide_number == p->num_slides-1 ) {
+ if ( cur_slide_number == p->num_slides-1 ) {
d = gtk_ui_manager_get_widget(p->ui,
"/ui/displaywindowtoolbar/next");
@@ -296,10 +298,12 @@ void notify_slide_update(struct presentation *p)
static gint add_slide_sig(GtkWidget *widget, struct presentation *p)
{
struct slide *new;
+ int cur_slide_number;
- new = add_slide(p, p->view_slide_number);
- p->view_slide = new;
- p->view_slide_number++;
+ cur_slide_number = slide_number(p, p->cur_edit_slide);
+
+ new = add_slide(p, cur_slide_number);
+ p->cur_edit_slide = new;
notify_slide_changed(p);
return FALSE;
@@ -308,8 +312,7 @@ static gint add_slide_sig(GtkWidget *widget, struct presentation *p)
static gint first_slide_sig(GtkWidget *widget, struct presentation *p)
{
- p->view_slide_number = 0;
- p->view_slide = p->slides[0];
+ p->cur_edit_slide = p->slides[0];
notify_slide_changed(p);
return FALSE;
@@ -318,10 +321,12 @@ static gint first_slide_sig(GtkWidget *widget, struct presentation *p)
static gint prev_slide_sig(GtkWidget *widget, struct presentation *p)
{
- if ( p->view_slide_number == 0 ) return FALSE;
+ int cur_slide_number;
+
+ cur_slide_number = slide_number(p, p->cur_edit_slide);
+ if ( cur_slide_number == 0 ) return FALSE;
- p->view_slide_number--;
- p->view_slide = p->slides[p->view_slide_number];
+ p->cur_edit_slide = p->slides[cur_slide_number-1];
notify_slide_changed(p);
return FALSE;
@@ -330,10 +335,12 @@ static gint prev_slide_sig(GtkWidget *widget, struct presentation *p)
static gint next_slide_sig(GtkWidget *widget, struct presentation *p)
{
- if ( p->view_slide_number == p->num_slides-1 ) return FALSE;
+ int cur_slide_number;
+
+ cur_slide_number = slide_number(p, p->cur_edit_slide);
+ if ( cur_slide_number == p->num_slides-1 ) return FALSE;
- p->view_slide_number++;
- p->view_slide = p->slides[p->view_slide_number];
+ p->cur_edit_slide = p->slides[cur_slide_number+1];
notify_slide_changed(p);
return FALSE;
@@ -342,8 +349,7 @@ static gint next_slide_sig(GtkWidget *widget, struct presentation *p)
static gint last_slide_sig(GtkWidget *widget, struct presentation *p)
{
- p->view_slide_number = p->num_slides-1;
- p->view_slide = p->slides[p->view_slide_number];
+ p->cur_edit_slide = p->slides[p->num_slides-1];
notify_slide_changed(p);
return FALSE;
@@ -628,7 +634,7 @@ static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event,
x = event->x - p->border_offs_x;
y = event->y - p->border_offs_y;
- clicked = find_object_at_position(p->view_slide, x, y);
+ clicked = find_object_at_position(p->cur_edit_slide, x, y);
if ( clicked == NULL ) {
@@ -814,8 +820,6 @@ static gboolean expose_sig(GtkWidget *da, GdkEventExpose *event,
GtkAllocation allocation;
double xoff, yoff;
- check_redraw_slide(p->view_slide);
-
cr = gdk_cairo_create(da->window);
/* Overall background */
@@ -837,7 +841,8 @@ static gboolean expose_sig(GtkWidget *da, GdkEventExpose *event,
/* 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->view_slide->render_cache, xoff, yoff);
+ cairo_set_source_surface(cr, p->cur_edit_slide->rendered_edit,
+ xoff, yoff);
cairo_fill(cr);
cairo_translate(cr, xoff, yoff);
@@ -1010,7 +1015,7 @@ static void dnd_receive(GtkWidget *widget, GdkDragContext *drag_context,
gtk_drag_finish(drag_context, TRUE, FALSE, time);
chomp(filename);
- o = add_image_object(p->view_slide,
+ o = add_image_object(p->cur_edit_slide,
p->start_corner_x,
p->start_corner_y,
p->import_width, p->import_height,
@@ -1131,10 +1136,15 @@ int open_mainwindow(struct presentation *p)
gtk_window_set_resizable(GTK_WINDOW(p->window), TRUE);
assert(p->num_slides > 0);
- check_redraw_slide(p->view_slide);
gtk_widget_grab_focus(GTK_WIDGET(p->drawingarea));
gtk_widget_show_all(window);
+
+ p->edit_slide_width = 1024;
+ p->proj_slide_width = 2048;
+ p->thumb_slide_width = 320; /* FIXME: Completely made up */
+ redraw_slide(p->cur_edit_slide);
+
return 0;
}
diff --git a/src/objects.c b/src/objects.c
index be92262..d7ad8a3 100644
--- a/src/objects.c
+++ b/src/objects.c
@@ -152,8 +152,7 @@ void notify_style_update(struct presentation *p, struct style *sty)
if ( s->objects[j]->style != sty ) continue;
s->objects[j]->update_object(s->objects[j]);
- s->object_seq++;
- if ( p->view_slide == s ) changed = 1;
+ if ( p->cur_edit_slide == s ) changed = 1;
break;
}
diff --git a/src/presentation.c b/src/presentation.c
index 68c87c1..1bc5689 100644
--- a/src/presentation.c
+++ b/src/presentation.c
@@ -41,20 +41,19 @@ struct slide *add_slide(struct presentation *p, int pos)
struct slide *new;
int i;
- new = malloc(sizeof(struct slide));
+ new = calloc(1, sizeof(struct slide));
if ( new == NULL ) return NULL;
/* No objects to start with */
new->num_objects = 0;
- new->object_seq = 0;
new->objects = NULL;
p->completely_empty = 0;
new->parent = p;
- new->render_cache_seq = 0;
- new->render_cache = NULL;
- render_slide(new); /* Render nothing, just to make the surface exist */
+ new->rendered_edit = NULL;
+ new->rendered_proj = NULL;
+ new->rendered_thumb = NULL;
try = realloc(p->slides, (1+p->num_slides)*sizeof(struct slide *));
if ( try == NULL ) {
@@ -63,6 +62,7 @@ struct slide *add_slide(struct presentation *p, int pos)
}
p->slides = try;
+ /* Insert into list. Yuk yuk yuk etc. */
if ( (p->num_slides>1) && (pos<p->num_slides-1) ) {
for ( i=p->num_slides; i>pos+1; i-- ) {
@@ -194,6 +194,13 @@ static void update_titlebar(struct presentation *p)
}
+int slide_number(struct presentation *p, struct slide *s)
+{
+ /* FIXME: Implement this */
+ return 0;
+}
+
+
struct presentation *new_presentation()
{
struct presentation *new;
@@ -215,8 +222,8 @@ struct presentation *new_presentation()
/* Add one blank slide and view it */
new->num_slides = 0;
new->slides = NULL;
- new->view_slide = add_slide(new, 0);
- new->view_slide_number = 0;
+ new->cur_edit_slide = add_slide(new, 0);
+ new->cur_proj_slide = NULL;
new->editing_object = NULL;
new->completely_empty = 1;
diff --git a/src/presentation.h b/src/presentation.h
index ed962a8..fdf36b3 100644
--- a/src/presentation.h
+++ b/src/presentation.h
@@ -37,12 +37,15 @@ struct slide
{
struct presentation *parent;
- cairo_surface_t *render_cache;
- int render_cache_seq;
+ /* Any of these may be NULL */
+ cairo_surface_t *rendered_proj;
+ cairo_surface_t *rendered_edit;
+
+ /* This should always be present (and up to date). */
+ cairo_surface_t *rendered_thumb;
int num_objects;
struct object **objects;
- int object_seq;
};
@@ -108,6 +111,28 @@ struct presentation
GtkIMContext *im_context;
GtkWidget *tbox;
+ /* Pointers to the current "editing" and "projection" slides */
+ struct slide *cur_edit_slide;
+ struct slide *cur_proj_slide;
+
+ /* This is the "native" size of the slide. It only exists to give
+ * font size some meaning in the context of a somewhat arbitrary DPI */
+ double slide_width;
+ double slide_height;
+
+ /* Width of a slide in the editor, projector or thumbnail (pixels) */
+ int edit_slide_width;
+ int proj_slide_width;
+ int thumb_slide_width;
+
+ /* This is just to help with rendering the slides within the
+ * editing window. */
+ double border_offs_x;
+ double border_offs_y;
+
+ /* FIXME: Might have more than one object selected at a time. */
+ struct object *editing_object;
+
/* Stylesheet */
StyleSheet *ss;
struct style *default_style;
@@ -122,16 +147,6 @@ struct presentation
int ss_blank;
char ss_geom[256];
- double slide_width;
- double slide_height;
- double border_offs_x;
- double border_offs_y;
-
- /* The slide currently being displayed */
- unsigned int view_slide_number;
- struct slide *view_slide;
- struct object *editing_object;
-
/* Tool status */
struct toolinfo *cur_tool;
@@ -166,4 +181,6 @@ extern void remove_object_from_slide(struct slide *s, struct object *o);
extern struct object *find_object_at_position(struct slide *s,
double x, double y);
+extern int slide_number(struct presentation *p, struct slide *s);
+
#endif /* PRESENTATION_H */
diff --git a/src/slide_render.c b/src/slide_render.c
index e68499a..c0734df 100644
--- a/src/slide_render.c
+++ b/src/slide_render.c
@@ -35,23 +35,22 @@
#include "stylesheet.h"
-int render_slide(struct slide *s)
+static cairo_surface_t *render_slide(struct slide *s, int w, int h)
{
cairo_surface_t *surf;
cairo_t *cr;
int i;
- surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
- s->parent->slide_width,
- s->parent->slide_height);
+ surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
cr = cairo_create(surf);
- cairo_rectangle(cr, 0.0, 0.0,
- s->parent->slide_width, s->parent->slide_height);
+ cairo_rectangle(cr, 0.0, 0.0, w, h);
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_fill(cr);
+ /* FIXME: Set scale such that nominal size fits */
+
for ( i=0; i<s->num_objects; i++ ) {
struct object *o = s->objects[i];
@@ -62,20 +61,54 @@ int render_slide(struct slide *s)
cairo_destroy(cr);
- if ( s->render_cache != NULL ) cairo_surface_destroy(s->render_cache);
- s->render_cache = surf;
- s->render_cache_seq = s->object_seq;
-
- return 0;
+ return surf;
}
-void check_redraw_slide(struct slide *s)
+void redraw_slide(struct slide *s)
{
- /* Update necessary? */
- if ( s->object_seq <= s->render_cache_seq ) return;
+ int w, h;
+
+ if ( s->rendered_thumb != NULL ) {
+ cairo_surface_destroy(s->rendered_thumb);
+ }
+
+ w = s->parent->thumb_slide_width;
+ h = (s->parent->slide_height/s->parent->slide_width) * w;
+ s->rendered_thumb = render_slide(s, w, h);
+ /* FIXME: Request redraw for slide sorter if open */
+
+ /* Is this slide currently open in the editor? */
+ if ( s == s->parent->cur_edit_slide ) {
+
+ if ( s->rendered_edit != NULL ) {
+ cairo_surface_destroy(s->rendered_edit);
+ }
+
+ w = s->parent->edit_slide_width;
+ h = (s->parent->slide_height/s->parent->slide_width) * w;
+ s->rendered_edit = render_slide(s, w, h);
- render_slide(s);
+ gdk_window_invalidate_rect(s->parent->drawingarea->window,
+ NULL, FALSE);
+
+ }
+
+ /* Is this slide currently being displayed on the projector? */
+ if ( s == s->parent->cur_proj_slide ) {
+
+ if ( s->rendered_proj != NULL ) {
+ cairo_surface_destroy(s->rendered_proj);
+ }
+
+ w = s->parent->proj_slide_width;
+ h = (s->parent->slide_height/s->parent->slide_width) * w;
+ s->rendered_proj = render_slide(s, w, h);
+
+ gdk_window_invalidate_rect(s->parent->ss_drawingarea->window,
+ NULL, FALSE);
+
+ }
}
diff --git a/src/slide_render.h b/src/slide_render.h
index 9b1cb02..ac3674d 100644
--- a/src/slide_render.h
+++ b/src/slide_render.h
@@ -30,8 +30,7 @@
#include "presentation.h"
-extern int render_slide(struct slide *s);
-extern void check_redraw_slide(struct slide *s);
+extern void redraw_slide(struct slide *s);
extern void draw_editing_box(cairo_t *cr, double xmin, double ymin,
double width, double height);
diff --git a/src/slideshow.c b/src/slideshow.c
index f5e2fd1..d702513 100644
--- a/src/slideshow.c
+++ b/src/slideshow.c
@@ -51,8 +51,6 @@ static gboolean ss_expose_sig(GtkWidget *da, GdkEventExpose *event,
GtkAllocation allocation;
double xoff, yoff;
- check_redraw_slide(p->view_slide);
-
cr = gdk_cairo_create(da->window);
/* Overall background */
@@ -71,7 +69,7 @@ static gboolean ss_expose_sig(GtkWidget *da, GdkEventExpose *event,
/* 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->view_slide->render_cache,
+ cairo_set_source_surface(cr, p->cur_proj_slide->rendered_proj,
xoff, yoff);
cairo_fill(cr);
@@ -91,14 +89,16 @@ void notify_slideshow_slide_changed(struct presentation *p)
static gint prev_slide_sig(GtkWidget *widget, struct presentation *p)
{
- if ( p->view_slide_number == 0 ) return FALSE;
+ int cur_slide_number;
+
+ cur_slide_number = slide_number(p, p->cur_proj_slide);
+
+ if ( cur_slide_number == 0 ) return FALSE;
- p->view_slide_number--;
p->ss_blank = 0;
- p->view_slide = p->slides[p->view_slide_number];
+ p->cur_proj_slide = p->slides[cur_slide_number-1];
notify_slideshow_slide_changed(p);
- notify_slide_changed(p);
return FALSE;
}
@@ -106,14 +106,16 @@ static gint prev_slide_sig(GtkWidget *widget, struct presentation *p)
static gint next_slide_sig(GtkWidget *widget, struct presentation *p)
{
- if ( p->view_slide_number == p->num_slides-1 ) return FALSE;
+ int cur_slide_number;
+
+ cur_slide_number = slide_number(p, p->cur_proj_slide);
+
+ if ( cur_slide_number == p->num_slides-1 ) return FALSE;
- p->view_slide_number++;
p->ss_blank = 0;
- p->view_slide = p->slides[p->view_slide_number];
+ p->cur_proj_slide = p->slides[cur_slide_number+1];
notify_slideshow_slide_changed(p);
- notify_slide_changed(p);
return FALSE;
}
@@ -124,6 +126,7 @@ void end_slideshow(struct presentation *p)
gtk_widget_destroy(p->ss_drawingarea);
gtk_widget_destroy(p->slideshow);
p->slideshow = NULL;
+ p->cur_proj_slide = NULL;
notify_slide_changed(p);
}
@@ -214,4 +217,7 @@ void try_start_slideshow(struct presentation *p)
p->slideshow = n;
gtk_window_fullscreen(GTK_WINDOW(n));
gtk_widget_show_all(GTK_WIDGET(n));
+
+ p->cur_proj_slide = p->cur_edit_slide;
+ redraw_slide(p->cur_proj_slide);
}
diff --git a/src/tool_image.c b/src/tool_image.c
index 09cc641..2baf7c3 100644
--- a/src/tool_image.c
+++ b/src/tool_image.c
@@ -86,6 +86,8 @@ static void update_image(struct image_object *o)
o->scaled_pb = gdk_pixbuf_scale_simple(i->pb, w, h,
GDK_INTERP_BILINEAR);
} /* else the size didn't change */
+
+ redraw_slide(((struct object *)o)->parent);
}
@@ -153,7 +155,6 @@ struct object *add_image_object(struct slide *s, double x, double y,
free(new);
return NULL;
}
- s->object_seq++;
update_image(new);
@@ -228,10 +229,8 @@ static void end_drag(struct toolinfo *tip, struct presentation *p,
o->bb_width = ti->box_width;
o->bb_height = ti->box_height;
update_image((struct image_object *)o);
- o->parent->object_seq++;
ti->drag_reason = IMAGE_DRAG_REASON_NONE;
- redraw_overlay(p);
}
diff --git a/src/tool_select.c b/src/tool_select.c
index 2327d0d..1fb66c7 100644
--- a/src/tool_select.c
+++ b/src/tool_select.c
@@ -76,10 +76,8 @@ static void drag(struct toolinfo *tip, struct presentation *p,
if ( o->x+o->bb_width > eright ) o->x = eright - o->bb_width;
if ( o->y+o->bb_height > ebottom ) o->y = ebottom - o->bb_height;
- o->update_object(o);
- p->view_slide->object_seq++;
-
- gdk_window_invalidate_rect(p->drawingarea->window, NULL, FALSE);
+ o->update_object(o); /* Object method is responsible for requesting
+ * a redraw */
}
diff --git a/src/tool_text.c b/src/tool_text.c
index 44a477b..8f18c7c 100644
--- a/src/tool_text.c
+++ b/src/tool_text.c
@@ -222,6 +222,8 @@ static void update_text(struct text_object *o)
if ( o->furniture ) {
calculate_position_from_style(o, eright, ebottom, mw, mh);
}
+
+ redraw_slide(((struct object *)o)->parent);
}
@@ -268,7 +270,6 @@ void insert_text(struct object *op, char *t)
update_text(o);
o->insertion_point += tlen;
- o->base.parent->object_seq++;
o->base.empty = 0;
}
@@ -322,9 +323,6 @@ void handle_text_backspace(struct object *op)
if ( strlen(o->text) == 0 ) o->base.empty = 1;
update_text(o);
- o->base.parent->object_seq++;
-
- redraw_overlay(op->parent->parent);
}
@@ -431,7 +429,8 @@ static struct object *add_text_object(struct slide *s, double x, double y,
delete_object((struct object *)new);
return NULL;
}
- s->object_seq++;
+
+ redraw_slide(((struct object *)new)->parent);
return (struct object *)new;
}
@@ -516,10 +515,8 @@ static void end_drag(struct toolinfo *tip, struct presentation *p,
o->bb_width = ti->box_width;
o->bb_height = ti->box_height;
update_text((struct text_object *)o);
- o->parent->object_seq++;
ti->drag_reason = TEXT_DRAG_REASON_NONE;
- redraw_overlay(p);
}
@@ -530,7 +527,7 @@ static void create_default(struct presentation *p, struct style *sty,
struct text_object *o;
struct text_toolinfo *ti = (struct text_toolinfo *)tip;
- n = add_text_object(p->view_slide, 0.0, 0.0, sty, ti);
+ n = add_text_object(p->cur_edit_slide, 0.0, 0.0, sty, ti);
o = (struct text_object *)n;
o->furniture = 1;
update_text(o);
@@ -545,7 +542,7 @@ static void create_region(struct toolinfo *tip, struct presentation *p,
struct text_toolinfo *ti = (struct text_toolinfo *)tip;
struct text_object *o;
- n = add_text_object(p->view_slide, 0.0, 0.0, p->ss->styles[0], ti);
+ n = add_text_object(p->cur_edit_slide, 0.0, 0.0, p->ss->styles[0], ti);
n->x = x1<x2 ? x1 : x2;
n->y = y1<y2 ? y1 : y2;
n->bb_width = fabs(x1-x2);