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.
This commit is contained in:
Vincent Sanders 2019-08-18 14:41:31 +01:00
parent 01f3879b64
commit c0e27bd0da
4 changed files with 92 additions and 39 deletions

View File

@ -349,16 +349,20 @@ static void scaffolding_update_context(struct nsgtk_scaffolding *g)
*/ */
static void nsgtk_throb(void *p) static void nsgtk_throb(void *p)
{ {
nserror res;
GdkPixbuf *pixbuf;
struct nsgtk_scaffolding *g = p; 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; g->throb_frame = 1;
} else { res = nsgtk_throbber_get_frame(g->throb_frame, &pixbuf);
g->throb_frame++;
} }
gtk_image_set_from_pixbuf(g->throbber, if (res == NSERROR_OK) {
nsgtk_throbber->framedata[g->throb_frame]); gtk_image_set_from_pixbuf(g->throbber, pixbuf);
}
nsgtk_schedule(100, nsgtk_throb, p); 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) void gui_window_stop_throbber(struct gui_window* _g)
{ {
nserror res;
GdkPixbuf *pixbuf;
struct nsgtk_scaffolding *g = nsgtk_get_scaffold(_g); struct nsgtk_scaffolding *g = nsgtk_get_scaffold(_g);
if (g == NULL)
if (g == NULL) {
return; return;
}
scaffolding_update_context(g); scaffolding_update_context(g);
nsgtk_schedule(-1, nsgtk_throb, g); nsgtk_schedule(-1, nsgtk_throb, g);
g->throb_frame = 0;
if (g->buttons[STOP_BUTTON] != NULL) if (g->buttons[STOP_BUTTON] != NULL)
g->buttons[STOP_BUTTON]->sensitivity = false; g->buttons[STOP_BUTTON]->sensitivity = false;
if (g->buttons[RELOAD_BUTTON] != NULL) if (g->buttons[RELOAD_BUTTON] != NULL)
@ -2370,11 +2382,11 @@ void gui_window_stop_throbber(struct gui_window* _g)
nsgtk_scaffolding_set_sensitivity(g); nsgtk_scaffolding_set_sensitivity(g);
if ((g->throbber == NULL) || (nsgtk_throbber == NULL) || res = nsgtk_throbber_get_frame(g->throb_frame, &pixbuf);
(nsgtk_throbber->framedata == NULL) || if ((res == NSERROR_OK) &&
(nsgtk_throbber->framedata[0] == NULL)) (g->throbber != NULL)) {
return; gtk_image_set_from_pixbuf(g->throbber, pixbuf);
gtk_image_set_from_pixbuf(g->throbber, nsgtk_throbber->framedata[0]); }
} }

View File

@ -28,7 +28,16 @@
#include "gtk/resources.h" #include "gtk/resources.h"
#include "gtk/throbber.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_FRAMES 9
#define THROBBER_FMT "throbber/throbber%d.png" #define THROBBER_FMT "throbber/throbber%d.png"
@ -36,10 +45,10 @@ struct nsgtk_throbber *nsgtk_throbber = NULL;
/* exported interface documented in gtk/throbber.h */ /* exported interface documented in gtk/throbber.h */
nserror nsgtk_throbber_init(void) nserror nsgtk_throbber_init(void)
{ {
struct nsgtk_throbber *throb; /**< structure we generate */ nserror res = NSERROR_OK;
struct nsgtk_throbber *throb;
int frame; int frame;
char resname[] = THROBBER_FMT; char resname[] = THROBBER_FMT;
nserror res = NSERROR_OK;
throb = malloc(sizeof(*throb)); throb = malloc(sizeof(*throb));
if (throb == NULL) { if (throb == NULL) {
@ -49,7 +58,7 @@ nserror nsgtk_throbber_init(void)
throb->framedata = malloc(sizeof(GdkPixbuf *) * THROBBER_FRAMES); throb->framedata = malloc(sizeof(GdkPixbuf *) * THROBBER_FRAMES);
if (throb->framedata == NULL) { if (throb->framedata == NULL) {
free(throb); free(throb);
return false; return NSERROR_NOMEM;
} }
for (frame = 0; frame < THROBBER_FRAMES; frame++) { for (frame = 0; frame < THROBBER_FRAMES; frame++) {
@ -73,11 +82,9 @@ nserror nsgtk_throbber_init(void)
throb->nframes = frame; throb->nframes = frame;
nsgtk_throbber = throb; nsgtk_throbber = throb;
return res; return res;
} }
/* exported interface documented in gtk/throbber.h */
void nsgtk_throbber_finalise(void) void nsgtk_throbber_finalise(void)
{ {
int i; int i;
@ -91,3 +98,30 @@ void nsgtk_throbber_finalise(void)
nsgtk_throbber = NULL; 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;
}

View File

@ -16,20 +16,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __GTK_THROBBER_H__ #ifndef NETSURF_GTK_THROBBER_H
#define __GTK_THROBBER_H__ #define NETSURF_GTK_THROBBER_H
#include <gtk/gtk.h>
struct nsgtk_throbber
{
int nframes; /**< Number of frames in the throbber */
GdkPixbuf **framedata;
};
extern struct nsgtk_throbber *nsgtk_throbber;
/**
* Initialise global throbber context
*/
nserror nsgtk_throbber_init(void); nserror nsgtk_throbber_init(void);
/**
* release global throbber context
*/
void nsgtk_throbber_finalise(void); 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 */

View File

@ -478,23 +478,23 @@ nsgtk_toolbar_make_widget(struct nsgtk_scaffolding *g,
} }
case THROBBER_ITEM: { case THROBBER_ITEM: {
if ((nsgtk_throbber == NULL) || nserror res;
(nsgtk_throbber->framedata == NULL) || GdkPixbuf *pixbuf;
(nsgtk_throbber->framedata[0] == NULL)) { res = nsgtk_throbber_get_frame(0, &pixbuf);
if (res != NSERROR_OK) {
return NULL; return NULL;
} }
if (edit_mode) { if (edit_mode) {
w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( w = GTK_WIDGET(gtk_tool_button_new(
gtk_image_new_from_pixbuf( GTK_WIDGET(gtk_image_new_from_pixbuf(pixbuf)),
nsgtk_throbber->framedata[0])),
"[throbber]")); "[throbber]"));
} else { } else {
GtkWidget *image; GtkWidget *image;
w = GTK_WIDGET(gtk_tool_item_new()); 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) { if (image != NULL) {
nsgtk_widget_set_alignment(image, nsgtk_widget_set_alignment(image,
GTK_ALIGN_CENTER, GTK_ALIGN_CENTER,