From c0e27bd0da9c6804c788473b891bff6c0c98af66 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 18 Aug 2019 14:41:31 +0100 Subject: access gtk throbber frames through an interface This changes the gtk throbber frames to be accessed through an API This removes teh nsgtk_throbber global and hides the implementation details from the rest of the code. --- frontends/gtk/scaffolding.c | 34 +++++++++++++++++++++----------- frontends/gtk/throbber.c | 48 ++++++++++++++++++++++++++++++++++++++------- frontends/gtk/throbber.h | 33 +++++++++++++++++++------------ frontends/gtk/toolbar.c | 16 +++++++-------- 4 files changed, 92 insertions(+), 39 deletions(-) diff --git a/frontends/gtk/scaffolding.c b/frontends/gtk/scaffolding.c index e39efc43f..ee08cc187 100644 --- a/frontends/gtk/scaffolding.c +++ b/frontends/gtk/scaffolding.c @@ -349,16 +349,20 @@ static void scaffolding_update_context(struct nsgtk_scaffolding *g) */ static void nsgtk_throb(void *p) { + nserror res; + GdkPixbuf *pixbuf; struct nsgtk_scaffolding *g = p; - if (g->throb_frame >= (nsgtk_throbber->nframes - 1)) { + g->throb_frame++; /* advance to next frame */ + res = nsgtk_throbber_get_frame(g->throb_frame, &pixbuf); + if (res == NSERROR_BAD_SIZE) { g->throb_frame = 1; - } else { - g->throb_frame++; + res = nsgtk_throbber_get_frame(g->throb_frame, &pixbuf); } - gtk_image_set_from_pixbuf(g->throbber, - nsgtk_throbber->framedata[g->throb_frame]); + if (res == NSERROR_OK) { + gtk_image_set_from_pixbuf(g->throbber, pixbuf); + } nsgtk_schedule(100, nsgtk_throb, p); } @@ -2358,11 +2362,19 @@ void gui_window_start_throbber(struct gui_window* _g) void gui_window_stop_throbber(struct gui_window* _g) { + nserror res; + GdkPixbuf *pixbuf; struct nsgtk_scaffolding *g = nsgtk_get_scaffold(_g); - if (g == NULL) + + if (g == NULL) { return; + } + scaffolding_update_context(g); nsgtk_schedule(-1, nsgtk_throb, g); + + g->throb_frame = 0; + if (g->buttons[STOP_BUTTON] != NULL) g->buttons[STOP_BUTTON]->sensitivity = false; if (g->buttons[RELOAD_BUTTON] != NULL) @@ -2370,11 +2382,11 @@ void gui_window_stop_throbber(struct gui_window* _g) nsgtk_scaffolding_set_sensitivity(g); - if ((g->throbber == NULL) || (nsgtk_throbber == NULL) || - (nsgtk_throbber->framedata == NULL) || - (nsgtk_throbber->framedata[0] == NULL)) - return; - gtk_image_set_from_pixbuf(g->throbber, nsgtk_throbber->framedata[0]); + res = nsgtk_throbber_get_frame(g->throb_frame, &pixbuf); + if ((res == NSERROR_OK) && + (g->throbber != NULL)) { + gtk_image_set_from_pixbuf(g->throbber, pixbuf); + } } diff --git a/frontends/gtk/throbber.c b/frontends/gtk/throbber.c index b8efceca1..f94893bef 100644 --- a/frontends/gtk/throbber.c +++ b/frontends/gtk/throbber.c @@ -28,7 +28,16 @@ #include "gtk/resources.h" #include "gtk/throbber.h" -struct nsgtk_throbber *nsgtk_throbber = NULL; +/** + * Throbber images context + */ +struct nsgtk_throbber +{ + int nframes; /**< Number of frames in the throbber */ + GdkPixbuf **framedata; /* pixbuf data for the frames */ +}; + +static struct nsgtk_throbber *nsgtk_throbber = NULL; #define THROBBER_FRAMES 9 #define THROBBER_FMT "throbber/throbber%d.png" @@ -36,10 +45,10 @@ struct nsgtk_throbber *nsgtk_throbber = NULL; /* exported interface documented in gtk/throbber.h */ nserror nsgtk_throbber_init(void) { - struct nsgtk_throbber *throb; /**< structure we generate */ + nserror res = NSERROR_OK; + struct nsgtk_throbber *throb; int frame; char resname[] = THROBBER_FMT; - nserror res = NSERROR_OK; throb = malloc(sizeof(*throb)); if (throb == NULL) { @@ -49,7 +58,7 @@ nserror nsgtk_throbber_init(void) throb->framedata = malloc(sizeof(GdkPixbuf *) * THROBBER_FRAMES); if (throb->framedata == NULL) { free(throb); - return false; + return NSERROR_NOMEM; } for (frame = 0; frame < THROBBER_FRAMES; frame++) { @@ -73,11 +82,9 @@ nserror nsgtk_throbber_init(void) throb->nframes = frame; nsgtk_throbber = throb; return res; - - } - +/* exported interface documented in gtk/throbber.h */ void nsgtk_throbber_finalise(void) { int i; @@ -91,3 +98,30 @@ void nsgtk_throbber_finalise(void) nsgtk_throbber = NULL; } + +/* exported interface documented in gtk/throbber.h */ +nserror nsgtk_throbber_get_frame(int frame, GdkPixbuf **pixbuf) +{ + nserror res = NSERROR_OK; + + /* ensure initialisation */ + if (nsgtk_throbber == NULL) { + res = nsgtk_throbber_init(); + } + if (res != NSERROR_OK) { + return res; + } + + /* ensure frame in range */ + if ((frame < 0) || (frame >= nsgtk_throbber->nframes)) { + return NSERROR_BAD_SIZE; + } + + /* ensure there is frame data */ + if (nsgtk_throbber->framedata[frame] == NULL) { + return NSERROR_INVALID; + } + + *pixbuf = nsgtk_throbber->framedata[frame]; + return NSERROR_OK; +} diff --git a/frontends/gtk/throbber.h b/frontends/gtk/throbber.h index e0b47e15c..c8529d2e2 100644 --- a/frontends/gtk/throbber.h +++ b/frontends/gtk/throbber.h @@ -16,20 +16,27 @@ * along with this program. If not, see . */ -#ifndef __GTK_THROBBER_H__ -#define __GTK_THROBBER_H__ - -#include - -struct nsgtk_throbber -{ - int nframes; /**< Number of frames in the throbber */ - GdkPixbuf **framedata; -}; - -extern struct nsgtk_throbber *nsgtk_throbber; +#ifndef NETSURF_GTK_THROBBER_H +#define NETSURF_GTK_THROBBER_H +/** + * Initialise global throbber context + */ nserror nsgtk_throbber_init(void); + +/** + * release global throbber context + */ void nsgtk_throbber_finalise(void); -#endif /* __GTK_THROBBER_H__ */ +/** + * get the pixbuf of a given frame of the throbber + * + * \param frame The frame number starting at 0 for stopped frame + * \param pixbuf updated on success + * \return NSERROR_OK and pixbuf updated on success, NSERROR_BAD_SIZE if frame + * is out of range else error code. + */ +nserror nsgtk_throbber_get_frame(int frame, GdkPixbuf **pixbuf); + +#endif /* NETSURF_GTK_THROBBER_H */ diff --git a/frontends/gtk/toolbar.c b/frontends/gtk/toolbar.c index d1b129afd..4ca03a1ea 100644 --- a/frontends/gtk/toolbar.c +++ b/frontends/gtk/toolbar.c @@ -478,23 +478,23 @@ nsgtk_toolbar_make_widget(struct nsgtk_scaffolding *g, } case THROBBER_ITEM: { - if ((nsgtk_throbber == NULL) || - (nsgtk_throbber->framedata == NULL) || - (nsgtk_throbber->framedata[0] == NULL)) { + nserror res; + GdkPixbuf *pixbuf; + res = nsgtk_throbber_get_frame(0, &pixbuf); + if (res != NSERROR_OK) { return NULL; } if (edit_mode) { - w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( - gtk_image_new_from_pixbuf( - nsgtk_throbber->framedata[0])), - "[throbber]")); + w = GTK_WIDGET(gtk_tool_button_new( + GTK_WIDGET(gtk_image_new_from_pixbuf(pixbuf)), + "[throbber]")); } else { GtkWidget *image; w = GTK_WIDGET(gtk_tool_item_new()); - image = gtk_image_new_from_pixbuf(nsgtk_throbber->framedata[0]); + image = gtk_image_new_from_pixbuf(pixbuf); if (image != NULL) { nsgtk_widget_set_alignment(image, GTK_ALIGN_CENTER, -- cgit v1.2.3