diff options
Diffstat (limited to 'riscos/gui/status_bar.c')
-rw-r--r-- | riscos/gui/status_bar.c | 625 |
1 files changed, 0 insertions, 625 deletions
diff --git a/riscos/gui/status_bar.c b/riscos/gui/status_bar.c deleted file mode 100644 index cbc404658..000000000 --- a/riscos/gui/status_bar.c +++ /dev/null @@ -1,625 +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 - * UTF8 status bar (implementation). - */ - -#include <assert.h> -#include <stdbool.h> -#include <string.h> -#include "swis.h" -#include "oslib/colourtrans.h" -#include "oslib/os.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/wimp.h" -#include "riscos/wimp_event.h" -#include "riscos/wimputils.h" -#include "riscos/font.h" -#include "riscos/gui/progress_bar.h" -#include "riscos/gui/status_bar.h" - -#define ICON_WIDGET 0 -#define WIDGET_WIDTH 12 -#define PROGRESS_WIDTH 160 - -struct status_bar { - wimp_w w; /**< status bar window handle */ - wimp_w parent; /**< parent window handle */ - const char *text; /**< status bar text */ - struct progress_bar *pb; /**< progress bar */ - unsigned int scale; /**< current status bar scale */ - int width; /**< current status bar width */ - bool visible; /**< status bar is visible? */ -}; - -static char status_widget_text[] = ""; -static char status_widget_validation[] = "R5;Pptr_lr,8,6"; - -wimp_WINDOW(1) status_bar_definition = { - {0, 0, 1, 1}, - 0, - 0, - wimp_TOP, - wimp_WINDOW_NEW_FORMAT | wimp_WINDOW_MOVEABLE | - wimp_WINDOW_FURNITURE_WINDOW | - wimp_WINDOW_IGNORE_XEXTENT, - wimp_COLOUR_BLACK, - 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, - {""}, - 1, - { - { - {0, 0, 1, 1}, - wimp_ICON_TEXT | wimp_ICON_INDIRECTED | - wimp_ICON_BORDER | wimp_ICON_FILLED | - (wimp_COLOUR_LIGHT_GREY << - wimp_ICON_BG_COLOUR_SHIFT) | - (wimp_BUTTON_CLICK_DRAG << - wimp_ICON_BUTTON_TYPE_SHIFT), - { - .indirected_text = { - status_widget_text, - status_widget_validation, - 1 - } - } - } - } -}; - -static void ro_gui_status_bar_open(wimp_open *open); -static bool ro_gui_status_bar_click(wimp_pointer *pointer); -static void ro_gui_status_bar_redraw(wimp_draw *redraw); -static void ro_gui_status_bar_redraw_callback(void *handle); -static void ro_gui_status_position_progress_bar(struct status_bar *sb); - - -/** - * Create a new status bar - * - * \param parent the window to contain the status bar - * \param width the proportional width to use (0...10,000) - */ -struct status_bar *ro_gui_status_bar_create(wimp_w parent, unsigned int width) -{ - struct status_bar *sb; - os_error *error; - - sb = calloc(1, sizeof(*sb)); - if (!sb) - return NULL; - - sb->pb = ro_gui_progress_bar_create(); - if (!sb->pb) - return NULL; - - error = xwimp_create_window((wimp_window *)&status_bar_definition, - &sb->w); - if (error) { - LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess); - free(sb); - return NULL; - } - sb->parent = parent; - sb->scale = width; - sb->visible = true; - - ro_gui_wimp_event_set_user_data(sb->w, sb); - ro_gui_wimp_event_register_open_window(sb->w, - ro_gui_status_bar_open); - ro_gui_wimp_event_register_mouse_click(sb->w, - ro_gui_status_bar_click); - ro_gui_wimp_event_register_redraw_window(sb->w, - ro_gui_status_bar_redraw); - ro_gui_wimp_event_set_help_prefix(sb->w, "HelpStatus"); - ro_gui_status_bar_resize(sb); - return sb; -} - - -/** - * Destroy a status bar and free all associated resources - * - * \param sb the status bar to destroy - */ -void ro_gui_status_bar_destroy(struct status_bar *sb) -{ - os_error *error; - assert(sb); - - ro_gui_wimp_event_finalise(sb->w); - error = xwimp_delete_window(sb->w); - if (error) { - LOG("xwimp_delete_window: 0x%x:%s", error->errnum, error->errmess); - } - - ro_gui_progress_bar_destroy(sb->pb); - - /* Remove any scheduled redraw callbacks */ - riscos_schedule(-1, ro_gui_status_bar_redraw_callback, (void *) sb); - - free(sb); -} - - -/** - * Get the handle of the window that represents a status bar - * - * \param sb the status bar to get the window handle of - * \return the status bar's window handle - */ -wimp_w ro_gui_status_bar_get_window(struct status_bar *sb) -{ - assert(sb); - - return sb->w; -} - - -/** - * Get the proportional width the status bar is currently using - * - * \param sb the status bar to get the width of - * \return the status bar's width (0...10,000) - */ -unsigned int ro_gui_status_bar_get_width(struct status_bar *sb) -{ - assert(sb); - - return sb->scale; -} - - -/** - * Set the visibility status of the status bar - * - * \param sb the status bar to check the visiblity of - * \param visible if the status bar should be shown or not. - * \return whether the status bar is visible - */ -void ro_gui_status_bar_set_visible(struct status_bar *sb, bool visible) -{ - assert(sb); - - sb->visible = visible; - if (visible) { - ro_gui_status_bar_resize(sb); - } else { - os_error *error = xwimp_close_window(sb->w); - if (error) { - LOG("xwimp_close_window: 0x%x:%s", error->errnum, error->errmess); - } - } -} - - -/** - * Get the visibility status of the status bar - * - * \param sb the status bar to check the visiblity of - * \return whether the status bar is visible - */ -bool ro_gui_status_bar_get_visible(struct status_bar *sb) -{ - assert(sb); - - return sb->visible; -} - - -/** - * Set the value of the progress bar - * - * \param sb the status bar to set the progress of - * \param value the value to use - */ -void ro_gui_status_bar_set_progress_value(struct status_bar *sb, - unsigned int value) -{ - assert(sb); - - ro_gui_status_bar_set_progress_range(sb, - max(value, ro_gui_progress_bar_get_range(sb->pb))); - ro_gui_progress_bar_set_value(sb->pb, value); -} - - -/** - * Set the range of the progress bar - * - * \param sb the status bar to set the range of - * \param range the range of the progress bar - */ -void ro_gui_status_bar_set_progress_range(struct status_bar *sb, - unsigned int range) -{ - unsigned int old_range; - - assert(sb); - - old_range = ro_gui_progress_bar_get_range(sb->pb); - ro_gui_progress_bar_set_range(sb->pb, range); - - LOG("Ranges are %i vs %i", old_range, range); - if ((old_range == 0) && (range != 0)) { - ro_gui_status_position_progress_bar(sb); - } else if ((old_range != 0) && (range == 0)) { - os_error *error = xwimp_close_window( - ro_gui_progress_bar_get_window(sb->pb)); - if (error) { - LOG("xwimp_close_window: 0x%x:%s", error->errnum, error->errmess); - } - } -} - - -/** - * Set the icon for the progress bar - * - * \param sb the status bar to set the icon for - * \param icon the icon to use, or NULL for no icon - */ -void ro_gui_status_bar_set_progress_icon(struct status_bar *sb, - const char *icon) -{ - assert(sb); - - ro_gui_progress_bar_set_icon(sb->pb, icon); -} - - -/** - * Set the text to display in the status bar - * - * \param sb the status bar to set the text for - * \param text the UTF8 text to display, or NULL for none - */ -void ro_gui_status_bar_set_text(struct status_bar *sb, const char *text) -{ - assert(sb); - - sb->text = text; - - /* Schedule a window redraw for 1cs' time. - * - * We do this to ensure that redraws as a result of text changes - * do not prevent other applications obtaining CPU time. - * - * The scheduled callback will be run when we receive the first - * null poll after 1cs has elapsed. It may then issue a redraw - * request to the Wimp. - * - * The scheduler ensures that only one instance of the - * { callback, handle } pair is registered at once. - */ - if (sb->visible && text != NULL) { - riscos_schedule(10, ro_gui_status_bar_redraw_callback, sb); - } -} - - -/** - * Resize a status bar following a change in the dimensions of the - * parent window. - * - * \param sb the status bar to resize - */ -void ro_gui_status_bar_resize(struct status_bar *sb) -{ - int window_width; - int status_width, status_height; - wimp_window_state state; - os_error *error; - os_box extent; - - if ((!sb) || (!sb->visible)) - return; - - /* get the window work area dimensions */ - state.w = sb->parent; - error = xwimp_get_window_state(&state); - if (error) { - LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); - return; - } - window_width = state.visible.x1 - state.visible.x0; - - - /* recalculate the scaled width */ - status_width = (window_width * sb->scale) / 10000; - if (status_width < WIDGET_WIDTH) - status_width = WIDGET_WIDTH; - status_height = ro_get_hscroll_height(sb->parent); - - /* resize the status/resize icons */ - if (status_width != sb->width) { - /* update the window extent */ - int redraw_left, redraw_right; - - extent.x0 = 0; - extent.y0 = 0; - extent.x1 = status_width; - extent.y1 = status_height - 4; - error = xwimp_set_extent(sb->w, &extent); - if (error) { - LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess); - return; - } - - /* re-open the nested window */ - state.w = sb->w; - state.xscroll = 0; - state.yscroll = 0; - state.next = wimp_TOP; - state.visible.x0 = state.visible.x0; - state.visible.y1 = state.visible.y0 - 2; - state.visible.x1 = state.visible.x0 + status_width; - state.visible.y0 = state.visible.y1 - status_height + 4; - error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), - sb->parent, - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_XORIGIN_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_YORIGIN_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_LS_EDGE_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_BS_EDGE_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_RS_EDGE_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_TS_EDGE_SHIFT); - if (error) { - LOG("xwimp_open_window_nested: 0x%x: %s", error->errnum, error->errmess); - return; - } - ro_gui_status_position_progress_bar(sb); - error = xwimp_resize_icon(sb->w, ICON_WIDGET, - status_width - WIDGET_WIDTH, 0, - status_width, status_height - 4); - if (error) { - LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess); - return; - } - - redraw_left = min(status_width, sb->width) - WIDGET_WIDTH - 2; - redraw_right = max(status_width, sb->width); - xwimp_force_redraw(sb->w, redraw_left, 0, - redraw_right, status_height); - sb->width = status_width; - } -} - - -/** - * Process a WIMP redraw request - * - * \param redraw the redraw request to process - */ -void ro_gui_status_bar_redraw(wimp_draw *redraw) -{ - struct status_bar *sb; - os_error *error; - osbool more; - rufl_code code; - - sb = (struct status_bar *)ro_gui_wimp_event_get_user_data(redraw->w); - assert(sb); - - /* initialise the plotters */ - ro_plot_origin_x = 0; - ro_plot_origin_y = 0; - - /* redraw the window */ - error = xwimp_redraw_window(redraw, &more); - if (error) { - LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess); - return; - } - while (more) { - /* redraw the status text */ - if (sb->text) { - error = xcolourtrans_set_font_colours(font_CURRENT, - 0xeeeeee00, 0x00000000, 14, 0, 0, 0); - if (error) { - LOG("xcolourtrans_set_font_colours: 0x%x: %s", error->errnum, error->errmess); - return; - } - code = rufl_paint(ro_gui_desktop_font_family, - ro_gui_desktop_font_style, - ro_gui_desktop_font_size, - sb->text, strlen(sb->text), - redraw->box.x0 + 6, redraw->box.y0 + 8, - rufl_BLEND_FONT); - if (code != rufl_OK) { - if (code == rufl_FONT_MANAGER_ERROR) - LOG("rufl_FONT_MANAGER_ERROR: 0x%x: %s", rufl_fm_error->errnum, rufl_fm_error->errmess); - else - LOG("rufl_paint: 0x%x", code); - } - } - - /* separate the widget from the text with a line */ - ro_plotters.rectangle((redraw->box.x0 + sb->width - WIDGET_WIDTH - 2) >> 1, - -redraw->box.y0 >> 1, - (redraw->box.x0 + sb->width - WIDGET_WIDTH) >> 1, - -redraw->box.y1 >> 1, - plot_style_fill_black); - - error = xwimp_get_rectangle(redraw, &more); - if (error) { - LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess); - return; - } - } -} - -/** - * Callback for scheduled redraw - * - * \param handle Callback handle - */ -void ro_gui_status_bar_redraw_callback(void *handle) -{ - struct status_bar *sb = handle; - - wimp_force_redraw(sb->w, 0, 0, sb->width - WIDGET_WIDTH, 65536); -} - - -/** - * Process an mouse_click event for a status window. - * - * \param pointer details of the mouse click - */ -bool ro_gui_status_bar_click(wimp_pointer *pointer) -{ - wimp_drag drag; - os_error *error; - - switch (pointer->i) { - case ICON_WIDGET: - drag.w = pointer->w; - drag.type = wimp_DRAG_SYSTEM_SIZE; - drag.initial.x0 = pointer->pos.x; - drag.initial.x1 = pointer->pos.x; - drag.initial.y0 = pointer->pos.y; - drag.initial.y1 = pointer->pos.y; - error = xwimp_drag_box(&drag); - if (error) { - LOG("xwimp_drag_box: 0x%x: %s", error->errnum, error->errmess); - } - break; - } - return true; -} - - -/** - * Process an open_window request for a status window. - * - * \param open the request to process - */ -void ro_gui_status_bar_open(wimp_open *open) -{ - struct status_bar *sb; - int window_width, status_width; - wimp_window_state state; - os_error *error; - - /* get the parent width for scaling */ - sb = (struct status_bar *)ro_gui_wimp_event_get_user_data(open->w); - state.w = sb->parent; - error = xwimp_get_window_state(&state); - if (error) { - LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); - return; - } - window_width = state.visible.x1 - state.visible.x0; - if (window_width == 0) - window_width = 1; - status_width = open->visible.x1 - open->visible.x0; - if (status_width <= 12) - status_width = 0; - - /* store the new size */ - sb->scale = (10000 * status_width) / window_width; - if (sb->scale > 10000) - sb->scale = 10000; - ro_gui_status_bar_resize(sb); -} - - -/** - * Reposition the progress component following a change in the - * dimension of the status window. - * - * \param sb the status bar to update - */ -void ro_gui_status_position_progress_bar(struct status_bar *sb) -{ - wimp_window_state state; - os_error *error; - int left, right; - - if (!sb) - return; - if (ro_gui_progress_bar_get_range(sb->pb) == 0) - return; - - /* get the window work area dimensions */ - state.w = sb->w; - error = xwimp_get_window_state(&state); - if (error) { - LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess); - return; - } - - /* calculate the dimensions */ - right = state.visible.x1 - WIDGET_WIDTH - 2; - left = max(state.visible.x0, right - PROGRESS_WIDTH); - - /* re-open the nested window */ - state.w = ro_gui_progress_bar_get_window(sb->pb); - state.xscroll = 0; - state.yscroll = 0; - state.next = wimp_TOP; - state.visible.x0 = left; - state.visible.x1 = right; - error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), - sb->w, - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_XORIGIN_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_YORIGIN_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_LS_EDGE_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_BS_EDGE_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_RS_EDGE_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_TS_EDGE_SHIFT); - if (error) { - LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess); - } - - /* update the progress bar display on non-standard width */ - if ((right - left) != PROGRESS_WIDTH) - ro_gui_progress_bar_update(sb->pb, right - left, - state.visible.y1 - state.visible.y0); -} |