diff options
Diffstat (limited to 'riscos/theme.c')
-rw-r--r-- | riscos/theme.c | 1857 |
1 files changed, 156 insertions, 1701 deletions
diff --git a/riscos/theme.c b/riscos/theme.c index 015cf10eb..6b83cad92 100644 --- a/riscos/theme.c +++ b/riscos/theme.c @@ -17,7 +17,7 @@ */ /** \file - * Window themes and toolbars (implementation). + * Window themes (implementation). */ #include <alloca.h> @@ -53,83 +53,16 @@ #include "utils/log.h" #include "utils/utils.h" -#define THEME_URL_MEMORY 256 -#define THEME_THROBBER_MEMORY 12 + +/* \TODO -- provide a proper interface for these and make them static again! + */ static struct theme_descriptor *theme_current = NULL; static struct theme_descriptor *theme_descriptors = NULL; -static struct toolbar *theme_toolbar_drag = NULL; -static struct toolbar_icon *theme_toolbar_icon_drag = NULL; -static bool theme_toolbar_editor_drag = false; - -/* these order of the icons must match the numbers defined in riscos/gui.h */ -static const char * theme_browser_icons[] = {"back", "forward", "stop", - "reload", "home", "history", "save", "print", "hotlist", - "scale", "search", "up", NULL}; -static const char * theme_hotlist_icons[] = {"delete", "expand", "open", - "launch", "create", NULL}; -static const char * theme_history_icons[] = {"delete", "expand", "open", - "launch", NULL}; -static const char * theme_cookies_icons[] = {"delete", "expand", "open", - NULL}; static bool ro_gui_theme_add_descriptor(const char *folder, const char *leafname); -static void ro_gui_theme_redraw(wimp_draw *redraw); static void ro_gui_theme_get_available_in_dir(const char *directory); static void ro_gui_theme_free(struct theme_descriptor *descriptor); -static struct toolbar_icon *ro_gui_theme_add_toolbar_icon( - struct toolbar *toolbar, const char *name, int icon_number); -static void ro_gui_theme_update_toolbar_icon(struct toolbar *toolbar, - struct toolbar_icon *icon); -static void ro_gui_theme_destroy_toolbar_icon(struct toolbar_icon *icon); -static void ro_gui_theme_link_toolbar_icon(struct toolbar *toolbar, - struct toolbar_icon *icon, struct toolbar_icon *link, - bool before); -static void ro_gui_theme_delink_toolbar_icon(struct toolbar *toolbar, - struct toolbar_icon *icon); -static struct toolbar_icon *ro_gui_theme_toolbar_get_insert_icon( - struct toolbar *toolbar, int x, int y, bool *before); -static void ro_gui_theme_add_toolbar_icons(struct toolbar *toolbar, - const char* icons[], const char* ident); -static void ro_gui_theme_set_help_prefix(struct toolbar *toolbar); - -/* A basic window for the toolbar and status -*/ -static wimp_window theme_toolbar_window = { - {0, 0, 1, 1}, - 0, - 0, - wimp_TOP, - wimp_WINDOW_NEW_FORMAT | wimp_WINDOW_MOVEABLE | wimp_WINDOW_NO_BOUNDS | - wimp_WINDOW_FURNITURE_WINDOW | - wimp_WINDOW_IGNORE_XEXTENT | wimp_WINDOW_IGNORE_YEXTENT, - 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, 16384, 16384}, - 0, - 0, - wimpspriteop_AREA, - 1, - 1, - {""}, - 0, - { } -}; - - -/* Shared icon validation -*/ -static char theme_url_validation[] = "Pptr_write;KN"; -static char theme_null_text_string[] = ""; -static char theme_separator_name[] = "separator"; -static char theme_favicon_sprite[12]; - /** * Initialise the theme handler @@ -267,6 +200,155 @@ static void ro_gui_theme_get_available_in_dir(const char *directory) /** + * Returns the current theme handle, or NULL if none is set. + * + * \return The theme descriptor handle, or NULL. + */ + +struct theme_descriptor *ro_gui_theme_get_current(void) +{ + return theme_current; +} + + +/** + * Returns a sprite area for use with the given theme. This may return a + * pointer to the wimp sprite pool if a theme area isn't available. + * + * \param *descriptor The theme to use, or NULL for the current. + * \return A pointer to the theme sprite area. + */ + +osspriteop_area *ro_gui_theme_get_sprites(struct theme_descriptor *descriptor) +{ + osspriteop_area *area; + + if (descriptor == NULL) + descriptor = theme_current; + + if (descriptor != NULL && descriptor->theme != NULL) + area = descriptor->theme->sprite_area; + else + area = (osspriteop_area *) 1; + + return area; +} + + +/** + * Returns an interger element from the specified theme, or the current theme + * if the descriptor is NULL. + * + * This is an attempt to abstract the theme data from its clients: it should + * simplify the task of expanding the theme system in the future should this + * be necessary to include other parts of the RISC OS GUI in the theme system. + * + * \param *descriptor The theme to use, or NULL for the current. + * \param style The style to use. + * \param element The style element to return. + * \return The requested value, or 0. + */ + +int ro_gui_theme_get_style_element(struct theme_descriptor *descriptor, + theme_style style, theme_element element) +{ + if (descriptor == NULL) + descriptor = theme_current; + + if (descriptor == NULL) + return 0; + + switch (style) { + case THEME_STYLE_NONE: + switch(element) { + case THEME_ELEMENT_FOREGROUND: + return wimp_COLOUR_BLACK; + case THEME_ELEMENT_BACKGROUND: + return wimp_COLOUR_VERY_LIGHT_GREY; + default: + return 0; + } + break; + + case THEME_STYLE_BROWSER_TOOLBAR: + switch (element) { + case THEME_ELEMENT_FOREGROUND: + return wimp_COLOUR_BLACK; + case THEME_ELEMENT_BACKGROUND: + return descriptor->browser_background; + default: + return 0; + } + break; + + case THEME_STYLE_HOTLIST_TOOLBAR: + case THEME_STYLE_COOKIES_TOOLBAR: + case THEME_STYLE_GLOBAL_HISTORY_TOOLBAR: + switch (element) { + case THEME_ELEMENT_FOREGROUND: + return wimp_COLOUR_BLACK; + case THEME_ELEMENT_BACKGROUND: + return descriptor->hotlist_background; + default: + return 0; + } + break; + + case THEME_STYLE_STATUS_BAR: + switch (element) { + case THEME_ELEMENT_FOREGROUND: + return descriptor->status_foreground; + case THEME_ELEMENT_BACKGROUND: + return descriptor->status_background; + default: + return 0; + } + break; + + default: + return 0; + } +} + +/** + * Returns details of the throbber as defined in a theme. + * + * \param *descriptor The theme of interest (NULL for current). + * \param *frames Return the number of animation frames. + * \param *width Return the throbber width. + * \param *height Return the throbber height. + * \param *right Return the 'locate on right' flag. + * \param *redraw Return the 'forcible redraw' flag. + * \return true if meaningful data has been returned; + * else false. + */ + +bool ro_gui_theme_get_throbber_data(struct theme_descriptor *descriptor, + int *frames, int *width, int *height, + bool *right, bool *redraw) +{ + if (descriptor == NULL) + descriptor = theme_current; + + if (descriptor == NULL || descriptor->theme == NULL) + return false; + + if (frames != NULL) + *frames = descriptor->theme->throbber_frames; + if (width != NULL) + *width = descriptor->theme->throbber_width; + if (height != NULL) + *height = descriptor->theme->throbber_height; + if (right != NULL) + *right = descriptor->throbber_right; + if (redraw != NULL) + *redraw = descriptor->throbber_redraw; + + return true; +} + + +/** * Checks a theme is valid and adds it to the current list * * \param folder the theme folder @@ -586,11 +668,9 @@ bool ro_gui_theme_apply(struct theme_descriptor *descriptor) theme_previous = theme_current; theme_current = descriptor; - /* apply the theme to all the current windows */ - ro_gui_window_update_theme(); - ro_gui_cookies_update_theme(true); - ro_gui_global_history_update_theme(true); - ro_gui_hotlist_update_theme(true); + /* apply the theme to all the current toolbar-ed windows */ + ro_toolbar_theme_update(); + ro_gui_theme_close(theme_previous, false); return true; } @@ -631,91 +711,6 @@ void ro_gui_theme_close(struct theme_descriptor *descriptor, bool list) /** - * Performs the redraw for a toolbar - * - * \param redraw the redraw area - * \param toolbar the toolbar to redraw - */ -void ro_gui_theme_redraw(wimp_draw *redraw) -{ - struct toolbar *toolbar; - struct gui_window *g; - - struct toolbar_icon *icon; - osbool more; - wimp_icon separator_icon; - os_error *error; - bool perform_redraw = false; - - toolbar = (struct toolbar *)ro_gui_wimp_event_get_user_data(redraw->w); - - assert(toolbar); - - /* set the content-type icon */ - g = ro_gui_toolbar_lookup(toolbar->toolbar_handle); - - /* only set type for browser windows */ - sprintf(theme_favicon_sprite, "Ssmall_xxx"); - if (g) { - assert(toolbar->type == THEME_BROWSER_TOOLBAR); - assert(g->bw); - if (g->bw->current_content) { - sprintf(theme_favicon_sprite, "Ssmall_%.3x", - ro_content_filetype_from_type( - content_get_type(g->bw->current_content))); - if (!ro_gui_wimp_sprite_exists(theme_favicon_sprite + 1)) - sprintf(theme_favicon_sprite, "Ssmall_xxx"); - } - } - - /* set up the icon */ - if ((toolbar->descriptor) && (toolbar->descriptor->theme) && - (toolbar->descriptor->theme->sprite_area)) { - const char *name = theme_separator_name; - - separator_icon.flags = wimp_ICON_SPRITE | wimp_ICON_INDIRECTED | - wimp_ICON_HCENTRED | wimp_ICON_VCENTRED; - separator_icon.data.indirected_sprite.id = (osspriteop_id) name; - separator_icon.data.indirected_sprite.area = - toolbar->descriptor->theme->sprite_area; - separator_icon.data.indirected_sprite.size = 12; - separator_icon.extent.y0 = 0; - separator_icon.extent.y1 = toolbar->height; - perform_redraw = true; - } - perform_redraw &= toolbar->display_buttons || toolbar->editor; - if ((toolbar->editor) && (toolbar->editor->toolbar_handle == redraw->w)) - toolbar = toolbar->editor; - - error = xwimp_redraw_window(redraw, &more); - if (error) { - LOG(("xwimp_redraw_window: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return; - } - while (more) { - if (perform_redraw) - for (icon = toolbar->icon; icon; icon = icon->next) - if ((icon->icon_number == -1) && - (icon->display)) { - separator_icon.extent.x0 = icon->x; - separator_icon.extent.x1 = icon->x + - icon->width; - xwimp_plot_icon(&separator_icon); - } - error = xwimp_get_rectangle(redraw, &more); - if (error) { - LOG(("xwimp_get_rectangle: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return; - } - } -} - - -/** * Frees any unused theme descriptors. * * \param descriptor the theme_descriptor to free @@ -757,1543 +752,3 @@ void ro_gui_theme_free(struct theme_descriptor *descriptor) } -/** - * Creates a toolbar. - * - * \param descriptor the theme to use, or NULL for current - * \param type the toolbar type - * \return a new toolbar, or NULL for failure - */ -struct toolbar *ro_gui_theme_create_toolbar(struct theme_descriptor *descriptor, - toolbar_type type) -{ - struct toolbar *toolbar; - - /* Create a new toolbar - */ - toolbar = calloc(sizeof(struct toolbar), 1); - if (!toolbar) { - LOG(("No memory for malloc()")); - warn_user("NoMemory", 0); - return NULL; - } - toolbar->type = type; - - /* Store the theme - */ - if (!descriptor) descriptor = theme_current; - toolbar->descriptor = descriptor; - - /* Apply the default settings - */ - toolbar->display_buttons = true; - toolbar->toolbar_current = 16384; - switch (type) { - case THEME_BROWSER_TOOLBAR: - toolbar->display_url = true; - toolbar->display_throbber = true; - ro_gui_theme_add_toolbar_icons(toolbar, - theme_browser_icons, - option_toolbar_browser); - toolbar->suggest = ro_gui_theme_add_toolbar_icon(NULL, - "gright", - ICON_TOOLBAR_SUGGEST); - break; - case THEME_HOTLIST_TOOLBAR: - ro_gui_theme_add_toolbar_icons(toolbar, - theme_hotlist_icons, - option_toolbar_hotlist); - break; - case THEME_HISTORY_TOOLBAR: - ro_gui_theme_add_toolbar_icons(toolbar, - theme_history_icons, - option_toolbar_history); - break; - case THEME_COOKIES_TOOLBAR: - ro_gui_theme_add_toolbar_icons(toolbar, - theme_cookies_icons, - option_toolbar_cookies); - break; - case THEME_BROWSER_EDIT_TOOLBAR: - ro_gui_theme_add_toolbar_icons(toolbar, - theme_browser_icons, - "0123456789ab|"); - break; - case THEME_HOTLIST_EDIT_TOOLBAR: - ro_gui_theme_add_toolbar_icons(toolbar, - theme_hotlist_icons, - "40123|"); - break; - case THEME_HISTORY_EDIT_TOOLBAR: - ro_gui_theme_add_toolbar_icons(toolbar, - theme_history_icons, - "0123|"); - break; - case THEME_COOKIES_EDIT_TOOLBAR: - ro_gui_theme_add_toolbar_icons(toolbar, - theme_cookies_icons, - "012|"); - break; - } - - /* Claim the memory for our Wimp indirection - */ - if (type == THEME_BROWSER_TOOLBAR) { - toolbar->url_buffer = calloc(1, THEME_URL_MEMORY + - THEME_THROBBER_MEMORY); - if (!toolbar->url_buffer) { - LOG(("No memory for calloc()")); - ro_gui_theme_destroy_toolbar(toolbar); - return NULL; - } - toolbar->throbber_buffer = toolbar->url_buffer + - THEME_URL_MEMORY; - sprintf(toolbar->throbber_buffer, "throbber0"); - } - - /* Apply the desired theme to the toolbar - */ - if (!ro_gui_theme_update_toolbar(descriptor, toolbar)) { - ro_gui_theme_destroy_toolbar(toolbar); - return NULL; - } - toolbar->old_height = ro_gui_theme_toolbar_full_height(toolbar); - return toolbar; -} - - -/** - * Updates a toolbar to use a particular theme. - * The toolbar may be unstable on failure and should be destroyed. - * - * \param descriptor the theme to use, or NULL for current - * \param toolbar the toolbar to update - * \return whether the operation was successful - */ -bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, - struct toolbar *toolbar) -{ - wimp_icon_create new_icon; - os_error *error; - osspriteop_area *sprite_area; - struct toolbar_icon *toolbar_icon; - int width, max_icon; - wimp_icon_flags icon_flags; - struct gui_window *g; - if (!toolbar) return false; - - /* Set the theme and window sprite area - */ - if (!descriptor) descriptor = theme_current; - toolbar->descriptor = descriptor; - if ((toolbar->descriptor) && (toolbar->descriptor->theme)) - sprite_area = toolbar->descriptor->theme->sprite_area; - else - sprite_area = (osspriteop_area *)1; - theme_toolbar_window.sprite_area = sprite_area; - - /* Update the icon sizes - */ - for (toolbar_icon = toolbar->icon; toolbar_icon; - toolbar_icon = toolbar_icon->next) - ro_gui_theme_update_toolbar_icon(toolbar, toolbar_icon); - if (toolbar->suggest) - ro_gui_theme_update_toolbar_icon(toolbar, toolbar->suggest); - - /* Recreate the toolbar window - */ - if (toolbar->descriptor) { - if (toolbar->type == THEME_BROWSER_TOOLBAR) - theme_toolbar_window.work_bg = - toolbar->descriptor->browser_background; - else - theme_toolbar_window.work_bg = - toolbar->descriptor->hotlist_background; - } else { - theme_toolbar_window.work_bg = wimp_COLOUR_VERY_LIGHT_GREY; - } - - theme_toolbar_window.work_flags &= ~wimp_ICON_BUTTON_TYPE; - if ((toolbar->editor) || - (toolbar->type == THEME_HOTLIST_EDIT_TOOLBAR) || - (toolbar->type == THEME_HISTORY_EDIT_TOOLBAR) || - (toolbar->type == THEME_BROWSER_EDIT_TOOLBAR) || - (toolbar->type == THEME_COOKIES_EDIT_TOOLBAR)) - theme_toolbar_window.work_flags |= (wimp_BUTTON_CLICK_DRAG << - wimp_ICON_BUTTON_TYPE_SHIFT); - theme_toolbar_window.sprite_area = sprite_area; - if (toolbar->toolbar_handle) { - error = xwimp_delete_window(toolbar->toolbar_handle); - if (error) - LOG(("xwimp_delete_window: 0x%x: %s", - error->errnum, error->errmess)); - ro_gui_wimp_event_finalise(toolbar->toolbar_handle); - toolbar->toolbar_handle = NULL; - } - error = xwimp_create_window(&theme_toolbar_window, - &toolbar->toolbar_handle); - if (error) { - LOG(("xwimp_create_window: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - ro_gui_wimp_event_register_redraw_window(toolbar->toolbar_handle, - ro_gui_theme_redraw); - ro_gui_wimp_event_set_user_data(toolbar->toolbar_handle, toolbar); - switch (toolbar->type) { - case THEME_BROWSER_TOOLBAR: - case THEME_BROWSER_EDIT_TOOLBAR: - ro_gui_wimp_event_register_mouse_click(toolbar->toolbar_handle, - ro_gui_toolbar_click); - break; - case THEME_HOTLIST_TOOLBAR: - case THEME_HOTLIST_EDIT_TOOLBAR: - ro_gui_wimp_event_register_mouse_click(toolbar->toolbar_handle, - ro_gui_hotlist_toolbar_click); - ro_gui_wimp_event_register_window_menu(toolbar->toolbar_handle, - tree_toolbar_menu, - ro_gui_hotlist_menu_prepare, - ro_gui_hotlist_menu_select, NULL, - ro_gui_hotlist_menu_warning, false); - break; - case THEME_HISTORY_TOOLBAR: - case THEME_HISTORY_EDIT_TOOLBAR: - ro_gui_wimp_event_register_mouse_click(toolbar->toolbar_handle, - ro_gui_global_history_toolbar_click); - ro_gui_wimp_event_register_window_menu(toolbar->toolbar_handle, - tree_toolbar_menu, - ro_gui_global_history_menu_prepare, - ro_gui_global_history_menu_select, NULL, - ro_gui_global_history_menu_warning, false); - break; - case THEME_COOKIES_TOOLBAR: - case THEME_COOKIES_EDIT_TOOLBAR: - ro_gui_wimp_event_register_mouse_click(toolbar->toolbar_handle, - ro_gui_cookies_toolbar_click); - ro_gui_wimp_event_register_window_menu(toolbar->toolbar_handle, - tree_toolbar_menu, - ro_gui_cookies_menu_prepare, - ro_gui_cookies_menu_select, NULL, - ro_gui_cookies_menu_warning, false); - break; - default: - break; - } - - /* Create the basic icons - */ - if ((toolbar->type == THEME_HOTLIST_TOOLBAR) || - (toolbar->type == THEME_HOTLIST_EDIT_TOOLBAR)) - max_icon = ICON_TOOLBAR_HOTLIST_LAST; - else if ((toolbar->type == THEME_HISTORY_TOOLBAR) || - (toolbar->type == THEME_HISTORY_EDIT_TOOLBAR)) - max_icon = ICON_TOOLBAR_HISTORY_LAST; - else if ((toolbar->type == THEME_COOKIES_TOOLBAR) || - (toolbar->type == THEME_COOKIES_EDIT_TOOLBAR)) - max_icon = ICON_TOOLBAR_COOKIES_LAST; - else - max_icon = ICON_TOOLBAR_LAST; - new_icon.w = toolbar->toolbar_handle; - new_icon.icon.data.indirected_text.size = 1; - new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE | - wimp_ICON_INDIRECTED | wimp_ICON_HCENTRED | - wimp_ICON_VCENTRED; - if ((toolbar->editor) || - (toolbar->type == THEME_HOTLIST_EDIT_TOOLBAR) || - (toolbar->type == THEME_HISTORY_EDIT_TOOLBAR) || - (toolbar->type == THEME_COOKIES_EDIT_TOOLBAR) || - (toolbar->type == THEME_BROWSER_EDIT_TOOLBAR)) - new_icon.icon.flags |= (wimp_BUTTON_CLICK_DRAG << - wimp_ICON_BUTTON_TYPE_SHIFT); - else - new_icon.icon.flags |= (wimp_BUTTON_CLICK << - wimp_ICON_BUTTON_TYPE_SHIFT); - if (toolbar->descriptor) - new_icon.icon.flags |= (toolbar->descriptor->browser_background - << wimp_ICON_BG_COLOUR_SHIFT); - else - new_icon.icon.flags |= (wimp_COLOUR_VERY_LIGHT_GREY - << wimp_ICON_BG_COLOUR_SHIFT); - icon_flags = new_icon.icon.flags; - - for (int i = 0; i < max_icon; i++) { - new_icon.icon.data.indirected_text.text = - theme_null_text_string; - new_icon.icon.data.indirected_text.validation = - theme_null_text_string; - toolbar_icon = toolbar->icon; - while (toolbar_icon) { - if (toolbar_icon->icon_number == i) { - new_icon.icon.data.indirected_text.validation = - toolbar_icon->validation; - break; - } else { - toolbar_icon = toolbar_icon->next; - } - } - error = xwimp_create_icon(&new_icon, 0); - if (error) { - LOG(("xwimp_create_icon: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - } - - /* Create the URL/throbber icons - */ - if (toolbar->type == THEME_BROWSER_TOOLBAR) { - /* container for all URL bits (ie border) */ - new_icon.icon.flags = wimp_ICON_BORDER | (wimp_COLOUR_BLACK << - wimp_ICON_FG_COLOUR_SHIFT); - error = xwimp_create_icon(&new_icon, 0); - if (error) { - LOG(("xwimp_create_icon: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - - /* favicon image */ - new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE | - wimp_ICON_INDIRECTED | wimp_ICON_FILLED | - wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | - (wimp_BUTTON_CLICK_DRAG << - wimp_ICON_BUTTON_TYPE_SHIFT); - new_icon.icon.data.indirected_text.text = theme_null_text_string; - new_icon.icon.data.indirected_text.validation = - theme_favicon_sprite; - new_icon.icon.data.indirected_text.size = 1; - error = xwimp_create_icon(&new_icon, 0); - if (error) { - LOG(("xwimp_create_icon: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - - /* Writable text portion */ - new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED | - wimp_ICON_VCENTRED | - wimp_ICON_FILLED | (wimp_COLOUR_BLACK << - wimp_ICON_FG_COLOUR_SHIFT) | - (wimp_BUTTON_WRITE_CLICK_DRAG << - wimp_ICON_BUTTON_TYPE_SHIFT); - new_icon.icon.data.indirected_text.text = toolbar->url_buffer; - new_icon.icon.data.indirected_text.validation = - theme_url_validation; - new_icon.icon.data.indirected_text.size = THEME_URL_MEMORY; - error = xwimp_create_icon(&new_icon, 0); - if (error) { - LOG(("xwimp_create_icon: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - - /* Now the URL suggestion icon - */ - new_icon.icon.data.indirected_text.text = - theme_null_text_string; - new_icon.icon.data.indirected_text.size = 1; - new_icon.icon.flags = icon_flags | (wimp_BUTTON_CLICK << - wimp_ICON_BUTTON_TYPE_SHIFT); - if (toolbar->suggest) - new_icon.icon.data.indirected_text.validation = - toolbar->suggest->validation; - else - new_icon.icon.data.indirected_text.validation = - theme_null_text_string; - error = xwimp_create_icon(&new_icon, 0); - if (error) { - LOG(("xwimp_create_icon: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - - /* Now the throbber - */ - new_icon.icon.flags = wimp_ICON_SPRITE | wimp_ICON_INDIRECTED | - wimp_ICON_HCENTRED | wimp_ICON_VCENTRED; - new_icon.icon.data.indirected_sprite.id = - (osspriteop_id)toolbar->throbber_buffer; - new_icon.icon.data.indirected_sprite.area = sprite_area; - new_icon.icon.data.indirected_sprite.size = - THEME_THROBBER_MEMORY; - error = xwimp_create_icon(&new_icon, 0); - if (error) { - LOG(("xwimp_create_icon: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - } - if (toolbar->parent_handle) - ro_gui_theme_attach_toolbar(toolbar, toolbar->parent_handle); - - - /* Force a re-processing of the toolbar - */ - width = toolbar->toolbar_current; - toolbar->reformat_buttons = true; - toolbar->toolbar_current = -1; - ro_gui_theme_process_toolbar(toolbar, width); - - /* Keep menus up to date etc - */ - ro_gui_theme_set_help_prefix(toolbar); - switch (toolbar->type) { - case THEME_BROWSER_TOOLBAR: - g = ro_gui_window_lookup(toolbar->parent_handle); - if (g) - ro_gui_prepare_navigate(g); - break; - case THEME_HOTLIST_TOOLBAR: - case THEME_HISTORY_TOOLBAR: - case THEME_COOKIES_TOOLBAR: - ro_gui_menu_prepare_action(toolbar->parent_handle, - TREE_SELECTION, false); - ro_gui_menu_prepare_action(toolbar->parent_handle, - TREE_EXPAND_ALL, false); - break; - default: - break; - } - return true; -} - - -/** - * Attaches a toolbar to a window. - * - * \param toolbar the toolbar to update - * \param parent the window to contain the toolbar - * \return whether the operation was successful - */ -bool ro_gui_theme_attach_toolbar(struct toolbar *toolbar, wimp_w parent) -{ - wimp_outline outline; - wimp_window_state state; - int height; - os_error *error; - - if (!toolbar) - return false; - - /* Attach/close the windows - */ - toolbar->parent_handle = parent; - height = ro_gui_theme_toolbar_height(toolbar); - if (height > 0) { - outline.w = parent; - xwimp_get_window_outline(&outline); - state.w = parent; - xwimp_get_window_state(&state); - state.w = toolbar->toolbar_handle; - state.visible.x1 = outline.outline.x1 - 2; - state.visible.y0 = state.visible.y1 - height + 2; - state.xscroll = 0; - state.yscroll = toolbar->height - 2; /* clipped by the WIMP */ - error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), parent, - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_XORIGIN_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT - << wimp_CHILD_YORIGIN_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_LS_EDGE_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT - << wimp_CHILD_BS_EDGE_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT - << wimp_CHILD_RS_EDGE_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT - << wimp_CHILD_TS_EDGE_SHIFT); - if (error) { - LOG(("xwimp_open_window_nested: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - if (!toolbar->editor) - return true; - - state.w = toolbar->editor->toolbar_handle; - state.visible.y1 -= toolbar->height; - state.yscroll = toolbar->editor->height - 2; - error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), - toolbar->toolbar_handle, - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_XORIGIN_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT - << wimp_CHILD_YORIGIN_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT - << wimp_CHILD_LS_EDGE_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT - << wimp_CHILD_BS_EDGE_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT - << wimp_CHILD_RS_EDGE_SHIFT | - wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT - << wimp_CHILD_TS_EDGE_SHIFT); - if (error) { - LOG(("xwimp_open_window_nested: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - return true; - } - - error = xwimp_close_window(toolbar->toolbar_handle); - if (error) { - LOG(("xwimp_close_window: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - return true; -} - - -/** - * Updates the toolbar to reflect changes to the icon flags and any reformatting - * required due to the change in parent window size. - * - * \param toolbar the toolbar to update - * \param width a specific width to resize to, or -1 to use parent width - * \return whether the operation was successful - */ -bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) -{ - wimp_caret caret; - os_box extent = { 0, 0, 0, 0 }; - os_error *error; - wimp_outline outline; - wimp_window_state state; - int height = -1; - int throbber_x = -1; - int left_edge, right_edge, bottom_edge; - int old_height; - int old_width; - struct toolbar_icon *toolbar_icon; - bool visible_icon = false; - int collapse_height; - int xeig, yeig; - os_coord pixel = {1, 1}; - int top, bottom, right; - - if (!toolbar) - return false; - - old_height = toolbar->height; - old_width = toolbar->toolbar_current; - - /* calculate 1px in OS units */ - ro_convert_pixels_to_os_units(&pixel, (os_mode)-1); - xeig = pixel.x; - yeig = pixel.y; - - /* find the parent window handle if we need to process the status - * window, or the caller has requested we calculate the width ourself */ - if ((toolbar->parent_handle) && (width == -1)) { - outline.w = toolbar->parent_handle; - error = xwimp_get_window_outline(&outline); - if (error) { - LOG(("xwimp_get_window_outline: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - if (width == -1) - width = outline.outline.x1 - outline.outline.x0 - 2; - } - - /* Find the parent visible height to clip our toolbar height to - */ - if ((toolbar->toolbar_handle) && (toolbar->parent_handle)) { - /* Get the current state - */ - state.w = toolbar->parent_handle; - error = xwimp_get_window_state(&state); - if (error) { - LOG(("xwimp_get_window_state: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return false; - } - height = state.visible.y1 - state.visible.y0 + 2; - - /* We can't obscure the height of the scroll bar as we - lose the resize icon if we do. - */ - if ((state.flags & wimp_WINDOW_SIZE_ICON) && - !(state.flags & wimp_WINDOW_HSCROLL)) - height -= ro_get_hscroll_height(0) - 2; - - /* Update our position - */ - if (height != toolbar->max_height) { - if ((state.flags & wimp_WINDOW_SIZE_ICON) && - !(state.flags & wimp_WINDOW_HSCROLL) && - (toolbar->height > toolbar->max_height)) - xwimp_force_redraw(toolbar->parent_handle, - 0, -16384, 16384, 16384); - toolbar->max_height = height; - collapse_height = toolbar->height + - (toolbar->editor ? toolbar->editor->height : 0); - ro_gui_theme_attach_toolbar(toolbar, toolbar->parent_handle); - if ((state.flags & wimp_WINDOW_SIZE_ICON) && - !(state.flags & wimp_WINDOW_HSCROLL) && - (collapse_height > toolbar->max_height)) - xwimp_force_redraw(toolbar->parent_handle, - 0, -16384, 16384, 16384); - } - - } - - /* Reformat the buttons starting with the throbber - */ - if ((width != old_width) || (toolbar->reformat_buttons)) { - left_edge = 6; - right_edge = width - 8; - toolbar->height = 0; - if ((toolbar->descriptor) && (toolbar->descriptor->theme) && - (toolbar->type == THEME_BROWSER_TOOLBAR) && - (toolbar->display_throbber)) { - if (!toolbar->descriptor->throbber_right) { - throbber_x = left_edge; - left_edge += toolbar->descriptor->theme->throbber_width + 8; - } - toolbar->height = toolbar->descriptor->theme->throbber_height + 8; - } - if ((toolbar->type == THEME_BROWSER_TOOLBAR) && (toolbar->display_url)) { - if (toolbar->height < 52 + 8) - toolbar->height = 52 + 8; - if ((toolbar->suggest) && (toolbar->height < - (toolbar->suggest->height + 8))) - toolbar->height = toolbar->suggest->height + 8; - } - - /* Get the minimum height of the icons - */ - bottom_edge = left_edge; - if ((toolbar->display_buttons || toolbar->editor) && (toolbar->descriptor) && - (toolbar->descriptor->theme)) { - toolbar_icon = toolbar->icon; - while (toolbar_icon) { - if (toolbar_icon->display) { - bottom_edge += toolbar_icon->width; - visible_icon = true; - if ((toolbar_icon->height != 0) && - (toolbar->height < toolbar_icon->height + 8)) { - toolbar->height = toolbar_icon->height + 8; - } - } - toolbar_icon = toolbar_icon->next; - } - if (visible_icon) bottom_edge += 8; - } - - /* Check for minimum widths - */ - if (toolbar->type == THEME_BROWSER_TOOLBAR) { - if (!toolbar->reformat_buttons) left_edge = bottom_edge; - if (toolbar->display_url) { - bottom_edge += 112; - if (toolbar->suggest) - bottom_edge += toolbar->suggest->width + 8; - } - if (bottom_edge > right_edge) - right_edge = bottom_edge; - if ((toolbar->descriptor) && (toolbar->descriptor->theme) && - (toolbar->display_throbber) && - (toolbar->descriptor->throbber_right)) { - bottom_edge += toolbar->descriptor->theme->throbber_width; - if (bottom_edge > right_edge) right_edge = bottom_edge; - throbber_x = right_edge - - toolbar->descriptor->theme->throbber_width; - right_edge -= toolbar->descriptor->theme->throbber_width + 8; - } - } - - if (toolbar->height != 0) - toolbar->height += 2; - if (toolbar->reformat_buttons) { - /* Hide the URL bar if we should - */ - if ((!toolbar->display_url) && - (toolbar->type == THEME_BROWSER_TOOLBAR)) { - if (!xwimp_get_caret_position(&caret)) { - if ((caret.w == toolbar->toolbar_handle) && - (caret.i == ICON_TOOLBAR_URL)) { - if (toolbar->parent_handle) - xwimp_set_caret_position( - toolbar->parent_handle, - wimp_ICON_WINDOW, - -100, -100, 32, -1); - else - xwimp_set_caret_position((wimp_w)-1, - 0, 0, 0, 0, 0); - } - } - xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_SURROUND, - 0, -16384, 0, -16384); - xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_FAVICON, - 0, -16384, 0, -16384); - xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_URL, - 0, -16384, 0, -16384); - xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_SUGGEST, - 0, -16384, 0, -16384); - } else if (toolbar->type == THEME_BROWSER_TOOLBAR) { - ro_gui_set_icon_shaded_state(toolbar->toolbar_handle, - ICON_TOOLBAR_URL, !toolbar->display_url); - } - xwimp_force_redraw(toolbar->toolbar_handle, - 0, 0, 16384, 16384); - - /* Move the buttons - */ - toolbar_icon = toolbar->icon; - while (toolbar_icon) { - if ((toolbar->display_buttons || toolbar->editor) && - (toolbar_icon->display) - && (toolbar_icon->width > 0)) { - visible_icon = true; - bottom_edge = (toolbar->height - - toolbar_icon->height) / 2; - toolbar_icon->x = left_edge; - toolbar_icon->y = bottom_edge; - xwimp_resize_icon(toolbar->toolbar_handle, - toolbar_icon->icon_number, - left_edge, bottom_edge, - left_edge + toolbar_icon->width, - bottom_edge + toolbar_icon->height); - left_edge += toolbar_icon->width; - } else { - xwimp_resize_icon(toolbar->toolbar_handle, - toolbar_icon->icon_number, - 0, -16384, 0, -16384); - } - toolbar_icon = toolbar_icon->next; - } - if (visible_icon) left_edge += 8; - } - - - if (toolbar->type == THEME_BROWSER_TOOLBAR) { - /* Move the URL bar - */ - if (toolbar->display_url) { - top = (toolbar->height / 2) + 26; - bottom = (toolbar->height / 2) - 26; - if (toolbar->suggest) { - right = right_edge - toolbar->suggest->width - 8; - xwimp_resize_icon(toolbar->toolbar_handle, - ICON_TOOLBAR_SUGGEST, - right_edge - toolbar->suggest->width, - (toolbar->height - toolbar->suggest->height) / 2, - right_edge, - (toolbar->height + toolbar->suggest->height) / 2); - } else { - right = right_edge; - } - xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_URL, - left_edge + 52, - bottom + yeig, - right - xeig, - top - yeig); - xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_FAVICON, - left_edge + xeig, - bottom + yeig, - left_edge + 52, - top - yeig); - xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_SURROUND, - left_edge, - bottom, - right, - top); - xwimp_force_redraw(toolbar->toolbar_handle, - right - xeig, 0, 16384, 16384); - xwimp_force_redraw(toolbar->toolbar_handle, - left_edge, - bottom, - right, - bottom + yeig); - xwimp_force_redraw(toolbar->toolbar_handle, - left_edge, - top - yeig, - right, - top); - if (!xwimp_get_caret_position(&caret)) { - if ((caret.w == toolbar->toolbar_handle) && - (caret.i == ICON_TOOLBAR_URL)) { - xwimp_set_caret_position(toolbar->toolbar_handle, - ICON_TOOLBAR_URL, - caret.pos.x, caret.pos.y, - -1, caret.index); - } - } - ro_gui_redraw_icon(toolbar->toolbar_handle, ICON_TOOLBAR_URL); - } - - /* Move the throbber - */ - if ((toolbar->descriptor) && (toolbar->descriptor->theme) && - (throbber_x >= 0) && (toolbar->display_throbber)) { - xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_THROBBER, - throbber_x, 0, - throbber_x + toolbar->descriptor->theme->throbber_width, - toolbar->height); - if (toolbar->descriptor->throbber_right) { - xwimp_force_redraw(toolbar->toolbar_handle, - old_width - width + throbber_x, 0, 16384, 16384); - xwimp_force_redraw(toolbar->toolbar_handle, - throbber_x, 0, 16384, 16384); - } - - } else { - xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_THROBBER, - 0, -16384, 0, -16384); - } - } - - /* Re-attach to the parent - */ - toolbar->toolbar_current = width; - if (toolbar->reformat_buttons) { - extent.x1 = 16384; - extent.y0 = (toolbar->editor ? -toolbar->editor->height : 0); - extent.y1 = toolbar->height - 2; - xwimp_set_extent(toolbar->toolbar_handle, &extent); - if ((toolbar->parent_handle) && (old_height != toolbar->height)) - ro_gui_theme_attach_toolbar(toolbar, toolbar->parent_handle); - } - toolbar->reformat_buttons = false; - } - return true; -} - - -/** - * Destroys a toolbar and frees any associated memory. - * - * \param toolbar the toolbar to destroy - */ -void ro_gui_theme_destroy_toolbar(struct toolbar *toolbar) -{ - struct toolbar_icon *icon; - struct toolbar_icon *next_icon; - if (!toolbar) return; - - /* Destroy our editor - */ - if (toolbar->editor) { - toolbar->editor = NULL; - ro_gui_theme_destroy_toolbar(toolbar->editor); - } - - /* Delete our windows - */ - if (toolbar->toolbar_handle) { - xwimp_delete_window(toolbar->toolbar_handle); - ro_gui_wimp_event_finalise(toolbar->toolbar_handle); - } - /* Free the Wimp buffer (we only created one for them all) - */ - free(toolbar->url_buffer); - - /* Free all the icons - */ - next_icon = toolbar->icon; - while ((icon = next_icon) != NULL) { - next_icon = icon->next; - ro_gui_theme_destroy_toolbar_icon(icon); - } - ro_gui_theme_destroy_toolbar_icon(toolbar->suggest); - free(toolbar); -} - - -/** - * Refresh a toolbar after it has been updated - * - * \param toolbar the toolbar to update - */ -void ro_gui_theme_refresh_toolbar(struct toolbar *toolbar) -{ - assert(toolbar); - - toolbar->reformat_buttons = true; - ro_gui_theme_process_toolbar(toolbar, -1); - if (toolbar->type == THEME_BROWSER_TOOLBAR) { - gui_window_update_extent(ro_gui_window_lookup( - current_menu_window)); - } else if (toolbar->type == THEME_HOTLIST_TOOLBAR) { - ro_gui_hotlist_update_theme(false); - } else if (toolbar->type == THEME_HISTORY_TOOLBAR) { - ro_gui_global_history_update_theme(false); - } else if (toolbar->type == THEME_COOKIES_TOOLBAR) { - ro_gui_cookies_update_theme(false); - } -} - - -/** - * Toggles the toolbar editing mode - * - * \param toolbar the toolbar to toggle editing for - */ -void ro_gui_theme_toggle_edit(struct toolbar *toolbar) -{ - int icons = 0; - struct toolbar_icon *icon; - struct gui_window *g = NULL; - wimp_window_state state; - os_error *error; - char *option; - char hex_no[4]; - - if (!toolbar) - return; - - if ((toolbar->type == THEME_BROWSER_TOOLBAR) && - (toolbar->parent_handle)) - g = ro_gui_window_lookup(toolbar->parent_handle); - - if (toolbar->editor) { - /* save options */ - icons = 0; - for (icon = toolbar->icon; icon; icon = icon->next) - if (icon->display) icons++; - option = calloc(icons + 1, 1); - if (!option) { - LOG(("No memory to save toolbar options")); - warn_user("NoMemory", 0); - } else { - icons = 0; - for (icon = toolbar->icon; icon; icon = icon->next) - if (icon->display) { - if (icon->icon_number == -1) { - option[icons] = '|'; - } else { - sprintf(hex_no, "%x", icon->icon_number); - option[icons] = hex_no[0]; - } - icons++; - } - switch (toolbar->type) { - case THEME_BROWSER_TOOLBAR: - free(option_toolbar_browser); - option_toolbar_browser = option; - break; - case THEME_HOTLIST_TOOLBAR: - free(option_toolbar_hotlist); - option_toolbar_hotlist = option; - break; - case THEME_HISTORY_TOOLBAR: - free(option_toolbar_history); - option_toolbar_history = option; - break; - case THEME_COOKIES_TOOLBAR: - free(option_toolbar_cookies); - option_toolbar_cookies = option; - break; - default: - break; - } - ro_gui_save_options(); - } - - /* turn off editing */ - ro_gui_theme_destroy_toolbar(toolbar->editor); - toolbar->editor = NULL; - ro_gui_theme_update_toolbar(toolbar->descriptor, toolbar); - switch (toolbar->type) { - case THEME_BROWSER_TOOLBAR: - if (g) - gui_window_update_extent(g); - break; - default: - if (toolbar->parent_handle) - xwimp_force_redraw(toolbar->parent_handle, - 0, -16384, 16384, 16384); - break; - } - } else { - /* create/initialise the toolbar editor */ - switch (toolbar->type) { - case THEME_BROWSER_TOOLBAR: - toolbar->editor = ro_gui_theme_create_toolbar( - toolbar->descriptor, - THEME_BROWSER_EDIT_TOOLBAR); - break; - case THEME_HOTLIST_TOOLBAR: - toolbar->editor = ro_gui_theme_create_toolbar( - toolbar->descriptor, - THEME_HOTLIST_EDIT_TOOLBAR); - break; - case THEME_HISTORY_TOOLBAR: - toolbar->editor = ro_gui_theme_create_toolbar( - toolbar->descriptor, - THEME_HISTORY_EDIT_TOOLBAR); - break; - case THEME_COOKIES_TOOLBAR: - toolbar->editor = ro_gui_theme_create_toolbar( - toolbar->descriptor, - THEME_COOKIES_EDIT_TOOLBAR); - break; - default: - return; - } - if (!toolbar->editor) { - LOG(("Unable to create toolbar editor")); - return; - } - ro_gui_wimp_event_set_user_data(toolbar->editor->toolbar_handle, - ro_gui_wimp_event_get_user_data(toolbar->toolbar_handle)); - ro_gui_theme_update_toolbar(toolbar->descriptor, toolbar); - switch (toolbar->type) { - case THEME_BROWSER_TOOLBAR: - if (g) - gui_window_update_extent(g); - break; - default: - if (toolbar->parent_handle) { - state.w = toolbar->parent_handle; - error = xwimp_get_window_state(&state); - if (error) { - LOG(("xwimp_get_window_state: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return; - } - ro_gui_open_window_request(PTR_WIMP_OPEN(&state)); - xwimp_force_redraw(toolbar->parent_handle, - 0, -16384, 16384, 16384); - } - break; - } - ro_gui_theme_process_toolbar(toolbar, -1); - ro_gui_theme_toolbar_editor_sync(toolbar); - } - ro_gui_theme_set_help_prefix(toolbar); -} - - -/** - * Synchronise a toolbar window with the associated editor. - * - * \param toolbar the toolbar to synchronise - */ -void ro_gui_theme_toolbar_editor_sync(struct toolbar *toolbar) -{ - struct toolbar_icon *icon; - struct toolbar_icon *icon_edit; - - if ((!toolbar) || (!toolbar->editor)) - return; - - for (icon = toolbar->icon; icon; icon = icon->next) - if ((icon->icon_number >= 0) && (icon->width > 0)) - for (icon_edit = toolbar->editor->icon; icon_edit; - icon_edit = icon_edit->next) - if (icon_edit->icon_number == icon->icon_number) - ro_gui_set_icon_shaded_state( - toolbar->editor->toolbar_handle, - icon_edit->icon_number, - icon->display); -} - - -/** - * Handle a toolbar click during an editor session - * - * \param toolbar the base toolbar (ie not editor) to respond to a click for - * \param pointer the WIMP pointer details - */ -void ro_gui_theme_toolbar_editor_click(struct toolbar *toolbar, - wimp_pointer *pointer) { - wimp_window_state state; - os_error *error; - os_box box; - - if (!toolbar->editor) - return; - if ((pointer->buttons != (wimp_CLICK_SELECT << 4)) && - (pointer->buttons != (wimp_CLICK_ADJUST << 4))) - return; - - state.w = pointer->w; - error = xwimp_get_window_state(&state); - if (error) { - LOG(("xwimp_get_window_state: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return; - } - - gui_current_drag_type = GUI_DRAG_TOOLBAR_CONFIG; - theme_toolbar_drag = toolbar; - theme_toolbar_editor_drag = !(pointer->w == toolbar->toolbar_handle); - if (theme_toolbar_editor_drag) - theme_toolbar_icon_drag = - ro_gui_theme_toolbar_get_icon(toolbar->editor, - pointer->pos.x - state.visible.x0, - state.visible.y1 - pointer->pos.y); - else - theme_toolbar_icon_drag = - ro_gui_theme_toolbar_get_icon(toolbar, - pointer->pos.x - state.visible.x0, - state.visible.y1 - pointer->pos.y); - if (!theme_toolbar_icon_drag) - return; - if ((theme_toolbar_icon_drag->icon_number >= 0) && - (pointer->w == toolbar->editor->toolbar_handle) && - (ro_gui_get_icon_shaded_state( - toolbar->editor->toolbar_handle, - theme_toolbar_icon_drag->icon_number))) - return; - - box.x0 = pointer->pos.x - theme_toolbar_icon_drag->width / 2; - box.x1 = box.x0 + theme_toolbar_icon_drag->width; - box.y0 = pointer->pos.y - theme_toolbar_icon_drag->height / 2; - box.y1 = box.y0 + theme_toolbar_icon_drag->height; - error = xdragasprite_start(dragasprite_HPOS_CENTRE | - dragasprite_VPOS_CENTRE | - dragasprite_BOUND_POINTER | - dragasprite_DROP_SHADOW, - toolbar->descriptor->theme->sprite_area, - theme_toolbar_icon_drag->name, &box, 0); - if (error) - LOG(("xdragasprite_start: 0x%x: %s", - error->errnum, error->errmess)); -} - - -/** - * Handle the end of a drag - * - * \param drag the details for the drag end - */ -void ro_gui_theme_toolbar_editor_drag_end(wimp_dragged *drag) -{ - wimp_window_state state; - os_error *error; - wimp_pointer pointer; - struct toolbar_icon *insert_icon; - struct toolbar_icon *local_icon = NULL; - struct toolbar_icon *icon; - bool before = false; - - if ((!theme_toolbar_drag) || (!theme_toolbar_icon_drag) || - (!theme_toolbar_drag->editor)) - return; - - error = xwimp_get_pointer_info(&pointer); - if (error) { - LOG(("xwimp_get_pointer_info: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return; - } - - if (pointer.w == theme_toolbar_drag->toolbar_handle) { - /* drag from editor or toolbar to toolbar */ - state.w = pointer.w; - error = xwimp_get_window_state(&state); - if (error) { - LOG(("xwimp_get_window_state: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return; - } - insert_icon = ro_gui_theme_toolbar_get_insert_icon( - theme_toolbar_drag, - pointer.pos.x - state.visible.x0, - state.visible.y1 - pointer.pos.y, &before); - if (theme_toolbar_icon_drag->icon_number == -1) { - if (theme_toolbar_editor_drag) { - theme_toolbar_icon_drag = - ro_gui_theme_add_toolbar_icon( - theme_toolbar_drag, - NULL, -1); - ro_gui_theme_update_toolbar_icon( - theme_toolbar_drag, - theme_toolbar_icon_drag); - } - /* move the separator */ - if (theme_toolbar_icon_drag != insert_icon) { - ro_gui_theme_delink_toolbar_icon( - theme_toolbar_drag, - theme_toolbar_icon_drag); - ro_gui_theme_link_toolbar_icon( - theme_toolbar_drag, - theme_toolbar_icon_drag, - insert_icon, before); - } - } else { - /* move/enable the icon */ - for (icon = theme_toolbar_drag->icon; icon; - icon = icon->next) - if (theme_toolbar_icon_drag->icon_number == - icon->icon_number) - local_icon = icon; - if (!local_icon) - return; - if (local_icon != insert_icon) { - ro_gui_theme_delink_toolbar_icon( - theme_toolbar_drag, local_icon); - ro_gui_theme_link_toolbar_icon( - theme_toolbar_drag, local_icon, - insert_icon, before); - } - local_icon->display = true; - } - } else if ((pointer.w == theme_toolbar_drag->editor->toolbar_handle) && - (!theme_toolbar_editor_drag)) { - /* drag from toolbar to editor */ - if (theme_toolbar_icon_drag->icon_number == -1) { - /* delete separators */ - ro_gui_theme_delink_toolbar_icon(theme_toolbar_drag, - theme_toolbar_icon_drag); - ro_gui_theme_destroy_toolbar_icon( - theme_toolbar_icon_drag); - } else { - /* hide icons */ - theme_toolbar_icon_drag->display = false; - } - } - theme_toolbar_drag->reformat_buttons = true; - ro_gui_theme_process_toolbar(theme_toolbar_drag, -1); - ro_gui_theme_toolbar_editor_sync(theme_toolbar_drag); -} - - -/** - * Adds a toolbar icon to the end of a toolbar - * - * \param toolbar the toolbar to add the icon to the end of (or NULL) - * \param name the icon name, or NULL for a separator - * \param icon_number RISC OS wimp icon number for the icon (not separators) - */ -struct toolbar_icon *ro_gui_theme_add_toolbar_icon(struct toolbar *toolbar, - const char *name, int icon_number) -{ - struct toolbar_icon *toolbar_icon; - struct toolbar_icon *link_icon; - - /* Separators are really a sprite called "separator" - */ - if (name == NULL) { - name = "separator"; - icon_number = -1; - } - - /* Create a new toolbar - */ - toolbar_icon = calloc(sizeof(struct toolbar_icon), 1); - if (!toolbar_icon) { - LOG(("No memory for malloc()")); - warn_user("NoMemory", 0); - return NULL; - } - - /* Set up and link in the icon - */ - sprintf(toolbar_icon->name, name); - sprintf(toolbar_icon->validation, "R5;S%s,p%s", name, name); - toolbar_icon->icon_number = icon_number; - toolbar_icon->display = true; - if (toolbar) { - if (!toolbar->icon) { - toolbar->icon = toolbar_icon; - } else { - link_icon = toolbar->icon; - while (link_icon->next) link_icon = link_icon->next; - link_icon->next = toolbar_icon; - } - } - return toolbar_icon; -} - - -/** - * Updates a toolbar icon with respect to the associated sprite. - * - * \param icon the toolbar icon to update - */ -void ro_gui_theme_update_toolbar_icon(struct toolbar *toolbar, - struct toolbar_icon *icon) -{ - os_coord dimensions = {0, 0}; - os_mode mode; - os_error *error = NULL; - int default_width = 0; - osspriteop_area *sprite_area = NULL; - - /* Separators default to a width of 16 */ - if (icon->icon_number == -1) - default_width = 16; - - /* Handle no theme/no sprite area */ - if (!toolbar) - return; - if ((toolbar->descriptor) && (toolbar->descriptor->theme)) - sprite_area = toolbar->descriptor->theme->sprite_area; - - /* Get the sprite details */ - if (sprite_area) - error = xosspriteop_read_sprite_info(osspriteop_USER_AREA, - sprite_area, (osspriteop_id)icon->name, - &dimensions.x, &dimensions.y, 0, &mode); - - /* fallback to Wimp pool, if necessary */ - if (error || sprite_area == NULL) - error = xwimpspriteop_read_sprite_info(icon->name, - &dimensions.x, &dimensions.y, 0, &mode); - - /* Give up, if both failed */ - if (error) { - icon->width = default_width; - icon->height = 0; - if (error->errnum != error_SPRITE_OP_DOESNT_EXIST) { - LOG(("xosspriteop_read_sprite_info: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("MiscError", error->errmess); - } - return; - } - - /* Store the details */ - ro_convert_pixels_to_os_units(&dimensions, mode); - icon->width = dimensions.x; - icon->height = dimensions.y; -} - - -/** - * Destroys a toolbar icon and frees any associated memory. - * The icon is not removed from any linked list. - * - * \param icon the toolbar icon to destroy - */ -void ro_gui_theme_destroy_toolbar_icon(struct toolbar_icon *icon) -{ - free(icon); -} - - -/** - * Links a toolbar icon - * - * \param icon the toolbar icon to link - */ -void ro_gui_theme_link_toolbar_icon(struct toolbar *toolbar, - struct toolbar_icon *icon, struct toolbar_icon *link, - bool before) -{ - struct toolbar_icon *temp; - assert(toolbar); - assert(icon); - assert(icon != link); - - /* no icon set, no link icon, or insert at head of list */ - if ((!toolbar->icon) || (!link) || - (before && (toolbar->icon == link))) { - if (toolbar->icon != icon) { - icon->next = toolbar->icon; - toolbar->icon = icon; - } - return; - } - - if (before) { - for (temp = toolbar->icon; temp; temp = temp->next) - if (temp->next == link) { - temp->next = icon; - icon->next = link; - return; - } - } else { - icon->next = link->next; - link->next = icon; - } -} - -/** - * Delinks a toolbar icon - * - * \param icon the toolbar icon to delink - */ -void ro_gui_theme_delink_toolbar_icon(struct toolbar *toolbar, - struct toolbar_icon *icon) -{ - struct toolbar_icon *link; - assert(toolbar); - assert(icon); - - if (toolbar->icon == icon) { - toolbar->icon = icon->next; - icon->next = NULL; - return; - } - - for (link = toolbar->icon; link; link = link->next) - if (link->next == icon) { - link->next = icon->next; - icon->next = NULL; - return; - } -} - - -/** - * Returns the toolbar icon at a specified position - * - * \param toolbar the toolbar to examine - * \param x the x co-ordinate to check - * \param y the y co-ordinate to check - * \return the toolbar icon at the specified position, or NULL for no icon - */ -struct toolbar_icon *ro_gui_theme_toolbar_get_icon(struct toolbar *toolbar, - int x, int y) -{ - struct toolbar_icon *icon; - - for (icon = toolbar->icon; icon; icon = icon->next) - if ((icon->display) && (icon->width > 0) && - (icon->x <= x) && (icon->y <= y) && - (icon->x + icon->width > x) && - (icon->y + icon->height > y)) - return icon; - return NULL; -} - - -/** - * Returns the toolbar icon closest to the specified position, and whether the - * position is before (left) or after (right) of it. - * - * \param toolbar the toolbar to examine - * \param x the x co-ordinate to check - * \param y the y co-ordinate to check - * \return the toolbar icon closest to the specified position, or NULL - */ -struct toolbar_icon *ro_gui_theme_toolbar_get_insert_icon( - struct toolbar *toolbar, int x, int y, bool *before) -{ - struct toolbar_icon *match = NULL; - struct toolbar_icon *icon; - int closest = 65536; - int distance; - - if (!toolbar->icon) - return NULL; - - for (icon = toolbar->icon; icon; icon = icon->next) { - if ((icon->display) && (icon->width > 0)) { - distance = icon->x + icon->width / 2 - x; - if (distance < 0) - distance = -distance; - if (distance < closest) { - closest = distance; - match = icon; - *before = (icon->x + icon->width / 2 - x) > 0; - } - } - } - return match; -} - - -/** - * Sets up a toolbar with icons according to an identifier string - */ -void ro_gui_theme_add_toolbar_icons(struct toolbar *toolbar, - const char* icons[], const char* ident) -{ - struct toolbar_icon *icon; - int index = 0; - int number = 0; - char hex_no[4]; - - /* step 1: add all main icons in their correct state */ - while (icons[index]) { - icon = ro_gui_theme_add_toolbar_icon(toolbar, icons[index], - index); - sprintf(hex_no, "%x", index); - if ((icon) && (!strchr(ident, hex_no[0]))) - icon->display = false; - index++; - } - - /* step 2: re-order and add separators */ - index = strlen(ident); - while (index--) { - if (ident[index] == '|') { - icon = ro_gui_theme_add_toolbar_icon(NULL, NULL, -1); - if (icon) - ro_gui_theme_link_toolbar_icon(toolbar, icon, - NULL, NULL); - } else { - hex_no[0] = ident[index]; - hex_no[1] = '\0'; - number = strtol(hex_no, NULL, 16); - for (icon = toolbar->icon; icon; icon = icon->next) - if (icon->icon_number == number) { - ro_gui_theme_delink_toolbar_icon( - toolbar, icon); - ro_gui_theme_link_toolbar_icon(toolbar, - icon, NULL, NULL); - } - } - } -} - - -/** - * Sets the correct help prefix for a toolbar - */ -void ro_gui_theme_set_help_prefix(struct toolbar *toolbar) -{ - if (toolbar->editor) { - ro_gui_wimp_event_set_help_prefix(toolbar->toolbar_handle, - "HelpEditToolbar"); - return; - } - switch (toolbar->type) { - case THEME_BROWSER_TOOLBAR: - ro_gui_wimp_event_set_help_prefix(toolbar->toolbar_handle, - "HelpToolbar"); - break; - case THEME_HOTLIST_TOOLBAR: - ro_gui_wimp_event_set_help_prefix(toolbar->toolbar_handle, - "HelpHotToolbar"); - break; - case THEME_HISTORY_TOOLBAR: - ro_gui_wimp_event_set_help_prefix(toolbar->toolbar_handle, - "HelpGHistToolbar"); - break; - case THEME_COOKIES_TOOLBAR: - ro_gui_wimp_event_set_help_prefix(toolbar->toolbar_handle, - "HelpCookiesToolbar"); - break; - case THEME_BROWSER_EDIT_TOOLBAR: - case THEME_HOTLIST_EDIT_TOOLBAR: - case THEME_HISTORY_EDIT_TOOLBAR: - case THEME_COOKIES_EDIT_TOOLBAR: - ro_gui_wimp_event_set_help_prefix(toolbar->toolbar_handle, - "HelpEditToolbar"); - break; - } -} - -int ro_gui_theme_height_change(struct toolbar *toolbar) -{ - int height, cur_height; - - cur_height = ro_gui_theme_toolbar_full_height(toolbar); - height = toolbar->old_height - cur_height; - toolbar->old_height = cur_height; - return height; -} |