From 02c75d07900d4566a8b2f835fb07a4eff1ab8235 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Tue, 20 Aug 2019 16:13:00 +0100 Subject: working throbber --- frontends/gtk/scaffolding.c | 75 +++++------------------ frontends/gtk/scaffolding.h | 3 - frontends/gtk/toolbar.c | 144 ++++++++++++++++++++++++++++++++++++++++---- frontends/gtk/toolbar.h | 8 +++ frontends/gtk/window.c | 7 ++- 5 files changed, 161 insertions(+), 76 deletions(-) (limited to 'frontends/gtk') diff --git a/frontends/gtk/scaffolding.c b/frontends/gtk/scaffolding.c index f9eab820a..6ff62a103 100644 --- a/frontends/gtk/scaffolding.c +++ b/frontends/gtk/scaffolding.c @@ -70,6 +70,7 @@ #include "gtk/search.h" #include "gtk/throbber.h" #include "gtk/toolbar.h" +#include "gtk/toolbar_items.h" #include "gtk/window.h" #include "gtk/gdk.h" #include "gtk/scaffolding.h" @@ -102,6 +103,13 @@ static gboolean nsgtk_on_##q##_activate_menu(GtkMenuItem *widget, gpointer data) #define BUTTONHANDLER(q)\ static gboolean nsgtk_on_##q##_activate(GtkButton *widget, gpointer data) + +struct nsgtk_menu { + GtkWidget *main; /* left click menu entry */ + GtkWidget *rclick; /* right click menu */ + GtkWidget *popup; /* popup menu entry */ +}; + /** Core scaffolding structure. */ struct nsgtk_scaffolding { /** global linked list of scaffolding for gui interface adjustments */ @@ -132,6 +140,9 @@ struct nsgtk_scaffolding { /** link popup menu */ struct nsgtk_link_menu *link_menu; + + /** menu entries widgets for sensativity adjustment */ + struct nsgtk_menu menus[PLACEHOLDER_BUTTON]; }; /** current scaffold for model dialogue use */ @@ -324,34 +335,6 @@ static void scaffolding_update_context(struct nsgtk_scaffolding *g) } -/** - * Make the throbber run. - * - * scheduled callback to update the throbber - * - * \param p The context passed when scheduled. - */ -static void nsgtk_throb(void *p) -{ -#if 0 - nserror res; - GdkPixbuf *pixbuf; - struct nsgtk_scaffolding *g = p; - - 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; - res = nsgtk_throbber_get_frame(g->throb_frame, &pixbuf); - } - - if (res == NSERROR_OK) { - gtk_image_set_from_pixbuf(g->throbber, pixbuf); - } - - nsgtk_schedule(100, nsgtk_throb, p); -#endif -} /** @@ -2115,23 +2098,20 @@ nserror gui_window_set_url(struct gui_window *gw, nsurl *url) return NSERROR_OK; } -void gui_window_start_throbber(struct gui_window* _g) -{ + #if 0 +static nserror gui_window_start_throbber(struct gui_window* gw) +{ struct nsgtk_scaffolding *g = nsgtk_get_scaffold(_g); g->buttons[STOP_BUTTON]->sensitivity = true; g->buttons[RELOAD_BUTTON]->sensitivity = false; nsgtk_scaffolding_set_sensitivity(g); scaffolding_update_context(g); - - nsgtk_schedule(100, nsgtk_throb, g); -#endif } -void gui_window_stop_throbber(struct gui_window* _g) +static nserror gui_window_stop_throbber(struct gui_window* gw) { -#if 0 nserror res; GdkPixbuf *pixbuf; struct nsgtk_scaffolding *g = nsgtk_get_scaffold(_g); @@ -2140,10 +2120,6 @@ void gui_window_stop_throbber(struct gui_window* _g) 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; @@ -2152,13 +2128,8 @@ void gui_window_stop_throbber(struct gui_window* _g) nsgtk_scaffolding_set_sensitivity(g); - res = nsgtk_throbber_get_frame(g->throb_frame, &pixbuf); - if ((res == NSERROR_OK) && - (g->throbber != NULL)) { - gtk_image_set_from_pixbuf(g->throbber, pixbuf); - } -#endif } +#endif static void @@ -2347,15 +2318,6 @@ void nsgtk_scaffolding_reset_offset(struct nsgtk_scaffolding *g) } -/* exported interface documented in gtk/scaffolding.h */ -void nsgtk_scaffolding_update_throbber_ref(struct nsgtk_scaffolding *g) -{ -#if 0 - g->throbber = GTK_IMAGE(gtk_bin_get_child( - GTK_BIN(g->buttons[THROBBER_ITEM]->button))); -#endif -} - /* exported interface documented in gtk/scaffolding.h */ void nsgtk_scaffolding_update_websearch_ref(struct nsgtk_scaffolding *g) { @@ -2433,11 +2395,6 @@ void nsgtk_scaffolding_set_sensitivity(struct nsgtk_scaffolding *g) gtk_widget_set_sensitive(GTK_WIDGET(\ g->buttons[i]->rclick),\ g->buttons[i]->sensitivity);\ - if ((g->buttons[i]->location != -1) && \ - (g->buttons[i]->button != NULL))\ - gtk_widget_set_sensitive(GTK_WIDGET(\ - g->buttons[i]->button),\ - g->buttons[i]->sensitivity);\ if (g->buttons[i]->popup != NULL)\ gtk_widget_set_sensitive(GTK_WIDGET(\ g->buttons[i]->popup),\ diff --git a/frontends/gtk/scaffolding.h b/frontends/gtk/scaffolding.h index a3e6155ed..c5f8a4721 100644 --- a/frontends/gtk/scaffolding.h +++ b/frontends/gtk/scaffolding.h @@ -112,7 +112,6 @@ void nsgtk_scaffolding_reset_offset(struct nsgtk_scaffolding *g); */ struct nsgtk_scaffolding *nsgtk_scaffolding_iterate(struct nsgtk_scaffolding *g); -void nsgtk_scaffolding_update_throbber_ref(struct nsgtk_scaffolding *g); void nsgtk_scaffolding_update_websearch_ref(struct nsgtk_scaffolding *g); @@ -172,8 +171,6 @@ nserror nsgtk_scaffolding_new_tab(struct gui_window *gw); void nsgtk_window_set_title(struct gui_window *gw, const char *title); nserror gui_window_set_url(struct gui_window *g, struct nsurl *url); -void gui_window_start_throbber(struct gui_window *g); -void gui_window_stop_throbber(struct gui_window *g); /** * toolbar style changed diff --git a/frontends/gtk/toolbar.c b/frontends/gtk/toolbar.c index 724e3735d..3ef753cde 100644 --- a/frontends/gtk/toolbar.c +++ b/frontends/gtk/toolbar.c @@ -44,9 +44,16 @@ #include "gtk/toolbar_items.h" #include "gtk/toolbar.h" -/** button location indicating button is not to be shown */ +/** + * button location indicating button is not to be shown + */ #define INACTIVE_LOCATION (-1) +/** + * time (in ms) between throbber animation frame updates + */ +#define THROBBER_FRAME_TIME (100) + /** * toolbar item context */ @@ -54,9 +61,6 @@ struct nsgtk_toolbar_item { GtkToolItem *button; int location; /* in toolbar */ bool sensitivity; - GtkWidget *main; /* left click menu entry */ - GtkWidget *rclick; /* right click menu */ - GtkWidget *popup; /* popup menu entry */ void *mhandler; /* menu item clicked */ void *bhandler; /* button clicked */ void *dataplus; /* customization -> toolbar */ @@ -83,9 +87,6 @@ struct nsgtk_toolbar { /** Completions for url_bar */ GtkEntryCompletion *url_bar_completion; - /** Activity throbber */ - GtkImage *throbber; - /** Current frame of throbber animation */ int throb_frame; @@ -151,7 +152,6 @@ typedef enum search_buttons { struct nsgtk_theme { GtkImage *image[PLACEHOLDER_BUTTON]; GtkImage *searchimage[SEARCH_BUTTONS_COUNT]; - /* apng throbber element */ }; @@ -364,6 +364,7 @@ void nsgtk_theme_implement(struct nsgtk_scaffolding *g) if (button == NULL) continue; + #if 0 /* gtk_image_menu_item_set_image accepts NULL image */ if ((button->main != NULL) && (theme[IMAGE_SET_MAIN_MENU] != NULL)) { @@ -371,7 +372,7 @@ void nsgtk_theme_implement(struct nsgtk_scaffolding *g) GTK_WIDGET(button->main), GTK_WIDGET(theme[IMAGE_SET_MAIN_MENU]->image[i])); gtk_widget_show_all(GTK_WIDGET(button->main)); - } + } if ((button->rclick != NULL) && (theme[IMAGE_SET_RCLICK_MENU] != NULL)) { nsgtk_image_menu_item_set_image(GTK_WIDGET(button->rclick), @@ -388,6 +389,7 @@ void nsgtk_theme_implement(struct nsgtk_scaffolding *g) image[i])); gtk_widget_show_all(GTK_WIDGET(button->popup)); } + #endif if ((button->location != -1) && (button->button != NULL) && (theme[IMAGE_SET_BUTTONS] != NULL)) { gtk_tool_button_set_icon_widget( @@ -546,7 +548,7 @@ make_toolbar_item(nsgtk_toolbar_button i, struct nsgtk_theme *theme) w = GTK_WIDGET(gtk_tool_button_new(GTK_WIDGET( \ theme->image[p##_BUTTON]), q)); \ } \ - break; \ + break; \ } MAKE_STOCKBUTTON(HOME, NSGTK_STOCK_HOME) @@ -1409,7 +1411,7 @@ static void nsgtk_scaffolding_update_url_bar_ref(struct nsgtk_scaffolding *g) static void nsgtk_toolbar_set_handler(struct nsgtk_scaffolding *g, nsgtk_toolbar_button i) { - switch(i){ + switch(i) { case URL_BAR_ITEM: nsgtk_scaffolding_update_url_bar_ref(g); g_signal_connect(GTK_WIDGET(nsgtk_scaffolding_urlbar(g)), @@ -1421,7 +1423,6 @@ nsgtk_toolbar_set_handler(struct nsgtk_scaffolding *g, nsgtk_toolbar_button i) break; case THROBBER_ITEM: - nsgtk_scaffolding_update_throbber_ref(g); break; case WEBSEARCH_ITEM: @@ -1556,6 +1557,9 @@ add_item_to_toolbar(struct nsgtk_toolbar *tb, tb->buttons[bidx]->button = GTK_TOOL_ITEM( make_toolbar_item(bidx, theme)); + gtk_widget_set_sensitive(tb->buttons[bidx]->button, + tb->buttons[bidx]->sensitivity); + gtk_toolbar_insert(tb->widget, tb->buttons[bidx]->button, location); @@ -1640,6 +1644,91 @@ toolbar_item_create(nsgtk_toolbar_button id, return NSERROR_OK; } +/** + * set a toolbar items sensitivity + * + * note this does not set menu items sensitivity + */ +static nserror +set_item_sensitivity(struct nsgtk_toolbar_item *item, bool sensitivity) +{ + if (item->sensitivity == sensitivity) { + /* item does not require sensitivity changing */ + return NSERROR_OK; + } + item->sensitivity = sensitivity; + + if ((item->location != -1) && (item->button != NULL)) { + gtk_widget_set_sensitive(GTK_WIDGET(item->button), + item->sensitivity); + } + + return NSERROR_OK; + +} + +/** + * set a toolbar item to a throbber frame number + * + * \param toolbar_item The toolbar item to update + * \param frame The animation frame number to update to + * \return NSERROR_OK on success, + * NSERROR_INVALID if the toolbar item does not contain an image, + * NSERROR_BAD_SIZE if the frame is out of range. + */ +static nserror set_throbber_frame(GtkToolItem *toolbar_item, int frame) +{ + nserror res; + GdkPixbuf *pixbuf; + GtkImage *throbber; + + if (toolbar_item == NULL) { + /* no toolbar item */ + return NSERROR_INVALID; + } + + res = nsgtk_throbber_get_frame(frame, &pixbuf); + if (res != NSERROR_OK) { + return res; + } + + throbber = GTK_IMAGE(gtk_bin_get_child(GTK_BIN(toolbar_item))); + + gtk_image_set_from_pixbuf(throbber, pixbuf); + + return NSERROR_OK; +} + + +/** + * Make the throbber run. + * + * scheduled callback to update the throbber + * + * \param p The context passed when scheduled. + */ +static void next_throbber_frame(void *p) +{ + struct nsgtk_toolbar *tb = p; + nserror res; + + tb->throb_frame++; /* advance to next frame */ + + res = set_throbber_frame(tb->buttons[THROBBER_ITEM]->button, + tb->throb_frame); + if (res == NSERROR_BAD_SIZE) { + tb->throb_frame = 1; + res = set_throbber_frame(tb->buttons[THROBBER_ITEM]->button, + tb->throb_frame); + } + + /* only schedule next frame if there are no errors */ + if (res == NSERROR_OK) { + nsgtk_schedule(THROBBER_FRAME_TIME, next_throbber_frame, p); + } +} + + /* exported interface documented in toolbar.h */ nserror nsgtk_toolbar_create(GtkBuilder *builder, struct nsgtk_toolbar **tb_out) { @@ -1750,3 +1839,34 @@ nserror nsgtk_toolbar_update(struct nsgtk_toolbar *tb) return NSERROR_OK; } + + +/* exported interface documented in toolbar.h */ +nserror nsgtk_toolbar_throbber(struct nsgtk_toolbar *tb, bool active) +{ + nserror res; + GdkPixbuf *pixbuf; + + /* when activating the throbber simply schedule the next frame update */ + if (active) { + nsgtk_schedule(THROBBER_FRAME_TIME, next_throbber_frame, tb); + + set_item_sensitivity(tb->buttons[STOP_BUTTON], true); + set_item_sensitivity(tb->buttons[RELOAD_BUTTON], false); + + return NSERROR_OK; + } + + /* stopping the throbber */ + nsgtk_schedule(-1, next_throbber_frame, tb); + tb->throb_frame = 0; + res = set_throbber_frame(tb->buttons[THROBBER_ITEM]->button, + tb->throb_frame); + + /* adjust sensitivity of other items */ + set_item_sensitivity(tb->buttons[STOP_BUTTON], false); + set_item_sensitivity(tb->buttons[RELOAD_BUTTON], true); + + return res; +} + diff --git a/frontends/gtk/toolbar.h b/frontends/gtk/toolbar.h index afce22eeb..2744d1f66 100644 --- a/frontends/gtk/toolbar.h +++ b/frontends/gtk/toolbar.h @@ -52,6 +52,14 @@ nserror nsgtk_toolbar_destroy(struct nsgtk_toolbar *toolbar); */ nserror nsgtk_toolbar_update(struct nsgtk_toolbar *tb); +/** + * Start or stop a throbber in a toolbar + * + * \param toolbar A toolbar returned from a creation + * \param active Trie if the throbber animation should play. + * \return NSERROR_OK on success + */ +nserror nsgtk_toolbar_throbber(struct nsgtk_toolbar *tb, bool active); /** * sets up the images for scaffolding. diff --git a/frontends/gtk/window.c b/frontends/gtk/window.c index 1c21a3eb6..4f8be47bd 100644 --- a/frontends/gtk/window.c +++ b/frontends/gtk/window.c @@ -52,6 +52,7 @@ #include "gtk/compat.h" #include "gtk/gui.h" #include "gtk/scaffolding.h" +#include "gtk/toolbar.h" #include "gtk/local_history.h" #include "gtk/plotters.h" #include "gtk/schedule.h" @@ -1344,11 +1345,13 @@ gui_window_event(struct gui_window *gw, enum gui_window_event event) break; case GW_EVENT_START_THROBBER: - gui_window_start_throbber(gw); + nsgtk_toolbar_throbber(gw->toolbar, true); + /** \todo menu sensitivity for back/reload */ break; case GW_EVENT_STOP_THROBBER: - gui_window_stop_throbber(gw); + nsgtk_toolbar_throbber(gw->toolbar, false); + /** \todo menu sensitivity for back/reload */ break; default: -- cgit v1.2.3