diff options
Diffstat (limited to 'riscos/gui/progress_bar.c')
-rw-r--r-- | riscos/gui/progress_bar.c | 535 |
1 files changed, 0 insertions, 535 deletions
diff --git a/riscos/gui/progress_bar.c b/riscos/gui/progress_bar.c deleted file mode 100644 index 3ec6b3aa8..000000000 --- a/riscos/gui/progress_bar.c +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Copyright 2006 Richard Wilson <info@tinct.net> - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf 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; version 2 of the License. - * - * NetSurf 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 <http://www.gnu.org/licenses/>. - */ - -/** \file - * Progress bar (implementation). - */ - -#include <assert.h> -#include <stdbool.h> -#include <string.h> -#include "swis.h" -#include "oslib/colourtrans.h" -#include "oslib/os.h" -#include "oslib/osspriteop.h" -#include "oslib/wimp.h" -#include "oslib/wimpspriteop.h" - -#include "desktop/plotters.h" -#include "utils/log.h" -#include "utils/utils.h" - -#include "riscos/gui.h" -#include "riscos/tinct.h" -#include "riscos/wimp_event.h" -#include "riscos/gui/progress_bar.h" - -#define MARGIN 6 - -struct progress_bar { - wimp_w w; /**< progress bar window handle */ - unsigned int range; /**< progress bar range */ - unsigned int value; /**< progress bar value */ - char icon[13]; /**< current icon */ - int offset; /**< progress bar rotation */ - os_box visible; /**< progress bar position */ - int icon_x0; /**< icon x0 */ - int icon_y0; /**< icon y0 */ - osspriteop_header *icon_img; /**< icon image */ - bool animating; /**< progress bar is animating */ - bool recalculate; /**< recalculation required */ - int cur_width; /**< current calculated width */ - int cur_height; /**< current calculated height */ - bool icon_obscured; /**< icon is partially obscured */ -}; - -static char progress_animation_sprite[] = "progress"; -static osspriteop_header *progress_icon; -static unsigned int progress_width; -static unsigned int progress_height; - -struct wimp_window_base progress_bar_definition = { - {0, 0, 1, 1}, - 0, - 0, - wimp_TOP, - wimp_WINDOW_NEW_FORMAT | wimp_WINDOW_MOVEABLE | wimp_WINDOW_NO_BOUNDS, - 0xff, - wimp_COLOUR_LIGHT_GREY, - wimp_COLOUR_LIGHT_GREY, - wimp_COLOUR_VERY_LIGHT_GREY, - wimp_COLOUR_DARK_GREY, - wimp_COLOUR_MID_LIGHT_GREY, - wimp_COLOUR_CREAM, - wimp_WINDOW_NEVER3D | 0x16u /* RISC OS 5.03+ */, - {0, 0, 65535, 65535}, - 0, - 0, - wimpspriteop_AREA, - 1, - 1, - {""}, - 0 -}; - - -static void ro_gui_progress_bar_calculate(struct progress_bar *pb, int width, - int height); -static void ro_gui_progress_bar_redraw(wimp_draw *redraw); -static void ro_gui_progress_bar_redraw_window(wimp_draw *redraw, - struct progress_bar *pb); -static void ro_gui_progress_bar_animate(void *p); - - -/** - * Initialise the progress bar - * - * \param icons the sprite area to use for icons - */ -void ro_gui_progress_bar_init(osspriteop_area *icons) -{ - const char *name = progress_animation_sprite; - os_error *error; - - progress_bar_definition.sprite_area = icons; - - progress_icon = NULL; - error = xosspriteop_select_sprite(osspriteop_USER_AREA, - progress_bar_definition.sprite_area, - (osspriteop_id) name, &progress_icon); - if (!error) { - xosspriteop_read_sprite_info(osspriteop_USER_AREA, - progress_bar_definition.sprite_area, - (osspriteop_id) name, - (int *) &progress_width, (int *) &progress_height, - 0, 0); - } -} - - -/** - * Create a new progress bar - */ -struct progress_bar *ro_gui_progress_bar_create(void) -{ - struct progress_bar *pb; - os_error *error; - - pb = calloc(1, sizeof(*pb)); - if (!pb) - return NULL; - - error = xwimp_create_window((wimp_window *)&progress_bar_definition, - &pb->w); - if (error) { - LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); - free(pb); - return NULL; - } - - ro_gui_wimp_event_register_redraw_window(pb->w, - ro_gui_progress_bar_redraw); - ro_gui_wimp_event_set_user_data(pb->w, pb); - return pb; -} - - -/** - * Destroy a progress bar and free all associated resources - * - * \param pb the progress bar to destroy - */ -void ro_gui_progress_bar_destroy(struct progress_bar *pb) -{ - os_error *error; - assert(pb); - - if (pb->animating) { - riscos_schedule(-1, ro_gui_progress_bar_animate, pb); - } - ro_gui_wimp_event_finalise(pb->w); - error = xwimp_delete_window(pb->w); - if (error) { - LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess); - } - - free(pb); -} - - -/** - * Get the handle of the window that represents a progress bar - * - * \param pb the progress bar to get the window handle of - * \return the progress bar's window handle - */ -wimp_w ro_gui_progress_bar_get_window(struct progress_bar *pb) -{ - assert(pb); - - return pb->w; -} - - -/** - * Set the icon for a progress bar - * - * \param pb the progress bar to set the icon for - * \param icon the icon to use, or NULL for no icon - */ -void ro_gui_progress_bar_set_icon(struct progress_bar *pb, const char *icon) -{ - assert(pb); - - if (!strcmp(icon, pb->icon)) - return; - if (!icon) - pb->icon[0] = '\0'; - else { - strncpy(pb->icon, icon, 12); - pb->icon[12] = '\0'; - } - pb->recalculate = true; - xwimp_force_redraw(pb->w, 0, 0, 32, 32); - ro_gui_progress_bar_update(pb, pb->cur_width, pb->cur_height); -} - - -/** - * Set the value of a progress bar - * - * \param pb the progress bar to set the value for - * \param value the value to use - */ -void ro_gui_progress_bar_set_value(struct progress_bar *pb, unsigned int value) -{ - assert(pb); - - pb->value = value; - if (pb->value > pb->range) - pb->range = pb->value; - ro_gui_progress_bar_update(pb, pb->cur_width, pb->cur_height); -} - - -/** - * Get the value of a progress bar - * - * \param pb the progress bar to get the value of - * \return the current value - */ -unsigned int ro_gui_progress_bar_get_value(struct progress_bar *pb) -{ - assert(pb); - - return pb->value; -} - - -/** - * Set the range of a progress bar - * - * \param pb the progress bar to set the range for - * \param range the range to use - */ -void ro_gui_progress_bar_set_range(struct progress_bar *pb, unsigned int range) -{ - assert(pb); - - pb->range = range; - if (pb->value > pb->range) - pb->value = pb->range; - ro_gui_progress_bar_update(pb, pb->cur_width, pb->cur_height); -} - - -/** - * Get the range of a progress bar - * - * \param pb the progress bar to get the range of - * \return the current range - */ -unsigned int ro_gui_progress_bar_get_range(struct progress_bar *pb) -{ - assert(pb); - - return pb->range; -} - - -/** - * Update the progress bar to a new dimension. - * - * \param pb the progress bar to update - * \param width the new progress bar width - * \param height the new progress bar height - */ -void ro_gui_progress_bar_update(struct progress_bar *pb, int width, int height) -{ - wimp_draw redraw; - os_error *error; - osbool more; - os_box cur; - - /* don't allow negative dimensions */ - width = max(width, 0); - height = max(height, 0); - - /* update the animation state */ - if ((pb->value == 0) || (pb->value == pb->range)) { - if (pb->animating) { - riscos_schedule(-1, ro_gui_progress_bar_animate, pb); - } - pb->animating = false; - } else { - if (!pb->animating) { - riscos_schedule(200, ro_gui_progress_bar_animate, pb); - } - pb->animating = true; - } - - /* get old and new positions */ - cur = pb->visible; - pb->recalculate = true; - ro_gui_progress_bar_calculate(pb, width, height); - - /* see if the progress bar hasn't moved. we don't need to consider - * the left edge moving as this is handled by the icon setting - * function */ - if (cur.x1 == pb->visible.x1) - return; - - /* if size has decreased then we must force a redraw */ - if (cur.x1 > pb->visible.x1) { - xwimp_force_redraw(pb->w, pb->visible.x1, pb->visible.y0, - cur.x1, pb->visible.y1); - return; - } - - /* perform a minimal redraw update */ - redraw.w = pb->w; - redraw.box = pb->visible; - redraw.box.x0 = cur.x1; - error = xwimp_update_window(&redraw, &more); - if (error) { - LOG("Error getting update window: 0x%x: %s", error->errnum, error->errmess); - return; - } - if (more) - ro_gui_progress_bar_redraw_window(&redraw, pb); -} - - -/** - * Process a WIMP redraw request - * - * \param redraw the redraw request to process - */ -void ro_gui_progress_bar_redraw(wimp_draw *redraw) -{ - struct progress_bar *pb; - os_error *error; - osbool more; - - pb = (struct progress_bar *)ro_gui_wimp_event_get_user_data(redraw->w); - assert(pb); - - error = xwimp_redraw_window(redraw, &more); - if (error) { - LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess); - return; - } - if (more) - ro_gui_progress_bar_redraw_window(redraw, pb); -} - - -/** - * Animate the progress bar - * - * \param p the progress bar to animate - */ -void ro_gui_progress_bar_animate(void *p) -{ - wimp_draw redraw; - os_error *error; - osbool more; - struct progress_bar *pb = p; - - if (!progress_icon) - return; - pb->offset -= 6; - if (pb->offset < 0) - pb->offset += progress_width * 2; - - if (pb->animating) { - riscos_schedule(200, ro_gui_progress_bar_animate, pb); - } - - redraw.w = pb->w; - redraw.box = pb->visible; - error = xwimp_update_window(&redraw, &more); - if (error != NULL) { - LOG("Error getting update window: '%s'", error->errmess); - return; - } - if (more) - ro_gui_progress_bar_redraw_window(&redraw, pb); -} - - -/** - * Calculate the position of the progress bar - * - * \param pb the progress bar to recalculate - * \param width the width of the progress bar - * \param height the height of the progress bar - * \return the address of the associated icon, or NULL - */ -void ro_gui_progress_bar_calculate(struct progress_bar *pb, int width, - int height) -{ - int icon_width, icon_height; - int icon_x0 = 0, icon_y0 = 0, progress_x0, progress_x1; - osspriteop_header *icon = NULL; - bool icon_redraw = false; - - /* try to use cached values */ - if ((!pb->recalculate) && (pb->cur_width == width) && - (pb->cur_height == height)) - return; - - /* update cache status */ - pb->recalculate = false; - pb->cur_width = width; - pb->cur_height = height; - - /* get the window dimensions */ - width -= MARGIN * 2; - icon_width = icon_height = 0; - progress_x0 = MARGIN; - - /* get the icon information */ - if (progress_bar_definition.sprite_area != wimpspriteop_AREA) { - int progress_ymid = height / 2; - os_error *error; - error = xosspriteop_read_sprite_info(osspriteop_USER_AREA, - progress_bar_definition.sprite_area, - (osspriteop_id)pb->icon, - &icon_width, &icon_height, 0, 0); - if (!error) { - error = xosspriteop_select_sprite(osspriteop_USER_AREA, - progress_bar_definition.sprite_area, - (osspriteop_id)pb->icon, &icon); - } - if (!error) { - progress_x0 += 32 + MARGIN; - width -= 32 + MARGIN; - icon_x0 = MARGIN + 16 - icon_width; - icon_y0 = progress_ymid - icon_height; - if (width < -MARGIN) { - icon_x0 += width + MARGIN; - icon_redraw = true; - } - } - } - - /* update the icon */ - if ((pb->icon_obscured) || (icon_redraw)) { - if (icon_x0 != pb->icon_x0) - xwimp_force_redraw(pb->w, 0, 0, 32 + MARGIN, 65536); - } - pb->icon_obscured = icon_redraw; - - progress_x1 = progress_x0; - if ((pb->range > 0) && (width > 0)) - progress_x1 += (width * pb->value) / pb->range; - - pb->visible.x0 = progress_x0; - pb->visible.y0 = MARGIN; - pb->visible.x1 = progress_x1; - pb->visible.y1 = height - MARGIN; - pb->icon_x0 = icon_x0; - pb->icon_y0 = icon_y0; - pb->icon_img = icon; -} - - -/** - * Redraw a section of a progress bar window - * - * \param redraw the section of the window to redraw - * \param pb the progress bar to redraw - */ -void ro_gui_progress_bar_redraw_window(wimp_draw *redraw, - struct progress_bar *pb) -{ - osbool more = true; - struct rect clip; - int progress_ymid; - - /* initialise the plotters */ - ro_plot_origin_x = 0; - ro_plot_origin_y = 0; - - /* recalculate the progress bar */ - ro_gui_progress_bar_calculate(pb, redraw->box.x1 - redraw->box.x0, - redraw->box.y1 - redraw->box.y0); - progress_ymid = redraw->box.y0 + pb->visible.y0 + - ((pb->visible.y1 - pb->visible.y0) >> 1); - - /* redraw the window */ - while (more) { - os_error *error; - if (pb->icon) - _swix(Tinct_PlotAlpha, _IN(2) | _IN(3) | _IN(4) | _IN(7), - pb->icon_img, - redraw->box.x0 + pb->icon_x0, - redraw->box.y0 + pb->icon_y0, - tinct_ERROR_DIFFUSE); - if (!pb->icon_obscured) { - clip.x0 = max(redraw->clip.x0, - redraw->box.x0 + pb->visible.x0) >> 1; - clip.y0 = -min(redraw->clip.y1, - redraw->box.y0 + pb->visible.y1) >> 1; - clip.x1 = min(redraw->clip.x1, - redraw->box.x0 + pb->visible.x1) >> 1; - clip.y1 = -max(redraw->clip.y0, - redraw->box.y0 + pb->visible.y0) >> 1; - if ((clip.x0 < clip.x1) && (clip.y0 < clip.y1)) { - if (progress_icon) { - ro_plotters.clip(&clip); - _swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7), - progress_icon, - redraw->box.x0 - pb->offset, - progress_ymid - progress_height, - tinct_FILL_HORIZONTALLY); - } else { - ro_plotters.rectangle(clip.x0, clip.y0, - clip.x1, clip.y1, - plot_style_fill_red); - } - } - } - error = xwimp_get_rectangle(redraw, &more); - if (error) { - LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess); - return; - } - } -} |