summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscos/Makefile.target18
-rw-r--r--riscos/configure/con_connect.c12
-rw-r--r--riscos/configure/con_home.c32
-rw-r--r--riscos/configure/con_image.c21
-rw-r--r--riscos/configure/con_theme.c39
-rw-r--r--riscos/cookies.c212
-rw-r--r--riscos/cookies.h8
-rw-r--r--riscos/dialog.c40
-rw-r--r--riscos/dialog.h2
-rw-r--r--riscos/global_history.c231
-rw-r--r--riscos/global_history.h8
-rw-r--r--riscos/gui.c83
-rw-r--r--riscos/gui.h34
-rw-r--r--riscos/gui/button_bar.c1231
-rw-r--r--riscos/gui/button_bar.h314
-rw-r--r--riscos/gui/throbber.c419
-rw-r--r--riscos/gui/throbber.h144
-rw-r--r--riscos/gui/url_bar.c984
-rw-r--r--riscos/gui/url_bar.h302
-rw-r--r--riscos/help.c43
-rw-r--r--riscos/hotlist.c242
-rw-r--r--riscos/hotlist.h7
-rw-r--r--riscos/iconbar.c233
-rw-r--r--riscos/iconbar.h32
-rw-r--r--riscos/menus.c1559
-rw-r--r--riscos/menus.h19
-rw-r--r--riscos/plugin.c9
-rw-r--r--riscos/print.c2
-rw-r--r--riscos/search.c59
-rw-r--r--riscos/sslcert.c4
-rw-r--r--riscos/textselection.c5
-rw-r--r--riscos/theme.c1857
-rw-r--r--riscos/theme.h122
-rw-r--r--riscos/toolbar.c1770
-rw-r--r--riscos/toolbar.h525
-rw-r--r--riscos/treeview.c173
-rw-r--r--riscos/treeview.h12
-rw-r--r--riscos/uri.c1
-rw-r--r--riscos/url_complete.c218
-rw-r--r--riscos/url_complete.h68
-rw-r--r--riscos/url_suggest.c71
-rw-r--r--riscos/url_suggest.h6
-rw-r--r--riscos/wimp.c112
-rw-r--r--riscos/wimp.h5
-rw-r--r--riscos/wimp_event.c424
-rw-r--r--riscos/wimp_event.h39
-rw-r--r--riscos/window.c4217
-rw-r--r--riscos/window.h33
48 files changed, 10688 insertions, 5313 deletions
diff --git a/riscos/Makefile.target b/riscos/Makefile.target
index 685979d77..f7ba8d895 100644
--- a/riscos/Makefile.target
+++ b/riscos/Makefile.target
@@ -1,4 +1,4 @@
-# RISC OS Target makefile
+# RISC OS Target makefile
# ----------------------------------------------------------------------------
# RISC OS target setup
@@ -68,13 +68,15 @@ endif
S_RISCOS := 401login.c artworks.c assert.c awrender.s bitmap.c buffer.c \
cookies.c configure.c debugwin.c dialog.c download.c draw.c \
filetype.c font.c global_history.c gui.c help.c history.c \
- hotlist.c image.c menus.c message.c palettes.c plotters.c \
- plugin.c print.c query.c save.c save_draw.c save_pdf.c \
- schedule.c search.c searchweb.c sprite.c sslcert.c \
- textarea.c textselection.c theme.c theme_install.c thumbnail.c \
- treeview.c ucstables.c uri.c url_complete.c url_protocol.c \
- url_suggest.c wimp.c wimp_event.c window.c system_colour.c \
- gui/progress_bar.c gui/status_bar.c \
+ hotlist.c iconbar.c image.c menus.c message.c palettes.c \
+ plotters.c plugin.c print.c query.c save.c save_draw.c \
+ save_pdf.c schedule.c search.c searchweb.c sprite.c sslcert.c \
+ system_colour.c textarea.c textselection.c theme.c \
+ theme_install.c thumbnail.c toolbar.c treeview.c ucstables.c \
+ uri.c url_complete.c url_protocol.c url_suggest.c wimp.c \
+ wimp_event.c window.c \
+ $(addprefix gui/,button_bar.c progress_bar.c status_bar.c \
+ throbber.c url_bar.c) \
$(addprefix configure/,con_cache.c con_connect.c con_content.c \
con_fonts.c con_home.c con_image.c con_inter.c con_language.c \
con_memory.c con_secure.c con_theme.c)
diff --git a/riscos/configure/con_connect.c b/riscos/configure/con_connect.c
index 70236f23a..fd74155bd 100644
--- a/riscos/configure/con_connect.c
+++ b/riscos/configure/con_connect.c
@@ -60,7 +60,8 @@
static int ro_gui_options_connection_proxy_type(wimp_w w);
static void ro_gui_options_connection_default(wimp_pointer *pointer);
static bool ro_gui_options_connection_ok(wimp_w w);
-static void ro_gui_options_connection_update(wimp_w w, wimp_i i);
+static bool ro_gui_options_connection_update(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_selection *s, menu_action a);
bool ro_gui_options_connection_initialise(wimp_w w)
{
@@ -88,7 +89,7 @@ bool ro_gui_options_connection_initialise(wimp_w w)
option_max_fetchers_per_host);
ro_gui_set_icon_integer(w, CONNECTION_CACHE_FETCH_FIELD,
option_max_cached_fetch_handles);
- ro_gui_options_connection_update(w, -1);
+ ro_gui_options_connection_update(w, -1, NULL, NULL, NO_ACTION);
/* register icons */
ro_gui_wimp_event_register_menu_gright(w, CONNECTION_PROXY_FIELD,
@@ -124,7 +125,8 @@ bool ro_gui_options_connection_initialise(wimp_w w)
}
-void ro_gui_options_connection_update(wimp_w w, wimp_i i)
+bool ro_gui_options_connection_update(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_selection *s, menu_action a)
{
int proxy_type;
bool host, user;
@@ -142,6 +144,8 @@ void ro_gui_options_connection_update(wimp_w w, wimp_i i)
ro_gui_set_icon_shaded_state(w, CONNECTION_PROXY_USERNAME, !user);
ro_gui_set_icon_shaded_state(w, CONNECTION_PROXY_PASSWORD_LABEL, !user);
ro_gui_set_icon_shaded_state(w, CONNECTION_PROXY_PASSWORD, !user);
+
+ return true;
}
int ro_gui_options_connection_proxy_type(wimp_w w)
@@ -169,7 +173,7 @@ void ro_gui_options_connection_default(wimp_pointer *pointer)
ro_gui_set_icon_integer(pointer->w, CONNECTION_MAX_FETCH_FIELD, 24);
ro_gui_set_icon_integer(pointer->w, CONNECTION_HOST_FETCH_FIELD, 5);
ro_gui_set_icon_integer(pointer->w, CONNECTION_CACHE_FETCH_FIELD, 6);
- ro_gui_options_connection_update(pointer->w, -1);
+ ro_gui_options_connection_update(pointer->w, -1, NULL, NULL, NO_ACTION);
}
bool ro_gui_options_connection_ok(wimp_w w)
diff --git a/riscos/configure/con_home.c b/riscos/configure/con_home.c
index fbe1b7039..65cc4e39a 100644
--- a/riscos/configure/con_home.c
+++ b/riscos/configure/con_home.c
@@ -30,7 +30,6 @@
#include "utils/messages.h"
#include "utils/utils.h"
-
#define HOME_URL_FIELD 3
#define HOME_URL_GRIGHT 4
#define HOME_OPEN_STARTUP 5
@@ -40,6 +39,8 @@
static void ro_gui_options_home_default(wimp_pointer *pointer);
static bool ro_gui_options_home_ok(wimp_w w);
+static bool ro_gui_options_home_menu_prepare(wimp_w w, wimp_i i,
+ wimp_menu *menu, wimp_pointer *pointer);
bool ro_gui_options_home_initialise(wimp_w w)
{
@@ -53,13 +54,15 @@ bool ro_gui_options_home_initialise(wimp_w w)
/* initialise all functions for a newly created window */
ro_gui_wimp_event_register_menu_gright(w, HOME_URL_FIELD,
- HOME_URL_GRIGHT, url_suggest_menu);
+ HOME_URL_GRIGHT, ro_gui_url_suggest_menu);
ro_gui_wimp_event_register_checkbox(w, HOME_OPEN_STARTUP);
ro_gui_wimp_event_register_button(w, HOME_DEFAULT_BUTTON,
ro_gui_options_home_default);
ro_gui_wimp_event_register_cancel(w, HOME_CANCEL_BUTTON);
ro_gui_wimp_event_register_ok(w, HOME_OK_BUTTON,
ro_gui_options_home_ok);
+ ro_gui_wimp_event_register_menu_prepare(w,
+ ro_gui_options_home_menu_prepare);
ro_gui_wimp_event_set_help_prefix(w, "HelpHomeConfig");
ro_gui_wimp_event_memorise(w);
return true;
@@ -84,3 +87,28 @@ bool ro_gui_options_home_ok(wimp_w w)
ro_gui_save_options();
return true;
}
+
+
+/**
+ * Callback to prepare menus in the Configure Home dialog. At present, this
+ * only has to handle the URL Suggestion pop-up.
+ *
+ * \param w The window handle owning the menu.
+ * \param i The icon handle owning the menu.
+ * \param *menu The menu to be prepared.
+ * \param *pointer The associated mouse click event block, or NULL
+ * on an Adjust-click re-opening.
+ * \return true if the event was handled; false if not.
+ */
+
+bool ro_gui_options_home_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer)
+{
+ if (menu != ro_gui_url_suggest_menu || i != HOME_URL_GRIGHT)
+ return false;
+
+ if (pointer != NULL)
+ ro_gui_url_suggest_prepare_menu();
+
+ return true;
+}
diff --git a/riscos/configure/con_image.c b/riscos/configure/con_image.c
index 45925d39b..1cb29a267 100644
--- a/riscos/configure/con_image.c
+++ b/riscos/configure/con_image.c
@@ -50,8 +50,9 @@
static bool ro_gui_options_image_click(wimp_pointer *pointer);
static bool ro_gui_options_image_ok(wimp_w w);
static void ro_gui_options_image_redraw(wimp_draw *redraw);
-static void ro_gui_options_image_update(wimp_w w, wimp_i i);
-static void ro_gui_options_image_read(wimp_w w, unsigned int *bg,
+static bool ro_gui_options_image_update(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_selection *s, menu_action a);
+static void ro_gui_options_image_read(wimp_w w, unsigned int *bg,
unsigned int *fg);
static void ro_gui_options_update_shading(wimp_w w);
@@ -86,7 +87,7 @@ bool ro_gui_options_image_initialise(wimp_w w)
image_quality_menu->entries[i].
data.indirected_text.text, true);
}
- ro_gui_set_icon_decimal(w, IMAGE_SPEED_FIELD,
+ ro_gui_set_icon_decimal(w, IMAGE_SPEED_FIELD,
option_minimum_gif_delay, 2);
ro_gui_set_icon_selected_state(w, IMAGE_DISABLE_ANIMATION,
!option_animate_images);
@@ -127,9 +128,12 @@ void ro_gui_options_image_finalise(wimp_w w)
ro_gui_wimp_event_finalise(w);
}
-void ro_gui_options_image_update(wimp_w w, wimp_i i)
+bool ro_gui_options_image_update(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_selection *s, menu_action a)
{
ro_gui_redraw_icon(w, IMAGE_CURRENT_DISPLAY);
+
+ return true;
}
void ro_gui_options_image_redraw(wimp_draw *redraw)
@@ -204,11 +208,11 @@ bool ro_gui_options_image_click(wimp_pointer *pointer)
ro_gui_options_image_read(pointer->w, &old_bg, &old_fg);
switch (pointer->i) {
case IMAGE_DEFAULT_BUTTON:
- ro_gui_set_icon_string(pointer->w,
+ ro_gui_set_icon_string(pointer->w,
IMAGE_FOREGROUND_FIELD,
image_quality_menu->entries[3].
data.indirected_text.text, true);
- ro_gui_set_icon_string(pointer->w,
+ ro_gui_set_icon_string(pointer->w,
IMAGE_BACKGROUND_FIELD,
image_quality_menu->entries[2].
data.indirected_text.text, true);
@@ -228,7 +232,8 @@ bool ro_gui_options_image_click(wimp_pointer *pointer)
ro_gui_options_image_read(pointer->w, &bg, &fg);
if ((bg != old_bg) || (fg != old_fg))
- ro_gui_options_image_update(pointer->w, pointer->i);
+ ro_gui_options_image_update(pointer->w, pointer->i,
+ NULL, NULL, NO_ACTION);
return false;
}
@@ -247,7 +252,7 @@ void ro_gui_options_update_shading(wimp_w w)
bool ro_gui_options_image_ok(wimp_w w)
{
- ro_gui_options_image_read(w, (unsigned int *) &option_bg_plot_style,
+ ro_gui_options_image_read(w, (unsigned int *) &option_bg_plot_style,
(unsigned int *) &option_fg_plot_style);
option_minimum_gif_delay = ro_gui_get_icon_decimal(w,
IMAGE_SPEED_FIELD, 2);
diff --git a/riscos/configure/con_theme.c b/riscos/configure/con_theme.c
index 0954a31e9..a6dc98265 100644
--- a/riscos/configure/con_theme.c
+++ b/riscos/configure/con_theme.c
@@ -29,6 +29,7 @@
#include "riscos/menus.h"
#include "riscos/options.h"
#include "riscos/theme.h"
+#include "riscos/toolbar.h"
#include "riscos/url_complete.h"
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
@@ -261,11 +262,17 @@ void ro_gui_options_theme_load(void)
/* create toolbars for each theme */
theme_count = 0;
descriptor = theme_list;
- while (descriptor) {
+ while (descriptor != NULL) {
/* try to create a toolbar */
- toolbar = ro_gui_theme_create_toolbar(descriptor,
- THEME_BROWSER_TOOLBAR);
- if (toolbar) {
+ toolbar = ro_toolbar_create(descriptor, NULL,
+ THEME_STYLE_BROWSER_TOOLBAR,
+ TOOLBAR_FLAGS_DISPLAY, NULL, NULL, NULL);
+ if (toolbar != NULL) {
+ ro_toolbar_add_buttons(toolbar, brower_toolbar_buttons,
+ option_toolbar_browser);
+ ro_toolbar_add_url(toolbar);
+ ro_toolbar_add_throbber(toolbar);
+ ro_toolbar_rebuild(toolbar);
toolbar_display = calloc(sizeof(struct toolbar_display), 1);
if (!toolbar_display) {
LOG(("No memory for calloc()"));
@@ -311,21 +318,23 @@ void ro_gui_options_theme_load(void)
/* update the toolbar */
item_height = 44 + 44 + 16;
if (link->next) item_height += 16;
- ro_gui_theme_process_toolbar(link->toolbar, parent_width);
- extent.y0 = nested_y - link->toolbar->height - item_height;
+ ro_toolbar_process(link->toolbar, parent_width, false);
+ extent.y0 = nested_y -
+ ro_toolbar_height(link->toolbar) -
+ item_height;
if (link->next) extent.y0 -= 16;
if (extent.y0 > min_extent) extent.y0 = min_extent;
xwimp_set_extent(theme_pane, &extent);
- ro_gui_set_icon_button_type(link->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL, wimp_BUTTON_NEVER);
/* create the descriptor icons and separator line */
new_icon.icon.extent.x0 = 8;
new_icon.icon.extent.x1 = parent_width - 8;
new_icon.icon.flags &= ~wimp_ICON_BORDER;
new_icon.icon.flags |= wimp_ICON_SPRITE;
- new_icon.icon.extent.y1 = nested_y - link->toolbar->height - 8;
- new_icon.icon.extent.y0 = nested_y - link->toolbar->height - 52;
+ new_icon.icon.extent.y1 = nested_y -
+ ro_toolbar_height(link->toolbar) - 8;
+ new_icon.icon.extent.y0 = nested_y -
+ ro_toolbar_height(link->toolbar) - 52;
new_icon.icon.data.indirected_text_and_sprite.text =
(char *)&link->descriptor->name;
new_icon.icon.data.indirected_text_and_sprite.size =
@@ -363,10 +372,11 @@ void ro_gui_options_theme_load(void)
}
/* nest the toolbar window */
- state.w = link->toolbar->toolbar_handle;
+ state.w = ro_toolbar_get_window(link->toolbar);
state.yscroll = 0;
state.visible.y1 = nested_y + base_extent;
- state.visible.y0 = state.visible.y1 - link->toolbar->height + 2;
+ state.visible.y0 = state.visible.y1 -
+ ro_toolbar_height(link->toolbar) + 2;
xwimp_open_window_nested(PTR_WIMP_OPEN(&state), theme_pane,
wimp_CHILD_LINKS_PARENT_WORK_AREA
<< wimp_CHILD_BS_EDGE_SHIFT |
@@ -374,7 +384,8 @@ void ro_gui_options_theme_load(void)
<< wimp_CHILD_TS_EDGE_SHIFT);
/* continue processing */
- nested_y -= link->toolbar->height + item_height;
+ nested_y -= ro_toolbar_height(link->toolbar) +
+ item_height;
link = link->next;
}
@@ -404,7 +415,7 @@ void ro_gui_options_theme_free(void)
if (next_toolbar)
xwimp_delete_icon(theme_pane,
toolbar->icon_number + 2);
- ro_gui_theme_destroy_toolbar(toolbar->toolbar);
+ ro_toolbar_destroy(toolbar->toolbar);
free(toolbar);
}
toolbars = NULL;
diff --git a/riscos/cookies.c b/riscos/cookies.c
index 5eb2191d2..76c7f4673 100644
--- a/riscos/cookies.c
+++ b/riscos/cookies.c
@@ -36,7 +36,7 @@
#include "riscos/dialog.h"
#include "riscos/menus.h"
#include "riscos/options.h"
-#include "riscos/theme.h"
+#include "riscos/toolbar.h"
#include "riscos/treeview.h"
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
@@ -45,6 +45,22 @@
#include "utils/url.h"
#include "utils/utils.h"
+static void ro_gui_cookies_toolbar_update_buttons(void);
+static void ro_gui_cookies_toolbar_save_buttons(char *config);
+static bool ro_gui_cookies_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer);
+static void ro_gui_cookies_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action);
+static bool ro_gui_cookies_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action);
+static void ro_gui_cookies_toolbar_click(button_bar_action action);
+
+struct ro_treeview_callbacks ro_cookies_treeview_callbacks = {
+ ro_gui_cookies_toolbar_click,
+ ro_gui_cookies_toolbar_update_buttons,
+ ro_gui_cookies_toolbar_save_buttons
+};
+
/* The RISC OS cookie window, toolbar and treeview data. */
static struct ro_cookies_window {
@@ -76,21 +92,30 @@ void ro_gui_cookies_postinitialise(void)
{
/* Create our toolbar. */
- cookies_window.toolbar = ro_gui_theme_create_toolbar(NULL,
- THEME_COOKIES_TOOLBAR);
- if (cookies_window.toolbar)
- ro_gui_theme_attach_toolbar(cookies_window.toolbar,
- cookies_window.window);
+ cookies_window.toolbar = ro_toolbar_create(NULL, cookies_window.window,
+ THEME_STYLE_COOKIES_TOOLBAR, TOOLBAR_FLAGS_NONE,
+ ro_treeview_get_toolbar_callbacks(), NULL,
+ "HelpCookiesToolbar");
+ if (cookies_window.toolbar != NULL) {
+ ro_toolbar_add_buttons(cookies_window.toolbar,
+ cookies_toolbar_buttons,
+ option_toolbar_cookies);
+ ro_toolbar_rebuild(cookies_window.toolbar);
+ }
/* Create the treeview with the window and toolbar. */
cookies_window.tv = ro_treeview_create(cookies_window.window,
- cookies_window.toolbar, cookies_get_tree_flags());
+ cookies_window.toolbar, &ro_cookies_treeview_callbacks,
+ cookies_get_tree_flags());
if (cookies_window.tv == NULL) {
LOG(("Failed to allocate treeview"));
return;
}
+ ro_toolbar_update_client_data(cookies_window.toolbar,
+ cookies_window.tv);
+
/* Initialise the cookies into the tree. */
cookies_initialise(ro_treeview_get_tree(cookies_window.tv),
@@ -123,14 +148,18 @@ void ro_gui_cookies_postinitialise(void)
};
cookies_window.menu = ro_gui_menu_define_menu(&cookies_definition);
- ro_gui_wimp_event_register_window_menu(cookies_window.window,
- cookies_window.menu, ro_gui_cookies_menu_prepare,
- ro_gui_cookies_menu_select, NULL,
- ro_gui_cookies_menu_warning, false);
+ ro_gui_wimp_event_register_menu(cookies_window.window,
+ cookies_window.menu, false, false);
+ ro_gui_wimp_event_register_menu_prepare(cookies_window.window,
+ ro_gui_cookies_menu_prepare);
+ ro_gui_wimp_event_register_menu_selection(cookies_window.window,
+ ro_gui_cookies_menu_select);
+ ro_gui_wimp_event_register_menu_warning(cookies_window.window,
+ ro_gui_cookies_menu_warning);
}
/**
- * \TODO - Open the cookies window.
+ * Open the cookies window.
*
*/
@@ -138,111 +167,128 @@ void ro_gui_cookies_open(void)
{
tree_set_redraw(ro_treeview_get_tree(cookies_window.tv), true);
+ ro_gui_cookies_toolbar_update_buttons();
+
if (!ro_gui_dialog_open_top(cookies_window.window,
cookies_window.toolbar, 600, 800)) {
ro_treeview_set_origin(cookies_window.tv, 0,
- -(ro_gui_theme_toolbar_height(
- cookies_window.toolbar)));
+ -(ro_toolbar_height(cookies_window.toolbar)));
}
}
/**
- * Handle Mouse Click events on the toolbar.
+ * Handle toolbar button clicks.
*
- * \param *pointer Pointer to the Mouse Click Event block.
- * \return Return true if click handled; else false.
+ * \param action The action to handle
*/
-bool ro_gui_cookies_toolbar_click(wimp_pointer *pointer)
+void ro_gui_cookies_toolbar_click(button_bar_action action)
{
- if (pointer->buttons == wimp_CLICK_MENU)
- return ro_gui_wimp_event_process_window_menu_click(pointer);
+ switch (action) {
+ case TOOLBAR_BUTTON_DELETE:
+ cookies_delete_selected();
+ break;
- if (cookies_window.toolbar->editor != NULL) {
- ro_gui_theme_toolbar_editor_click(cookies_window.toolbar,
- pointer);
- return true;
- }
+ case TOOLBAR_BUTTON_EXPAND:
+ cookies_expand_cookies();
+ break;
- switch (pointer->i) {
- case ICON_TOOLBAR_DELETE:
- if (pointer->buttons == wimp_CLICK_SELECT) {
- cookies_delete_selected();
- return true;
- }
+ case TOOLBAR_BUTTON_COLLAPSE:
+ cookies_collapse_cookies();
break;
- case ICON_TOOLBAR_EXPAND:
- if (pointer->buttons == wimp_CLICK_SELECT) {
- cookies_expand_cookies();
- return true;
- } else if (pointer->buttons == wimp_CLICK_ADJUST) {
- cookies_collapse_cookies();
- return true;
- }
+
+ case TOOLBAR_BUTTON_OPEN:
+ cookies_expand_domains();
break;
- case ICON_TOOLBAR_OPEN:
- if (pointer->buttons == wimp_CLICK_SELECT) {
- cookies_expand_domains();
- return true;
- } else if (pointer->buttons == wimp_CLICK_ADJUST) {
- cookies_collapse_domains();
- return true;
- }
+
+ case TOOLBAR_BUTTON_CLOSE:
+ cookies_collapse_domains();
+ break;
+
+ default:
break;
}
+}
- return false;
+
+/**
+ * Update the button state in the cookies toolbar.
+ */
+
+void ro_gui_cookies_toolbar_update_buttons(void)
+{
+ ro_toolbar_set_button_shaded_state(cookies_window.toolbar,
+ TOOLBAR_BUTTON_DELETE,
+ !ro_treeview_has_selection(cookies_window.tv));
}
+
+/**
+ * Save a new button arrangement in the cookies toolbar.
+ *
+ * \param *config The new button configuration string.
+ */
+
+void ro_gui_cookies_toolbar_save_buttons(char *config)
+{
+ if (option_toolbar_cookies != NULL)
+ free(option_toolbar_cookies);
+ option_toolbar_cookies = config;
+ ro_gui_save_options();
+}
+
+
/**
* Prepare the cookies menu for opening
*
- * \param window The window owning the menu.
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
* \param *menu The menu about to be opened.
+ * \param *pointer Pointer to the relevant wimp event block, or
+ * NULL for an Adjust click.
+ * \return true if the event was handled; else false.
*/
-void ro_gui_cookies_menu_prepare(wimp_w window, wimp_menu *menu)
+bool ro_gui_cookies_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer)
{
bool selection;
- if (menu != cookies_window.menu && menu != tree_toolbar_menu)
- return;
+ if (menu != cookies_window.menu)
+ return false;
- if (menu == cookies_window.menu) {
- selection = ro_treeview_has_selection(cookies_window.tv);
+ selection = ro_treeview_has_selection(cookies_window.tv);
- ro_gui_menu_set_entry_shaded(cookies_window.menu, TREE_SELECTION,
- !selection);
- ro_gui_menu_set_entry_shaded(cookies_window.menu, TREE_CLEAR_SELECTION,
- !selection);
- }
+ ro_gui_menu_set_entry_shaded(cookies_window.menu,
+ TREE_SELECTION, !selection);
+ ro_gui_menu_set_entry_shaded(cookies_window.menu,
+ TREE_CLEAR_SELECTION, !selection);
ro_gui_menu_set_entry_shaded(menu, TOOLBAR_BUTTONS,
- (cookies_window.toolbar == NULL ||
- cookies_window.toolbar->editor));
+ ro_toolbar_menu_option_shade(cookies_window.toolbar));
ro_gui_menu_set_entry_ticked(menu, TOOLBAR_BUTTONS,
- (cookies_window.toolbar != NULL &&
- (cookies_window.toolbar->display_buttons ||
- (cookies_window.toolbar->editor))));
+ ro_toolbar_menu_buttons_tick(cookies_window.toolbar));
ro_gui_menu_set_entry_shaded(menu, TOOLBAR_EDIT,
- cookies_window.toolbar == NULL);
+ ro_toolbar_menu_edit_shade(cookies_window.toolbar));
ro_gui_menu_set_entry_ticked(menu, TOOLBAR_EDIT,
- (cookies_window.toolbar != NULL &&
- cookies_window.toolbar->editor));
+ ro_toolbar_menu_edit_tick(cookies_window.toolbar));
+
+ return true;
}
/**
* Handle submenu warnings for the cookies menu
*
- * \param window The window owning the menu.
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
* \param *menu The menu to which the warning applies.
* \param *selection The wimp menu selection data.
* \param action The selected menu action.
*/
-void ro_gui_cookies_menu_warning(wimp_w window, wimp_menu *menu,
+void ro_gui_cookies_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
wimp_selection *selection, menu_action action)
{
/* Do nothing */
@@ -251,14 +297,15 @@ void ro_gui_cookies_menu_warning(wimp_w window, wimp_menu *menu,
/**
* Handle selections from the cookies menu
*
- * \param window The window owning the menu.
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
* \param *menu The menu from which the selection was made.
* \param *selection The wimp menu selection data.
* \param action The selected menu action.
* \return true if action accepted; else false.
*/
-bool ro_gui_cookies_menu_select(wimp_w window, wimp_menu *menu,
+bool ro_gui_cookies_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
wimp_selection *selection, menu_action action)
{
switch (action) {
@@ -290,12 +337,12 @@ bool ro_gui_cookies_menu_select(wimp_w window, wimp_menu *menu,
cookies_clear_selection();
return true;
case TOOLBAR_BUTTONS:
- cookies_window.toolbar->display_buttons =
- !cookies_window.toolbar->display_buttons;
- ro_gui_theme_refresh_toolbar(cookies_window.toolbar);
+ ro_toolbar_set_display_buttons(cookies_window.toolbar,
+ !ro_toolbar_get_display_buttons(
+ cookies_window.toolbar));
return true;
case TOOLBAR_EDIT:
- ro_gui_theme_toggle_edit(cookies_window.toolbar);
+ ro_toolbar_toggle_edit(cookies_window.toolbar);
return true;
default:
return false;
@@ -305,21 +352,6 @@ bool ro_gui_cookies_menu_select(wimp_w window, wimp_menu *menu,
}
/**
- * Update the theme details of the cookies window.
- *
- * \param full_update true to force a full theme change; false to
- * refresh the toolbar size.
- */
-
-void ro_gui_cookies_update_theme(bool full_update)
-{
- if (full_update)
- ro_treeview_update_theme(cookies_window.tv);
- else
- ro_treeview_update_toolbar(cookies_window.tv);
-}
-
-/**
* Check if a particular window handle is the cookies window
*
* \param window the window in question
diff --git a/riscos/cookies.h b/riscos/cookies.h
index 8f46147c4..e55ca0275 100644
--- a/riscos/cookies.h
+++ b/riscos/cookies.h
@@ -30,16 +30,8 @@ void ro_gui_cookies_preinitialise(void);
void ro_gui_cookies_postinitialise(void);
bool ro_gui_cookies_check_window(wimp_w window);
bool ro_gui_cookies_check_menu(wimp_menu *menu);
-bool ro_gui_cookies_toolbar_click(wimp_pointer *pointer);
-
-void ro_gui_cookies_menu_prepare(wimp_w window, wimp_menu *menu);
-bool ro_gui_cookies_menu_select(wimp_w window, wimp_menu *menu,
- wimp_selection *selection, menu_action action);
-void ro_gui_cookies_menu_warning(wimp_w window, wimp_menu *menu,
- wimp_selection *selection, menu_action action);
void ro_gui_cookies_open(void);
-void ro_gui_cookies_update_theme(bool full_update);
#endif
diff --git a/riscos/dialog.c b/riscos/dialog.c
index b4195a5b7..611b7efc2 100644
--- a/riscos/dialog.c
+++ b/riscos/dialog.c
@@ -44,7 +44,7 @@
#include "riscos/options.h"
#include "riscos/save.h"
#include "riscos/sslcert.h"
-#include "riscos/theme.h"
+#include "riscos/toolbar.h"
#include "riscos/url_complete.h"
#include "riscos/url_suggest.h"
#include "riscos/wimp.h"
@@ -86,6 +86,9 @@ static struct {
static bool ro_gui_dialog_openurl_apply(wimp_w w);
+static bool ro_gui_dialog_open_url_menu_prepare(wimp_w w, wimp_i i,
+ wimp_menu *menu, wimp_pointer *pointer);
+
static bool ro_gui_dialog_zoom_apply(wimp_w w);
/**
@@ -162,10 +165,12 @@ void ro_gui_dialog_init(void)
/* open URL */
dialog_openurl = ro_gui_dialog_create("open_url");
ro_gui_wimp_event_register_menu_gright(dialog_openurl, ICON_OPENURL_URL,
- ICON_OPENURL_MENU, url_suggest_menu);
+ ICON_OPENURL_MENU, ro_gui_url_suggest_menu);
ro_gui_wimp_event_register_cancel(dialog_openurl, ICON_OPENURL_CANCEL);
ro_gui_wimp_event_register_ok(dialog_openurl, ICON_OPENURL_OPEN,
ro_gui_dialog_openurl_apply);
+ ro_gui_wimp_event_register_menu_prepare(dialog_openurl,
+ ro_gui_dialog_open_url_menu_prepare);
ro_gui_wimp_event_set_help_prefix(dialog_openurl, "HelpOpenURL");
/* scale view */
@@ -426,8 +431,8 @@ bool ro_gui_dialog_open_top(wimp_w w, struct toolbar *toolbar,
open = state.flags & wimp_WINDOW_OPEN;
if (!open) {
/* cancel any editing */
- if ((toolbar) && (toolbar->editor))
- ro_gui_theme_toggle_edit(toolbar);
+ if (ro_toolbar_get_editing(toolbar))
+ ro_toolbar_toggle_edit(toolbar);
/* move to the centre */
ro_gui_screen_size(&screen_width, &screen_height);
@@ -443,7 +448,7 @@ bool ro_gui_dialog_open_top(wimp_w w, struct toolbar *toolbar,
state.xscroll = 0;
state.yscroll = 0;
if (toolbar)
- state.yscroll = ro_gui_theme_toolbar_height(toolbar);
+ state.yscroll = ro_toolbar_height(toolbar);
}
/* open the window at the top of the stack */
@@ -727,3 +732,28 @@ void ro_gui_dialog_prepare_open_url(void)
ICON_OPENURL_MENU, !ro_gui_url_suggest_prepare_menu());
ro_gui_wimp_event_memorise(dialog_openurl);
}
+
+
+/**
+ * Callback to prepare menus in the Open URL dialog. At present, this
+ * only has to handle the URL Suggestion pop-up.
+ *
+ * \param w The window handle owning the menu.
+ * \param i The icon handle owning the menu.
+ * \param *menu The menu to be prepared.
+ * \param *pointer The associated mouse click event block, or NULL
+ * on an Adjust-click re-opening.
+ * \return true if the event was handled; false if not.
+ */
+
+bool ro_gui_dialog_open_url_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer)
+{
+ if (menu != ro_gui_url_suggest_menu || i != ICON_OPENURL_MENU)
+ return false;
+
+ if (pointer != NULL)
+ return ro_gui_url_suggest_prepare_menu();
+
+ return true;
+}
diff --git a/riscos/dialog.h b/riscos/dialog.h
index 29c2e5024..5758ad366 100644
--- a/riscos/dialog.h
+++ b/riscos/dialog.h
@@ -22,7 +22,7 @@
#include <stdbool.h>
#include <stdlib.h>
#include "oslib/wimp.h"
-#include "riscos/theme.h"
+#include "riscos/toolbar.h"
#include "riscos/gui.h"
void ro_gui_dialog_init(void);
diff --git a/riscos/global_history.c b/riscos/global_history.c
index d46600005..28fd107ce 100644
--- a/riscos/global_history.c
+++ b/riscos/global_history.c
@@ -38,7 +38,7 @@
#include "riscos/menus.h"
#include "riscos/options.h"
#include "riscos/save.h"
-#include "riscos/theme.h"
+#include "riscos/toolbar.h"
#include "riscos/treeview.h"
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
@@ -47,6 +47,22 @@
#include "utils/url.h"
#include "utils/utils.h"
+static void ro_gui_global_history_toolbar_update_buttons(void);
+static void ro_gui_global_history_toolbar_save_buttons(char *config);
+static bool ro_gui_global_history_menu_prepare(wimp_w w, wimp_i i,
+ wimp_menu *menu, wimp_pointer *pointer);
+static void ro_gui_global_history_menu_warning(wimp_w w, wimp_i i,
+ wimp_menu *menu, wimp_selection *selection, menu_action action);
+static bool ro_gui_global_history_menu_select(wimp_w w, wimp_i i,
+ wimp_menu *menu, wimp_selection *selection, menu_action action);
+static void ro_gui_global_history_toolbar_click(button_bar_action action);
+
+struct ro_treeview_callbacks ro_global_history_treeview_callbacks = {
+ ro_gui_global_history_toolbar_click,
+ ro_gui_global_history_toolbar_update_buttons,
+ ro_gui_global_history_toolbar_save_buttons
+};
+
/* The RISC OS global history window, toolbar and treeview data */
static struct ro_global_history_window {
@@ -76,26 +92,35 @@ void ro_gui_global_history_preinitialise(void)
void ro_gui_global_history_postinitialise(void)
{
-
/* Create our toolbar. */
- global_history_window.toolbar = ro_gui_theme_create_toolbar(NULL,
- THEME_HISTORY_TOOLBAR);
- if (global_history_window.toolbar)
- ro_gui_theme_attach_toolbar(global_history_window.toolbar,
- global_history_window.window);
+ global_history_window.toolbar = ro_toolbar_create(NULL,
+ global_history_window.window,
+ THEME_STYLE_GLOBAL_HISTORY_TOOLBAR, TOOLBAR_FLAGS_NONE,
+ ro_treeview_get_toolbar_callbacks(), NULL,
+ "HelpGHistoryToolbar");
+ if (global_history_window.toolbar != NULL) {
+ ro_toolbar_add_buttons(global_history_window.toolbar,
+ global_history_toolbar_buttons,
+ option_toolbar_history);
+ ro_toolbar_rebuild(global_history_window.toolbar);
+ }
/* Create the treeview with the window and toolbar. */
global_history_window.tv =
ro_treeview_create(global_history_window.window,
global_history_window.toolbar,
+ &ro_global_history_treeview_callbacks,
history_global_get_tree_flags());
if (global_history_window.tv == NULL) {
LOG(("Failed to allocate treeview"));
return;
}
+ ro_toolbar_update_client_data(global_history_window.toolbar,
+ global_history_window.tv);
+
/* Initialise the global history into the tree. */
history_global_initialise(
@@ -130,11 +155,14 @@ void ro_gui_global_history_postinitialise(void)
global_history_window.menu = ro_gui_menu_define_menu(
&global_history_definition);
- ro_gui_wimp_event_register_window_menu(global_history_window.window,
- global_history_window.menu,
- ro_gui_global_history_menu_prepare,
- ro_gui_global_history_menu_select, NULL,
- ro_gui_global_history_menu_warning, false);
+ ro_gui_wimp_event_register_menu(global_history_window.window,
+ global_history_window.menu, false, false);
+ ro_gui_wimp_event_register_menu_prepare(global_history_window.window,
+ ro_gui_global_history_menu_prepare);
+ ro_gui_wimp_event_register_menu_selection(global_history_window.window,
+ ro_gui_global_history_menu_select);
+ ro_gui_wimp_event_register_menu_warning(global_history_window.window,
+ ro_gui_global_history_menu_warning);
}
/**
@@ -145,120 +173,143 @@ void ro_gui_global_history_open(void)
{
tree_set_redraw(ro_treeview_get_tree(global_history_window.tv), true);
+ ro_gui_global_history_toolbar_update_buttons();
+
if (!ro_gui_dialog_open_top(global_history_window.window,
global_history_window.toolbar, 600, 800)) {
ro_treeview_set_origin(global_history_window.tv, 0,
- -(ro_gui_theme_toolbar_height(
+ -(ro_toolbar_height(
global_history_window.toolbar)));
}
}
/**
- * Handle Mouse Click events on the toolbar.
+ * Handle toolbar button clicks.
*
- * \param *pointer Pointer to the Mouse Click Event block.
- * \return Return true if click handled; else false.
+ * \param action The action to handle
*/
-bool ro_gui_global_history_toolbar_click(wimp_pointer *pointer)
+void ro_gui_global_history_toolbar_click(button_bar_action action)
{
- if (pointer->buttons == wimp_CLICK_MENU)
- return ro_gui_wimp_event_process_window_menu_click(pointer);
+ switch (action) {
+ case TOOLBAR_BUTTON_DELETE:
+ history_global_delete_selected();
+ break;
- if (global_history_window.toolbar->editor != NULL) {
- ro_gui_theme_toolbar_editor_click(global_history_window.toolbar,
- pointer);
- return true;
- }
+ case TOOLBAR_BUTTON_EXPAND:
+ history_global_expand_addresses();
+ break;
- switch (pointer->i) {
- case ICON_TOOLBAR_DELETE:
- if (pointer->buttons == wimp_CLICK_SELECT) {
- history_global_delete_selected();
- return true;
- }
+ case TOOLBAR_BUTTON_COLLAPSE:
+ history_global_collapse_addresses();
break;
- case ICON_TOOLBAR_EXPAND:
- if (pointer->buttons == wimp_CLICK_SELECT) {
- history_global_expand_addresses();
- return true;
- } else if (pointer->buttons == wimp_CLICK_ADJUST) {
- history_global_collapse_addresses();
- return true;
- }
+
+ case TOOLBAR_BUTTON_OPEN:
+ history_global_expand_directories();
break;
- case ICON_TOOLBAR_OPEN:
- if (pointer->buttons == wimp_CLICK_SELECT) {
- history_global_expand_directories();
- return true;
- } else if (pointer->buttons == wimp_CLICK_ADJUST) {
- history_global_collapse_directories();
- return true;
- }
+
+ case TOOLBAR_BUTTON_CLOSE:
+ history_global_collapse_directories();
break;
- case ICON_TOOLBAR_LAUNCH:
- if (pointer->buttons == wimp_CLICK_SELECT) {
- history_global_launch_selected();
- return true;
- }
+
+ case TOOLBAR_BUTTON_LAUNCH:
+ history_global_launch_selected();
+ break;
+
+ default:
break;
}
+}
- return true;
+
+/**
+ * Update the button state in the global history toolbar.
+ */
+
+void ro_gui_global_history_toolbar_update_buttons(void)
+{
+ ro_toolbar_set_button_shaded_state(global_history_window.toolbar,
+ TOOLBAR_BUTTON_DELETE,
+ !ro_treeview_has_selection(global_history_window.tv));
+
+ ro_toolbar_set_button_shaded_state(global_history_window.toolbar,
+ TOOLBAR_BUTTON_LAUNCH,
+ !ro_treeview_has_selection(global_history_window.tv));
+}
+
+
+/**
+ * Save a new button arrangement in the global history toolbar.
+ *
+ * \param *config The new button configuration string.
+ */
+
+void ro_gui_global_history_toolbar_save_buttons(char *config)
+{
+ if (option_toolbar_history != NULL)
+ free(option_toolbar_history);
+ option_toolbar_history = config;
+ ro_gui_save_options();
}
/**
* Prepare the global history menu for opening
*
- * \param window The window owning the menu.
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
* \param *menu The menu about to be opened.
+ * \param *pointer Pointer to the relevant wimp event block, or
+ * NULL for an Adjust click.
+ * \return true if the event was handled; else false.
*/
-void ro_gui_global_history_menu_prepare(wimp_w window, wimp_menu *menu)
+bool ro_gui_global_history_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer)
{
bool selection;
- if (menu != global_history_window.menu && menu != tree_toolbar_menu)
- return;
+ if (menu != global_history_window.menu)
+ return false;
- if (menu == global_history_window.menu) {
- selection = ro_treeview_has_selection(global_history_window.tv);
+ selection = ro_treeview_has_selection(global_history_window.tv);
- ro_gui_menu_set_entry_shaded(global_history_window.menu,
- TREE_SELECTION, !selection);
- ro_gui_menu_set_entry_shaded(global_history_window.menu,
- TREE_CLEAR_SELECTION, !selection);
+ ro_gui_menu_set_entry_shaded(global_history_window.menu,
+ TREE_SELECTION, !selection);
+ ro_gui_menu_set_entry_shaded(global_history_window.menu,
+ TREE_CLEAR_SELECTION, !selection);
- ro_gui_save_prepare(GUI_SAVE_HISTORY_EXPORT_HTML,
- NULL, NULL, NULL, NULL);
- }
+ ro_gui_save_prepare(GUI_SAVE_HISTORY_EXPORT_HTML,
+ NULL, NULL, NULL, NULL);
ro_gui_menu_set_entry_shaded(menu, TOOLBAR_BUTTONS,
- (global_history_window.toolbar == NULL ||
- global_history_window.toolbar->editor));
+ ro_toolbar_menu_option_shade(
+ global_history_window.toolbar));
ro_gui_menu_set_entry_ticked(menu, TOOLBAR_BUTTONS,
- (global_history_window.toolbar != NULL &&
- (global_history_window.toolbar->display_buttons ||
- (global_history_window.toolbar->editor))));
+ ro_toolbar_menu_buttons_tick(
+ global_history_window.toolbar));
ro_gui_menu_set_entry_shaded(menu, TOOLBAR_EDIT,
- global_history_window.toolbar == NULL);
+ ro_toolbar_menu_edit_shade(
+ global_history_window.toolbar));
ro_gui_menu_set_entry_ticked(menu, TOOLBAR_EDIT,
- (global_history_window.toolbar != NULL &&
- global_history_window.toolbar->editor));
+ ro_toolbar_menu_edit_tick(
+ global_history_window.toolbar));
+
+ return true;
}
/**
* Handle submenu warnings for the global_hostory menu
*
- * \param window The window owning the menu.
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
* \param *menu The menu to which the warning applies.
* \param *selection The wimp menu selection data.
* \param action The selected menu action.
*/
-void ro_gui_global_history_menu_warning(wimp_w window, wimp_menu *menu,
+void ro_gui_global_history_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
wimp_selection *selection, menu_action action)
{
/* Do nothing */
@@ -267,19 +318,20 @@ void ro_gui_global_history_menu_warning(wimp_w window, wimp_menu *menu,
/**
* Handle selections from the global history menu
*
- * \param window The window owning the menu.
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
* \param *menu The menu from which the selection was made.
* \param *selection The wimp menu selection data.
* \param action The selected menu action.
* \return true if action accepted; else false.
*/
-bool ro_gui_global_history_menu_select(wimp_w window, wimp_menu *menu,
+bool ro_gui_global_history_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
wimp_selection *selection, menu_action action)
{
switch (action) {
case HISTORY_EXPORT:
- ro_gui_dialog_open_persistent(window, dialog_saveas, true);
+ ro_gui_dialog_open_persistent(w, dialog_saveas, true);
return true;
case TREE_EXPAND_ALL:
history_global_expand_all();
@@ -312,12 +364,12 @@ bool ro_gui_global_history_menu_select(wimp_w window, wimp_menu *menu,
history_global_clear_selection();
return true;
case TOOLBAR_BUTTONS:
- global_history_window.toolbar->display_buttons =
- !global_history_window.toolbar->display_buttons;
- ro_gui_theme_refresh_toolbar(global_history_window.toolbar);
+ ro_toolbar_set_display_buttons(global_history_window.toolbar,
+ !ro_toolbar_get_display_buttons(
+ global_history_window.toolbar));
return true;
case TOOLBAR_EDIT:
- ro_gui_theme_toggle_edit(global_history_window.toolbar);
+ ro_toolbar_toggle_edit(global_history_window.toolbar);
return true;
default:
return false;
@@ -327,21 +379,6 @@ bool ro_gui_global_history_menu_select(wimp_w window, wimp_menu *menu,
}
/**
- * Update the theme details of the global history window.
- *
- * \param full_update true to force a full theme change; false to
- * refresh the toolbar size.
- */
-
-void ro_gui_global_history_update_theme(bool full_update)
-{
- if (full_update)
- ro_treeview_update_theme(global_history_window.tv);
- else
- ro_treeview_update_toolbar(global_history_window.tv);
-}
-
-/**
* Check if a particular window handle is the global history window
*
* \param window the window in question
diff --git a/riscos/global_history.h b/riscos/global_history.h
index ff06d574b..99ea8c609 100644
--- a/riscos/global_history.h
+++ b/riscos/global_history.h
@@ -30,16 +30,8 @@ void ro_gui_global_history_preinitialise(void);
void ro_gui_global_history_postinitialise(void);
void ro_gui_global_history_open(void);
void ro_gui_global_history_save(void);
-void ro_gui_global_history_update_theme(bool full_update);
bool ro_gui_global_history_check_window(wimp_w window);
bool ro_gui_global_history_check_menu(wimp_menu *menu);
-bool ro_gui_global_history_toolbar_click(wimp_pointer *pointer);
-
-void ro_gui_global_history_menu_prepare(wimp_w window, wimp_menu *menu);
-bool ro_gui_global_history_menu_select(wimp_w window, wimp_menu *menu,
- wimp_selection *selection, menu_action action);
-void ro_gui_global_history_menu_warning(wimp_w window, wimp_menu *menu,
- wimp_selection *selection, menu_action action);
#endif
diff --git a/riscos/gui.c b/riscos/gui.c
index 4d8b5a17c..8ebbc4fe6 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -74,6 +74,7 @@
#include "riscos/gui.h"
#include "riscos/help.h"
#include "riscos/hotlist.h"
+#include "riscos/iconbar.h"
#include "riscos/menus.h"
#include "riscos/message.h"
#include "riscos/options.h"
@@ -86,6 +87,7 @@
#include "riscos/sslcert.h"
#include "riscos/textselection.h"
#include "riscos/theme.h"
+#include "riscos/toolbar.h"
#include "riscos/treeview.h"
#include "riscos/uri.h"
#include "riscos/url_protocol.h"
@@ -93,6 +95,7 @@
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
#include "riscos/wimputils.h"
+#include "riscos/window.h"
#include "utils/filename.h"
#include "utils/log.h"
#include "utils/messages.h"
@@ -249,7 +252,6 @@ static struct
static void ro_gui_create_dirs(void);
static void ro_gui_create_dir(char *path);
static void ro_gui_choose_language(void);
-static void ro_gui_icon_bar_create(void);
static void ro_gui_signal(int sig);
static void ro_gui_cleanup(void);
static void ro_gui_handle_event(wimp_event_no event, wimp_block *block);
@@ -257,7 +259,6 @@ static void ro_gui_null_reason_code(void);
static void ro_gui_close_window_request(wimp_close *close);
static void ro_gui_pointer_leaving_window(wimp_leaving *leaving);
static void ro_gui_pointer_entering_window(wimp_entering *entering);
-static bool ro_gui_icon_bar_click(wimp_pointer *pointer);
static void ro_gui_check_resolvers(void);
static void ro_gui_drag_end(wimp_dragged *drag);
static void ro_gui_keypress(wimp_key *key);
@@ -349,7 +350,7 @@ static void gui_init(int argc, char** argv)
option_theme_path = strdup("NetSurf:Themes");
if (!option_theme_save)
option_theme_save = strdup(CHOICES_PREFIX "Themes");
-
+
tree_set_icon_dir(strdup("NetSurf:Resources.Icons"));
if (!option_theme || ! option_toolbar_browser ||
@@ -479,12 +480,16 @@ static void gui_init(int argc, char** argv)
ro_gui_query_init();
/* Initialise the history subsystem */
ro_gui_history_init();
+ /* Initialise toolbars */
+ ro_toolbar_init();
+ /* Initialise browser windows */
+ ro_gui_window_initialise();
/* Done with the templates file */
wimp_close_template();
- /* Create Iconbar icon */
- ro_gui_icon_bar_create();
+ /* Create Iconbar icon and menus */
+ ro_gui_iconbar_initialise();
/* Finally, check Inet$Resolvers for sanity */
ro_gui_check_resolvers();
@@ -621,31 +626,6 @@ const char *ro_gui_default_language(void)
/**
- * Create an iconbar icon.
- */
-
-void ro_gui_icon_bar_create(void)
-{
- os_error *error;
-
- wimp_icon_create icon = {
- wimp_ICON_BAR_RIGHT,
- { { 0, 0, 68, 68 },
- wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED |
- (wimp_BUTTON_CLICK << wimp_ICON_BUTTON_TYPE_SHIFT),
- { "!netsurf" } } };
- error = xwimp_create_icon(&icon, 0);
- if (error) {
- LOG(("xwimp_create_icon: 0x%x: %s",
- error->errnum, error->errmess));
- die(error->errmess);
- }
- ro_gui_wimp_event_register_mouse_click(wimp_ICON_BAR,
- ro_gui_icon_bar_click);
-}
-
-
-/**
* Warn the user if Inet$Resolvers is not set.
*/
@@ -1234,43 +1214,6 @@ void ro_gui_pointer_entering_window(wimp_entering *entering)
/**
- * Handle Mouse_Click events on the iconbar icon.
- */
-
-bool ro_gui_icon_bar_click(wimp_pointer *pointer)
-{
- char url[80];
- int key_down = 0;
-
- if (pointer->buttons == wimp_CLICK_MENU) {
- ro_gui_menu_create(iconbar_menu, pointer->pos.x,
- 96 + iconbar_menu_height, wimp_ICON_BAR,
- true);
-
- } else if (pointer->buttons == wimp_CLICK_SELECT) {
- if (option_homepage_url && option_homepage_url[0]) {
- browser_window_create(option_homepage_url, NULL, 0,
- true, false);
- } else {
- snprintf(url, sizeof url,
- "file:///<NetSurf$Dir>/Docs/welcome/index_%s",
- option_language);
- browser_window_create(url, NULL, 0, true, false);
- }
-
- } else if (pointer->buttons == wimp_CLICK_ADJUST) {
- xosbyte1(osbyte_SCAN_KEYBOARD, 0 ^ 0x80, 0, &key_down);
- if (key_down == 0)
- ro_gui_menu_handle_action(pointer->w, HOTLIST_SHOW,
- false);
- else
- ro_gui_debugwin_open();
- }
- return true;
-}
-
-
-/**
* Handle User_Drag_Box events.
*/
@@ -1302,8 +1245,8 @@ void ro_gui_drag_end(wimp_dragged *drag)
ro_treeview_drag_end(drag);
break;
- case GUI_DRAG_TOOLBAR_CONFIG:
- ro_gui_theme_toolbar_editor_drag_end(drag);
+ case GUI_DRAG_BUTTONBAR:
+ ro_gui_button_bar_drag_end(drag);
break;
case GUI_DRAG_FRAME:
@@ -1376,7 +1319,7 @@ void ro_gui_user_message(wimp_event_no event, wimp_message *message)
break;
case message_MENUS_DELETED:
- ro_gui_menu_closed(true);
+ ro_gui_menu_closed();
break;
case message_CLAIM_ENTITY:
diff --git a/riscos/gui.h b/riscos/gui.h
index 6bc1991f0..d0e842849 100644
--- a/riscos/gui.h
+++ b/riscos/gui.h
@@ -67,7 +67,7 @@ extern bool print_active, print_text_black;
typedef enum { GUI_DRAG_NONE, GUI_DRAG_SELECTION, GUI_DRAG_DOWNLOAD_SAVE,
GUI_DRAG_SAVE, GUI_DRAG_SCROLL, GUI_DRAG_STATUS_RESIZE,
- GUI_DRAG_TREEVIEW, GUI_DRAG_TOOLBAR_CONFIG,
+ GUI_DRAG_TREEVIEW, GUI_DRAG_BUTTONBAR,
GUI_DRAG_FRAME } gui_drag_type;
extern gui_drag_type gui_current_drag_type;
@@ -94,9 +94,6 @@ struct gui_window {
char title[256]; /**< Buffer for window title. */
- int throbber; /**< Current frame of throbber animation. */
- int throbtime; /**< Time of last throbber frame. */
-
int iconise_icon; /**< ID number of icon when window is iconised */
char validation[12]; /**< Validation string for colours */
@@ -136,26 +133,28 @@ bool ro_gui_download_prequit(void);
void ro_gui_401login_init(void);
/* in window.c */
+void ro_gui_scroll_request(wimp_scroll *scroll);
+bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message);
+void ro_gui_window_mouse_at(struct gui_window *g, wimp_pointer *pointer);
+void ro_gui_window_iconise(struct gui_window *g,
+ wimp_full_message_window_info *wi);
+void ro_gui_window_scroll_end(struct gui_window *g, wimp_dragged *drag);
+void ro_gui_window_frame_resize_end(struct gui_window *g, wimp_dragged *drag);
+bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message);
+void ro_gui_window_redraw_all(void);
+void ro_gui_window_update_boxes(void);
+void ro_gui_window_process_reformats(void);
void ro_gui_window_quit(void);
/* void ro_gui_window_close_all(void); */
#define ro_gui_window_close_all ro_gui_window_quit /* no need for a separate fn */
-void ro_gui_window_update_theme(void);
-void ro_gui_window_mouse_at(struct gui_window *g, wimp_pointer *pointer);
-bool ro_gui_toolbar_click(wimp_pointer *pointer);
void ro_gui_throb(void);
+void ro_gui_window_default_options(struct browser_window *bw);
struct gui_window *ro_gui_window_lookup(wimp_w window);
struct gui_window *ro_gui_toolbar_lookup(wimp_w window);
-void ro_gui_scroll_request(wimp_scroll *scroll);
bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y,
os_coord *pos);
bool ro_gui_window_to_screen_pos(struct gui_window *g, int x, int y,
os_coord *pos);
-bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message);
-bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message);
-void ro_gui_window_process_reformats(void);
-void ro_gui_window_default_options(struct browser_window *bw);
-void ro_gui_window_redraw_all(void);
-void ro_gui_window_prepare_navigate_all(void);
browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons,
wimp_icon_flags type);
browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons,
@@ -163,12 +162,6 @@ browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons,
bool ro_gui_shift_pressed(void);
bool ro_gui_ctrl_pressed(void);
bool ro_gui_alt_pressed(void);
-void ro_gui_window_scroll_end(struct gui_window *g, wimp_dragged *drag);
-void ro_gui_window_frame_resize_end(struct gui_window *g, wimp_dragged *drag);
-void ro_gui_window_iconise(struct gui_window *g,
- wimp_full_message_window_info *wi);
-bool ro_gui_window_navigate_up(struct gui_window *g, const char *url);
-void ro_gui_window_update_boxes(void);
/* in history.c */
void ro_gui_history_init(void);
@@ -192,7 +185,6 @@ void ro_gui_debugwin_open(void);
/* in search.c */
void ro_gui_search_init(void);
void ro_gui_search_prepare(struct browser_window *g);
-bool ro_gui_search_prepare_menu(void);
/* in print.c */
void ro_gui_print_init(void);
diff --git a/riscos/gui/button_bar.c b/riscos/gui/button_bar.c
new file mode 100644
index 000000000..00e357457
--- /dev/null
+++ b/riscos/gui/button_bar.c
@@ -0,0 +1,1231 @@
+/*
+ * Copyright 2004, 2005 Richard Wilson <info@tinct.net>
+ * Copyright 2011 Stephen Fryatt <stevef@netsurf-browser.org>
+ *
+ * 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
+ * Button bars (implementation).
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include "oslib/dragasprite.h"
+#include "oslib/os.h"
+#include "oslib/osspriteop.h"
+#include "oslib/wimp.h"
+#include "oslib/wimpspriteop.h"
+#include "riscos/gui/button_bar.h"
+#include "riscos/gui.h"
+#include "riscos/theme.h"
+#include "riscos/wimp.h"
+#include "utils/log.h"
+#include "utils/utils.h"
+
+#define BUTTONBAR_SPRITE_NAME_LENGTH 12
+#define BUTTONBAR_VALIDATION_LENGTH 40
+
+struct button_bar_button {
+ wimp_i icon;
+ bool shaded;
+ bool separator;
+
+ button_bar_action select_action;
+ button_bar_action adjust_action;
+
+ int x_pos, y_pos;
+ int x_size, y_size;
+
+ char sprite[BUTTONBAR_SPRITE_NAME_LENGTH];
+ char validation[BUTTONBAR_VALIDATION_LENGTH];
+ char opt_key;
+ const char *help_suffix;
+
+ struct button_bar_button *bar_next;
+ struct button_bar_button *next;
+};
+
+
+struct button_bar {
+ /** The applied theme (or NULL to use the default) */
+ struct theme_descriptor *theme;
+
+ /** The widget dimensions. */
+ int x_min, y_min;
+ int separator_width;
+ int vertical_offset;
+
+ bool separators;
+
+ /** The window details and bar position. */
+ wimp_w window;
+ os_box extent;
+ osspriteop_area *sprites;
+ int background;
+
+ bool hidden;
+
+ bool edit;
+ struct button_bar *edit_target;
+ struct button_bar *edit_source;
+ void (*edit_refresh)(void *);
+ void *edit_client_data;
+
+ /** The list of all the defined buttons. */
+
+ struct button_bar_button *buttons;
+
+ /** The list of the buttons in the current bar. */
+
+ struct button_bar_button *bar;
+};
+
+static char null_text_string[] = "";
+static char separator_name[] = "separator";
+
+static struct button_bar *drag_start = NULL;
+static char drag_opt = '\0';
+static bool drag_separator = false;
+
+/*
+ * Private function prototypes.
+ */
+
+static bool ro_gui_button_bar_place_buttons(struct button_bar *button_bar);
+static bool ro_gui_button_bar_icon_update(struct button_bar *button_bar);
+static bool ro_gui_button_bar_icon_resize(struct button_bar *button_bar);
+static void ro_gui_button_bar_sync_editors(struct button_bar *target,
+ struct button_bar *source);
+static struct button_bar_button *ro_gui_button_bar_find_icon(
+ struct button_bar *button_bar, wimp_i icon);
+static struct button_bar_button *ro_gui_button_bar_find_opt_key(
+ struct button_bar *button_bar, char opt_key);
+static struct button_bar_button *ro_gui_button_bar_find_action(
+ struct button_bar *button_bar, button_bar_action action);
+static struct button_bar_button *ro_gui_button_bar_find_coords(
+ struct button_bar *button_bar, os_coord pos,
+ bool *separator, bool *right);
+
+/* This is an exported interface documented in button_bar.h */
+
+struct button_bar *ro_gui_button_bar_create(struct theme_descriptor *theme,
+ const struct button_bar_buttons buttons[])
+{
+ struct button_bar *button_bar;
+ struct button_bar_button *icon, *new_icon;
+ bool failed;
+ int def;
+
+ /* Allocate memory. */
+
+ button_bar = malloc(sizeof(struct button_bar));
+ if (button_bar == NULL) {
+ LOG(("No memory for malloc()"));
+ return NULL;
+ }
+
+ /* Set up default parameters. */
+
+ button_bar->theme = theme;
+ button_bar->sprites = ro_gui_theme_get_sprites(theme);
+ button_bar->background = wimp_COLOUR_VERY_LIGHT_GREY;
+
+ button_bar->x_min = -1;
+ button_bar->y_min = -1;
+ button_bar->separator_width = 0;
+ button_bar->vertical_offset = 0;
+
+ button_bar->separators = false;
+
+ button_bar->window = NULL;
+
+ button_bar->hidden = false;
+
+ button_bar->edit = false;
+ button_bar->edit_target = NULL;
+ button_bar->edit_source = NULL;
+ button_bar->edit_refresh = NULL;
+ button_bar->edit_client_data = NULL;
+
+ button_bar->buttons = NULL;
+
+ /* Process the button icon definitions */
+
+ icon = NULL;
+ failed = false;
+
+ for (def = 0; buttons[def].icon != NULL; def++) {
+ new_icon = malloc(sizeof(struct button_bar_button));
+ if (new_icon == NULL) {
+ failed = true;
+ break;
+ }
+
+ if (icon == NULL) {
+ button_bar->buttons = new_icon;
+ button_bar->bar = new_icon;
+ } else {
+ icon->next = new_icon;
+ icon->bar_next = new_icon;
+ }
+ icon = new_icon;
+ icon->next = NULL;
+ icon->bar_next = NULL;
+
+ strncpy(icon->sprite, buttons[def].icon,
+ BUTTONBAR_SPRITE_NAME_LENGTH);
+ snprintf(icon->validation, BUTTONBAR_VALIDATION_LENGTH,
+ "R5;S%s,p%s", icon->sprite, icon->sprite);
+
+ icon->icon = -1;
+ icon->shaded = false;
+ icon->separator = false;
+
+ icon->select_action = buttons[def].select;
+ icon->adjust_action = buttons[def].adjust;
+ icon->opt_key = buttons[def].opt_key;
+ icon->help_suffix = buttons[def].help;
+ }
+
+ /* Add a separator after the last entry. This will be lost if the
+ * buttons are subsequently set, but is used for the edit source bar.
+ */
+
+ if (icon != NULL)
+ icon->separator = true;
+
+ return button_bar;
+}
+
+
+/* This is an exported interface documented in button_bar.h */
+
+bool ro_gui_button_bar_link_editor(struct button_bar *target,
+ struct button_bar *source, void (* refresh)(void *),
+ void *client_data)
+{
+ if (target == NULL || source == NULL ||
+ target->edit_target != NULL ||
+ target->edit_source != NULL ||
+ source->edit_target != NULL ||
+ source->edit_source != NULL)
+ return false;
+
+ target->edit_source = source;
+ source->edit_target = target;
+
+ /* Store the callback data in the editor bar. */
+
+ source->edit_refresh = refresh;
+ source->edit_client_data = client_data;
+
+ return true;
+}
+
+
+/* This is an exported interface documented in button_bar.h */
+
+bool ro_gui_button_bar_rebuild(struct button_bar *button_bar,
+ struct theme_descriptor *theme, theme_style style,
+ wimp_w window, bool edit)
+{
+ struct button_bar_button *button;
+ os_error *error;
+ int height;
+
+
+ if (button_bar == NULL)
+ return false;
+
+ button_bar->theme = theme;
+ button_bar->window = window;
+ button_bar->sprites = ro_gui_theme_get_sprites(theme);
+ button_bar->background = ro_gui_theme_get_style_element(theme, style,
+ THEME_ELEMENT_BACKGROUND);
+
+ button_bar->edit = edit;
+
+ height = 0;
+ button_bar->separator_width = 16;
+ ro_gui_wimp_get_sprite_dimensions(button_bar->sprites, separator_name,
+ &button_bar->separator_width, &height);
+
+ /* If the separator height is 0, then either the sprite really is
+ * zero pixels high or the default was used as no sprite was found.
+ * Either way, we don't have a separator.
+ */
+
+ button_bar->separators = (height == 0) ? false : true;
+
+ button = button_bar->buttons;
+ error = NULL;
+
+ while (button != NULL) {
+ button->x_size = 0;
+ button->y_size = 0;
+ button->icon = -1;
+
+ ro_gui_wimp_get_sprite_dimensions(button_bar->sprites,
+ button->sprite,
+ &button->x_size, &button->y_size);
+
+ button = button->next;
+ }
+
+ if (!ro_gui_button_bar_place_buttons(button_bar))
+ return false;
+
+ if (button_bar->edit && button_bar->edit_target != NULL)
+ ro_gui_button_bar_sync_editors(button_bar->edit_target,
+ button_bar);
+
+ return ro_gui_button_bar_icon_update(button_bar);
+}
+
+
+/* This is an exported interface documented in button_bar.h */
+
+bool ro_gui_button_bar_arrange_buttons(struct button_bar *button_bar,
+ char order[])
+{
+ struct button_bar_button *button, *new;
+ int i;
+
+ if (button_bar == NULL || order == NULL)
+ return false;
+
+ /* Delete any existing button arrangement. */
+
+ button_bar->bar = NULL;
+
+ for (button = button_bar->buttons; button != NULL;
+ button = button->next) {
+ button->bar_next = NULL;
+ button->separator = false;
+ }
+
+ /* Parse the config string and link up the new buttons. */
+
+ button = NULL;
+
+ for (i = 0; order[i] != '\0'; i++) {
+ if (order[i] != '|') {
+ new = ro_gui_button_bar_find_opt_key(button_bar,
+ order[i]);
+
+ if (new != NULL) {
+ if (button == NULL)
+ button_bar->bar = new;
+ else
+ button->bar_next = new;
+
+ button = new;
+ }
+ } else {
+ if (button != NULL)
+ button->separator = true;
+ }
+ }
+
+ if (!ro_gui_button_bar_place_buttons(button_bar))
+ return false;
+
+ return ro_gui_button_bar_place_buttons(button_bar);
+}
+
+/**
+ * Place the buttons on a button bar, taking into account the button arrangement
+ * and the current theme, and update the bar extent details.
+ *
+ * \param *button_bar The button bar to update.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_button_bar_place_buttons(struct button_bar *button_bar)
+{
+ struct button_bar_button *button;
+ int x_pos, y_pos, height;
+
+ if (button_bar == NULL)
+ return false;
+
+ button = button_bar->bar;
+ x_pos = 0;
+ y_pos = 0;
+ height = 0;
+
+ while (button != NULL) {
+ button->x_pos = x_pos;
+ button->y_pos = y_pos;
+
+ x_pos += button->x_size;
+ if (button->separator)
+ x_pos += button_bar->separator_width;
+
+ if (button->y_size > height)
+ height = button->y_size;
+
+ button = button->bar_next;
+ }
+
+ button_bar->x_min = x_pos;
+ button_bar->y_min = height;
+
+ return true;
+}
+
+
+/* This is an exported interface documented in button_bar.h */
+
+void ro_gui_button_bar_destroy(struct button_bar *button_bar)
+{
+ struct button_bar_button *button;
+
+ if (button_bar == NULL)
+ return;
+
+ /* Free the button definitions. */
+
+ while (button_bar->buttons != NULL) {
+ button = button_bar->buttons;
+ button_bar->buttons = button->next;
+ free(button);
+ }
+
+ free(button_bar);
+}
+
+
+/* This is an exported interface documented in button_bar.h */
+
+bool ro_gui_button_bar_get_dims(struct button_bar *button_bar,
+ int *width, int *height)
+{
+ if (button_bar == NULL)
+ return false;
+
+ if (button_bar->x_min != -1 && button_bar->y_min != -1) {
+ if (width != NULL)
+ *width = button_bar->x_min;
+ if (height != NULL)
+ *height = button_bar->y_min;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+/* This is an exported interface documented in button_bar.h */
+
+bool ro_gui_button_bar_set_extent(struct button_bar *button_bar,
+ int x0, int y0, int x1, int y1)
+{
+ if (button_bar == NULL)
+ return false;
+
+ if ((x1 - x0) < button_bar->x_min || (y1 - y0) < button_bar->y_min)
+ return false;
+
+ if (button_bar->extent.x0 == x0 && button_bar->extent.y0 == y0 &&
+ button_bar->extent.x1 == x1 &&
+ button_bar->extent.y1 == y1)
+ return true;
+
+ /* Redraw the relevant bits of the toolbar. We can't optimise for
+ * stretching the X-extent, as this probably means the button
+ * arrangement has changed which necessitates a full redraw anyway.
+ */
+
+ if (button_bar->window != NULL) {
+ xwimp_force_redraw(button_bar->window,
+ button_bar->extent.x0, button_bar->extent.y0,
+ button_bar->extent.x1, button_bar->extent.y1);
+ xwimp_force_redraw(button_bar->window, x0, y0, x1, y1);
+ }
+
+ button_bar->extent.x0 = x0;
+ button_bar->extent.y0 = y0;
+ button_bar->extent.x1 = x1;
+ button_bar->extent.y1 = y1;
+
+ if ((y1 - y0) > button_bar->y_min)
+ button_bar->vertical_offset =
+ ((y1 - y0) - button_bar->y_min) / 2;
+ else
+ button_bar->vertical_offset = 0;
+
+ return ro_gui_button_bar_icon_resize(button_bar);
+}
+
+
+/**
+ * Update the icons on a button bar, creating or deleting them from the window
+ * as necessary.
+ */
+
+bool ro_gui_button_bar_icon_update(struct button_bar *button_bar)
+{
+ wimp_icon_create icon;
+ struct button_bar_button *button, *b;
+ os_error *error;
+ bool on_bar;
+
+
+ if (button_bar == NULL || button_bar->window == NULL)
+ return (button_bar == NULL) ? false : true;
+
+ button = button_bar->buttons;
+
+ while (button != NULL) {
+ on_bar = false;
+
+ /* Check if the icon is currently on the bar. */
+
+ for (b = button_bar->bar; b != NULL; b = b->bar_next) {
+ if (b == button) {
+ on_bar = true;
+ break;
+ }
+ }
+
+ if (on_bar && !button_bar->hidden && button->icon == -1) {
+ icon.w = button_bar->window;
+ icon.icon.extent.x0 = 0;
+ icon.icon.extent.y0 = 0;
+ icon.icon.extent.x1 = 0;
+ icon.icon.extent.y1 = 0;
+ icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE |
+ wimp_ICON_INDIRECTED |
+ wimp_ICON_HCENTRED |
+ wimp_ICON_VCENTRED |
+ (button_bar->background
+ << wimp_ICON_BG_COLOUR_SHIFT);
+ icon.icon.data.indirected_text.size = 1;
+
+ /* We don't actually shade buttons unless there's no
+ * editor active or this is the source bar.
+ */
+
+ if (button->shaded && (!button_bar->edit ||
+ button_bar->edit_target != NULL))
+ icon.icon.flags |= wimp_ICON_SHADED;
+
+ if (button_bar->edit)
+ icon.icon.flags |= (wimp_BUTTON_CLICK_DRAG <<
+ wimp_ICON_BUTTON_TYPE_SHIFT);
+ else
+ icon.icon.flags |= (wimp_BUTTON_CLICK <<
+ wimp_ICON_BUTTON_TYPE_SHIFT);
+
+ icon.icon.data.indirected_text.text = null_text_string;
+ icon.icon.data.indirected_text.validation =
+ button->validation;
+
+ error = xwimp_create_icon(&icon, &button->icon);
+ if (error) {
+ LOG(("xwimp_create_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ button->icon = -1;
+ return false;
+ }
+ } else if ((!on_bar || button_bar->hidden)
+ && button->icon != -1) {
+ error = xwimp_delete_icon(button_bar->window,
+ button->icon);
+ if (error != NULL) {
+ LOG(("xwimp_delete_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return false;
+ }
+
+ button->icon = -1;
+ }
+
+ button = button->next;
+ }
+
+ return ro_gui_button_bar_icon_resize(button_bar);
+}
+
+
+/**
+ * Position the icons in the button bar to take account of the currently
+ * configured extent.
+ *
+ * \param *button_bar The button bar to update.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_button_bar_icon_resize(struct button_bar *button_bar)
+{
+ os_error *error;
+ struct button_bar_button *button;
+
+ if (button_bar == NULL || button_bar->hidden)
+ return (button_bar == NULL) ? false : true;
+
+ /* Reposition all the icons. */
+
+ button = button_bar->bar;
+
+ while (button != NULL) {
+ if(button->icon != -1) {
+ error = xwimp_resize_icon(button_bar->window,
+ button->icon,
+ button_bar->extent.x0 + button->x_pos,
+ button_bar->extent.y0 +
+ button_bar->vertical_offset +
+ button->y_pos,
+ button_bar->extent.x0 + button->x_pos +
+ button->x_size,
+ button_bar->extent.y0 +
+ button_bar->vertical_offset +
+ button->y_pos +
+ button->y_size);
+ if (error != NULL) {
+ LOG(("xwimp_resize_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ button->icon = -1;
+ return false;
+ }
+ }
+
+ button = button->bar_next;
+ }
+
+ return true;
+}
+
+
+/* This is an exported interface documented in button_bar.h */
+
+bool ro_gui_button_bar_hide(struct button_bar *button_bar, bool hide)
+{
+ if (button_bar == NULL || button_bar->hidden == hide)
+ return (button_bar == NULL) ? false : true;
+
+ button_bar->hidden = hide;
+
+ return ro_gui_button_bar_icon_update(button_bar);
+}
+
+
+/* This is an exported interface documented in button_bar.h */
+
+bool ro_gui_button_bar_shade_button(struct button_bar *button_bar,
+ button_bar_action action, bool shaded)
+{
+ struct button_bar_button *button;
+
+ if (button_bar == NULL)
+ return false;
+
+ button = ro_gui_button_bar_find_action(button_bar, action);
+ if (button == NULL)
+ return false;
+
+ if (button->shaded == shaded)
+ return true;
+
+ button->shaded = shaded;
+
+ /* We don't actually shade buttons unless there's no editor active
+ * or this is the source bar.
+ */
+
+ if (button->icon != -1 &&
+ (!button_bar->edit || button_bar->edit_target != NULL))
+ ro_gui_set_icon_shaded_state(button_bar->window, button->icon,
+ shaded);
+
+ return true;
+}
+
+
+/* This is an exported interface documented in button_bar.h */
+
+void ro_gui_button_bar_redraw(struct button_bar *button_bar,
+ wimp_draw *redraw)
+{
+ wimp_icon icon;
+ struct button_bar_button *button;
+
+ /* Test for a valid button bar, and then check that the redraw box
+ * coincides with the bar's extent.
+ */
+
+ if (button_bar == NULL || button_bar->hidden ||
+ (redraw->clip.x0 - (redraw->box.x0 - redraw->xscroll))
+ > button_bar->extent.x1 ||
+ (redraw->clip.y0 - (redraw->box.y1 - redraw->yscroll))
+ > button_bar->extent.y1 ||
+ (redraw->clip.x1 - (redraw->box.x0 - redraw->xscroll))
+ < button_bar->extent.x0 ||
+ (redraw->clip.y1 - (redraw->box.y1 - redraw->yscroll))
+ < button_bar->extent.y0 ||
+ (!button_bar->edit && !button_bar->separators))
+ return;
+
+ icon.flags = wimp_ICON_SPRITE | wimp_ICON_INDIRECTED |
+ wimp_ICON_HCENTRED | wimp_ICON_VCENTRED;
+ if (button_bar->edit)
+ icon.flags |= wimp_ICON_BORDER | wimp_COLOUR_DARK_GREY <<
+ wimp_ICON_FG_COLOUR_SHIFT;
+ if (!button_bar->separators)
+ icon.flags |= wimp_ICON_FILLED | wimp_COLOUR_LIGHT_GREY <<
+ wimp_ICON_BG_COLOUR_SHIFT;
+ icon.data.indirected_sprite.id = (osspriteop_id) separator_name;
+ icon.data.indirected_sprite.area = button_bar->sprites;
+ icon.data.indirected_sprite.size = 12;
+ icon.extent.y0 = button_bar->extent.y0 + button_bar->vertical_offset;
+ icon.extent.y1 = icon.extent.y0 + button_bar->y_min;
+
+ for (button = button_bar->bar; button != NULL;
+ button = button->bar_next) {
+ if (button->separator) {
+ icon.extent.x0 = button_bar->extent.x0 +
+ button->x_pos + button->x_size;
+ icon.extent.x1 = icon.extent.x0 +
+ button_bar->separator_width;
+ xwimp_plot_icon(&icon);
+ }
+ }
+}
+
+
+/* This is an exported interface documented in button_bar.h */
+
+bool ro_gui_button_bar_click(struct button_bar *button_bar,
+ wimp_pointer *pointer, wimp_window_state *state,
+ button_bar_action *action)
+{
+ struct button_bar_button *button;
+ os_coord pos;
+ os_box box;
+ os_error *error;
+ char *sprite;
+
+ if (button_bar == NULL || button_bar->hidden)
+ return false;
+
+ /* Check that the click was within our part of the window. */
+
+ pos.x = pointer->pos.x - state->visible.x0 + state->xscroll;
+ pos.y = pointer->pos.y - state->visible.y1 + state->yscroll;
+
+ if (pos.x < button_bar->extent.x0 || pos.x > button_bar->extent.x1 ||
+ pos.y < button_bar->extent.y0 ||
+ pos.y > button_bar->extent.y1)
+ return false;
+
+ if (button_bar->edit && pointer->buttons == wimp_DRAG_SELECT) {
+ /* This is an editor click, so we need to check for drags on
+ * icons (buttons) and work area (separators).
+ */
+
+ button = ro_gui_button_bar_find_coords(button_bar, pos,
+ &drag_separator, NULL);
+
+ if (button != NULL && (!button->shaded || drag_separator ||
+ button_bar->edit_source != NULL)) {
+ gui_current_drag_type = GUI_DRAG_BUTTONBAR;
+
+ drag_start = button_bar;
+ drag_opt = button->opt_key;
+
+ if (drag_separator) {
+ box.x0 = pointer->pos.x -
+ button_bar->separator_width / 2;
+ box.x1 = box.x0 + button_bar->separator_width;
+ sprite = separator_name;
+ } else {
+ box.x0 = pointer->pos.x - button->x_size / 2;
+ box.x1 = box.x0 + button->x_size;
+ sprite = button->sprite;
+ }
+
+ box.y0 = pointer->pos.y - button->y_size / 2;
+ box.y1 = box.y0 + button->y_size;
+
+ error = xdragasprite_start(dragasprite_HPOS_CENTRE |
+ dragasprite_VPOS_CENTRE |
+ dragasprite_BOUND_SPRITE |
+ dragasprite_BOUND_TO_WINDOW |
+ dragasprite_DROP_SHADOW,
+ button_bar->sprites,
+ sprite, &box, NULL);
+ if (error)
+ LOG(("xdragasprite_start: 0x%x: %s",
+ error->errnum, error->errmess));
+
+ return true;
+ }
+
+ } else if (!button_bar->edit && pointer->i != -1 &&
+ (pointer->buttons == wimp_CLICK_SELECT ||
+ pointer->buttons == wimp_CLICK_ADJUST)) {
+ /* This isn't an editor click, so we're only interested in
+ * Select or Adjust clicks that occur on physical icons.
+ */
+
+ button = ro_gui_button_bar_find_icon(button_bar, pointer->i);
+
+ if (button != NULL) {
+ if (action != NULL) {
+ switch (pointer->buttons) {
+ case wimp_CLICK_SELECT:
+ *action = button->select_action;
+ break;
+ case wimp_CLICK_ADJUST:
+ *action = button->adjust_action;
+ break;
+ default:
+ break;
+ }
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/* This is an exported interface documented in button_bar.h */
+
+bool ro_gui_button_bar_help_suffix(struct button_bar *button_bar, wimp_i i,
+ os_coord *mouse, wimp_window_state *state,
+ wimp_mouse_state buttons, const char **suffix)
+{
+ os_coord pos;
+ struct button_bar_button *button;
+
+ if (button_bar == NULL || button_bar->hidden)
+ return false;
+
+ /* Check that the click was within our part of the window. */
+
+ pos.x = mouse->x - state->visible.x0 + state->xscroll;
+ pos.y = mouse->y - state->visible.y1 + state->yscroll;
+
+ if (pos.x < button_bar->extent.x0 || pos.x > button_bar->extent.x1 ||
+ pos.y < button_bar->extent.y0 ||
+ pos.y > button_bar->extent.y1)
+ return false;
+
+ /* Look up and return the help suffix assocuated with the button. */
+
+ button = ro_gui_button_bar_find_icon(button_bar, i);
+
+ if (button != NULL)
+ *suffix = button->help_suffix;
+ else
+ *suffix = "";
+
+ return true;
+}
+
+
+/* This is an exported interface documented in button_bar.h */
+
+void ro_gui_button_bar_drag_end(wimp_dragged *drag)
+{
+ struct button_bar *drag_end = NULL;
+ struct button_bar *source = NULL, *target = NULL;
+ struct button_bar_button *button, *drop, *previous;
+ bool right, separator;
+ wimp_window_state state;
+ wimp_pointer pointer;
+ os_coord pos;
+ os_error *error;
+
+ xdragasprite_stop();
+ gui_current_drag_type = GUI_DRAG_NONE;
+
+ if (drag_start == NULL)
+ return;
+
+ /* Sort out the window coordinates of the drag end. */
+
+ 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;
+ }
+
+ assert(pointer.w = drag_start->window);
+
+ state.w = drag_start->window;
+ 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;
+ }
+
+ pos.x = pointer.pos.x - state.visible.x0 + state.xscroll;
+ pos.y = pointer.pos.y - state.visible.y1 + state.yscroll;
+
+ /* Work out the destination bar, and establish source and target. */
+
+ if (drag_start->edit_target != NULL) {
+ source = drag_start;
+ target = drag_start->edit_target;
+ if (pos.x >= target->extent.x0 && pos.x <= target->extent.x1 &&
+ pos.y >= target->extent.y0 &&
+ pos.y <= target->extent.y1)
+ drag_end = target;
+ } else if (drag_start->edit_source != NULL) {
+ source = drag_start->edit_source;
+ target = drag_start;
+ if (pos.x >= target->extent.x0 && pos.x <= target->extent.x1 &&
+ pos.y >= target->extent.y0 &&
+ pos.y <= target->extent.y1)
+ drag_end = target;
+ /* drag_end == source and drag_end == NULL are both equivalent
+ * as far as the following code are concerned, and we don't need
+ * to identify either case. */
+ }
+
+ button = ro_gui_button_bar_find_opt_key(target, drag_opt);
+ assert(button != NULL);
+
+ /* The drag finished in the target bar, so find out where. */
+
+ if (drag_end == target) {
+ drop = ro_gui_button_bar_find_coords(target, pos,
+ &separator, &right);
+ } else {
+ drop = NULL;
+ }
+
+ /* If the button is dropped on itself, there's no change and it's
+ * less messy to get out now.
+ */
+
+ if (drag_start == target && drag_end == target && button == drop) {
+ drag_start = NULL;
+ return;
+ }
+
+ /* The drag started in the target bar, so remove the dragged button. */
+
+ if (drag_start == target) {
+ if (drag_separator) {
+ button->separator = false;
+ } else if (target->bar == button) {
+ target->bar = button->bar_next;
+ } else {
+ for (previous = target->bar; previous != NULL &&
+ previous->bar_next != button;
+ previous = previous->bar_next);
+ assert(previous != NULL);
+ previous->bar_next = button->bar_next;
+ if (button->separator) // ??
+ previous->separator = true; // ??
+ }
+ }
+
+ /* The drag ended in the target bar, so add the dragged button in. */
+
+ if (drop != NULL) {
+ if (right) {
+ if (drag_separator) {
+ drop->separator = true;
+ } else {
+ button->bar_next = drop->bar_next;
+ drop->bar_next = button;
+ if (drop->separator && !separator) {
+ drop->separator = false;
+ button->separator = true;
+ } else {
+ button->separator = false;
+ }
+ }
+ } else if (target->bar == drop && !drag_separator) {
+ button->separator = false;
+ button->bar_next = target->bar;
+ target->bar = button;
+ } else if (target->bar != drop) {
+ for (previous = target->bar; previous != NULL &&
+ previous->bar_next != drop;
+ previous = previous->bar_next);
+ assert(previous != NULL);
+
+ if (drag_separator) {
+ previous->separator = true;
+ } else {
+ if (separator) {
+ previous->separator = false;
+ button->separator = true;
+ } else {
+ button->separator = false;
+ }
+ button->bar_next = previous->bar_next;
+ previous->bar_next = button;
+ }
+ }
+ }
+
+ /* Reposition the buttons and force our client to update. */
+
+ ro_gui_button_bar_place_buttons(target);
+ ro_gui_button_bar_icon_update(target);
+ ro_gui_button_bar_sync_editors(target, source);
+
+ xwimp_force_redraw(target->window,
+ target->extent.x0, target->extent.y0,
+ target->extent.x1, target->extent.y1);
+
+ if (source->edit_refresh != NULL)
+ source->edit_refresh(source->edit_client_data);
+
+ drag_start = NULL;
+}
+
+
+/**
+ * Synchronise the shading of a button bar editor source bar with the currently
+ * defined buttons in its target bar.
+ *
+ * \param *target The editor target bar.
+ * \param *source The editor source bar.
+ */
+
+void ro_gui_button_bar_sync_editors(struct button_bar *target,
+ struct button_bar *source)
+{
+ struct button_bar_button *sb, *tb;
+
+ if (source == NULL || target == NULL)
+ return;
+
+ /* Unshade all of the buttons in the source bar. */
+
+ for (sb = source->bar; sb != NULL; sb = sb->bar_next)
+ sb->shaded = false;
+
+ /* Step through the target bar and shade each corresponding
+ * button in the source.
+ */
+
+ for (tb = target->bar; tb != NULL; tb = tb->bar_next) {
+ sb = ro_gui_button_bar_find_opt_key(source, tb->opt_key);
+
+ if (sb != NULL)
+ sb->shaded = true;
+ }
+
+ /* Phyically shade the necessary buttons in the toolbar. */
+
+ for (sb = source->bar; sb != NULL; sb = sb->bar_next)
+ if (sb->icon != -1)
+ ro_gui_set_icon_shaded_state(source->window, sb->icon,
+ sb->shaded);
+}
+
+
+/* This is an exported interface documented in button_bar.h */
+
+char *ro_gui_button_bar_get_config(struct button_bar *button_bar)
+{
+ struct button_bar_button *button;
+ size_t size;
+ char *config;
+ int i;
+
+ if (button_bar == NULL)
+ return NULL;
+
+ for (size = 1, button = button_bar->bar; button != NULL;
+ button = button->bar_next) {
+ size++;
+ if (button->separator)
+ size++;
+ }
+
+ config = malloc(size);
+ if (config == NULL) {
+ LOG(("No memory for malloc()"));
+ warn_user("NoMemory", 0);
+ return NULL;
+ }
+
+ for (i = 0, button = button_bar->bar; button != NULL;
+ button = button->bar_next) {
+ config[i++] = button->opt_key;
+ if (button->separator)
+ config[i++] = '|';
+ }
+
+ config[i] = '\0';
+
+ return config;
+}
+
+
+/**
+ * Find a button bar icon definition from an icon handle.
+ *
+ * \param *button_bar The button bar to use.
+ * \param icon The icon handle.
+ * \return Pointer to the button bar icon, or NULL.
+ */
+
+struct button_bar_button *ro_gui_button_bar_find_icon(
+ struct button_bar *button_bar, wimp_i icon)
+{
+ struct button_bar_button *button;
+
+ if (button_bar == NULL || icon == -1)
+ return NULL;
+
+ button = button_bar->buttons;
+
+ while (button != NULL && button->icon != icon)
+ button = button->next;
+
+ return button;
+}
+
+
+/**
+ * Find a button bar icon definition from an options key code.
+ *
+ * \param *button_bar The button bar to use.
+ * \param opt_key The option key character code.
+ * \return Pointer to the button bar icon, or NULL.
+ */
+
+struct button_bar_button *ro_gui_button_bar_find_opt_key(
+ struct button_bar *button_bar, char opt_key)
+{
+ struct button_bar_button *button;
+
+ if (button_bar == NULL)
+ return NULL;
+
+ button = button_bar->buttons;
+
+ while (button != NULL && button->opt_key != opt_key)
+ button = button->next;
+
+ return button;
+}
+
+
+/**
+ * Find a button bar icon definition from an action code.
+ *
+ * \param *button_bar The button bar to use.
+ * \param action The button action to find.
+ * \return Pointer to the button bar icon, or NULL.
+ */
+
+struct button_bar_button *ro_gui_button_bar_find_action(
+ struct button_bar *button_bar, button_bar_action action)
+{
+ struct button_bar_button *button;
+
+ if (button_bar == NULL)
+ return NULL;
+
+ button = button_bar->buttons;
+
+ while (button != NULL &&
+ button->select_action != action &&
+ button->adjust_action != action)
+ button = button->next;
+
+ return button;
+}
+
+
+/**
+ * Find a button bar icon definition from coordinates.
+ *
+ * \param *button_bar The button bar to use.
+ * \param pos The coordinates to find, work area relative.
+ * \param *separator Returns true if the associated separator was
+ * matched; else false.
+ * \param *right Returns true if the coordinates were in the
+ * right hand side of the target; else false.
+ * \return Pointer to the button bar icon, or NULL.
+ */
+
+struct button_bar_button *ro_gui_button_bar_find_coords(
+ struct button_bar *button_bar, os_coord pos,
+ bool *separator, bool *right)
+{
+ struct button_bar_button *button;
+ int x0, y0, x1, y1;
+
+ if (button_bar == NULL)
+ return NULL;
+
+ button = button_bar->bar;
+
+ while (button != NULL) {
+ /* Match button extents. */
+
+ x0 = button_bar->extent.x0 + button->x_pos;
+ y0 = button_bar->extent.y0 + button->y_pos;
+ x1 = x0 + button->x_size;
+ y1 = y0 + button->y_size;
+
+ if (pos.x > x0 && pos.y > y0 && pos.x < x1 && pos.y < y1) {
+ if (separator != NULL)
+ *separator = false;
+
+ if (right != NULL)
+ *right = (pos.x > x0 + button->x_size/2) ?
+ true : false;
+ return button;
+ }
+
+ x0 = x1;
+ x1 = x0 + button_bar->separator_width;
+
+ /* Match separator extents. */
+
+ if (pos.x > x0 && pos.y > y0 && pos.x < x1 && pos.y < y1 &&
+ button->separator) {
+ if (separator != NULL)
+ *separator = true;
+
+ if (right != NULL)
+ *right = (x0 + button_bar->separator_width/2) ?
+ true : false;
+ return button;
+ }
+
+ button = button->bar_next;
+ }
+
+ return NULL;
+}
+
diff --git a/riscos/gui/button_bar.h b/riscos/gui/button_bar.h
new file mode 100644
index 000000000..d92428859
--- /dev/null
+++ b/riscos/gui/button_bar.h
@@ -0,0 +1,314 @@
+/*
+ * Copyright 2005 Richard Wilson <info@tinct.net>
+ * Copyright 2011 Stephen Fryatt <stevef@netsurf-browser.org>
+ *
+ * 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
+ * Button bars (interface).
+ */
+
+#ifndef _NETSURF_RISCOS_BUTTONBAR_H_
+#define _NETSURF_RISCOS_BUTTONBAR_H_
+
+#include <stdbool.h>
+#include "riscos/theme.h"
+
+/* A list of possible toolbar actions. */
+
+typedef enum {
+ TOOLBAR_BUTTON_NONE = 0, /* Special case: no action */
+ TOOLBAR_BUTTON_BACK,
+ TOOLBAR_BUTTON_BACK_NEW,
+ TOOLBAR_BUTTON_UP,
+ TOOLBAR_BUTTON_UP_NEW,
+ TOOLBAR_BUTTON_FORWARD,
+ TOOLBAR_BUTTON_FORWARD_NEW,
+ TOOLBAR_BUTTON_STOP,
+ TOOLBAR_BUTTON_RELOAD,
+ TOOLBAR_BUTTON_RELOAD_ALL,
+ TOOLBAR_BUTTON_HOME,
+ TOOLBAR_BUTTON_HISTORY_LOCAL,
+ TOOLBAR_BUTTON_HISTORY_GLOBAL,
+ TOOLBAR_BUTTON_SAVE_SOURCE,
+ TOOLBAR_BUTTON_SAVE_COMPLETE,
+ TOOLBAR_BUTTON_PRINT,
+ TOOLBAR_BUTTON_BOOKMARK_OPEN,
+ TOOLBAR_BUTTON_BOOKMARK_ADD,
+ TOOLBAR_BUTTON_SCALE,
+ TOOLBAR_BUTTON_SEARCH,
+ TOOLBAR_BUTTON_DELETE,
+ TOOLBAR_BUTTON_EXPAND,
+ TOOLBAR_BUTTON_COLLAPSE,
+ TOOLBAR_BUTTON_OPEN,
+ TOOLBAR_BUTTON_CLOSE,
+ TOOLBAR_BUTTON_LAUNCH,
+ TOOLBAR_BUTTON_CREATE
+} button_bar_action;
+
+/* Button bar button source definitions.
+ *
+ * Help tokens are added to the help prefix for the given toolbar by the
+ * help system, and correspond to the hard-coded icon numbers that were
+ * assigned to the different buttons in the original toolbar implementation.
+ * If the Messages file can be updated, these can change to something more
+ * meaningful.
+ */
+
+struct button_bar_buttons {
+ const char *icon; /**< The sprite used for the icon. */
+ button_bar_action select; /**< The action for select clicks. */
+ button_bar_action adjust; /**< The action for Adjust clicks. */
+ const char opt_key; /**< The char used in option strings. */
+ const char *help; /**< The interactive help token. */
+};
+
+/* \TODO -- Move these to the correct modules.
+ */
+
+static const struct button_bar_buttons brower_toolbar_buttons[] = {
+ {"back", TOOLBAR_BUTTON_BACK, TOOLBAR_BUTTON_BACK_NEW, '0', "0"},
+ {"up", TOOLBAR_BUTTON_UP, TOOLBAR_BUTTON_UP_NEW, 'b', "11"},
+ {"forward", TOOLBAR_BUTTON_FORWARD, TOOLBAR_BUTTON_FORWARD_NEW, '1', "1"},
+ {"stop", TOOLBAR_BUTTON_STOP, TOOLBAR_BUTTON_NONE, '2', "2"},
+ {"reload", TOOLBAR_BUTTON_RELOAD, TOOLBAR_BUTTON_RELOAD_ALL, '3', "3"},
+ {"home", TOOLBAR_BUTTON_HOME, TOOLBAR_BUTTON_NONE, '4', "4"},
+ {"history", TOOLBAR_BUTTON_HISTORY_LOCAL, TOOLBAR_BUTTON_HISTORY_GLOBAL, '5', "5"},
+ {"save", TOOLBAR_BUTTON_SAVE_SOURCE, TOOLBAR_BUTTON_SAVE_COMPLETE, '6', "6"},
+ {"print", TOOLBAR_BUTTON_PRINT, TOOLBAR_BUTTON_NONE, '7', "7"},
+ {"hotlist", TOOLBAR_BUTTON_BOOKMARK_OPEN, TOOLBAR_BUTTON_BOOKMARK_ADD, '8', "8"},
+ {"scale", TOOLBAR_BUTTON_SCALE, TOOLBAR_BUTTON_NONE, '9', "9"},
+ {"search", TOOLBAR_BUTTON_SEARCH, TOOLBAR_BUTTON_NONE, 'a', "10"},
+ {NULL, TOOLBAR_BUTTON_NONE, TOOLBAR_BUTTON_NONE, '\0', ""}
+};
+
+static const struct button_bar_buttons cookies_toolbar_buttons[] = {
+ {"delete", TOOLBAR_BUTTON_DELETE, TOOLBAR_BUTTON_NONE, '0', "0"},
+ {"expand", TOOLBAR_BUTTON_EXPAND, TOOLBAR_BUTTON_COLLAPSE, '1', "1"},
+ {"open", TOOLBAR_BUTTON_OPEN, TOOLBAR_BUTTON_CLOSE, '2', "2"},
+ {NULL, TOOLBAR_BUTTON_NONE, TOOLBAR_BUTTON_NONE, '\0', ""}
+};
+
+static const struct button_bar_buttons global_history_toolbar_buttons[] = {
+ {"delete", TOOLBAR_BUTTON_DELETE, TOOLBAR_BUTTON_NONE, '0', "0"},
+ {"expand", TOOLBAR_BUTTON_EXPAND, TOOLBAR_BUTTON_COLLAPSE, '1', "1"},
+ {"open", TOOLBAR_BUTTON_OPEN, TOOLBAR_BUTTON_CLOSE, '2', "2"},
+ {"launch", TOOLBAR_BUTTON_LAUNCH, TOOLBAR_BUTTON_NONE, '3', "3"},
+ {NULL, TOOLBAR_BUTTON_NONE, TOOLBAR_BUTTON_NONE, '\0', ""}
+};
+
+static const struct button_bar_buttons hotlist_toolbar_buttons[] = {
+ {"delete", TOOLBAR_BUTTON_DELETE, TOOLBAR_BUTTON_NONE, '0', "0"},
+ {"expand", TOOLBAR_BUTTON_EXPAND, TOOLBAR_BUTTON_COLLAPSE, '1', "1"},
+ {"open", TOOLBAR_BUTTON_OPEN, TOOLBAR_BUTTON_CLOSE, '2', "2"},
+ {"launch", TOOLBAR_BUTTON_LAUNCH, TOOLBAR_BUTTON_NONE, '3', "3"},
+ {"create", TOOLBAR_BUTTON_CREATE, TOOLBAR_BUTTON_NONE, '4', "4"},
+ {NULL, TOOLBAR_BUTTON_NONE, TOOLBAR_BUTTON_NONE, '\0', ""}
+};
+
+struct button_bar;
+
+
+/**
+ * Create a new button bar widget.
+ *
+ * \param *theme The theme to apply (or NULL for the default).
+ * \param buttons[] An array of button definitions for the bar.
+ * \return A button bar handle, or NULL on failure.
+ */
+
+struct button_bar *ro_gui_button_bar_create(struct theme_descriptor *theme,
+ const struct button_bar_buttons buttons[]);
+
+
+/**
+ * Link two button bars together: the target being the active bar, and the
+ * source being the editing bar used to supply valid buttons. The bars are
+ * checked to ensure that they are not already part of an edit pair, but are
+ * not checked for button-compatibility.
+ *
+ * \param *target The target button bar.
+ * \param *source The source button bar.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_button_bar_link_editor(struct button_bar *target,
+ struct button_bar *source, void (* refresh)(void *),
+ void *client_data);
+
+/**
+ * Place a button bar into a toolbar window and initialise any theme-specific
+ * settings. Any previous incarnation of the bar will be forgotten: this
+ * is for use when a new toolbar is being created, or when a toolbar has been
+ * deleted and rebuilt following a theme change.
+ *
+ * \param *button_bar The button bar to rebuild.
+ * \param *theme The theme to apply (or NULL for current).
+ * \param style The theme style to apply.
+ * \param window The window that the bar is in.
+ * \param edit The edit mode of the button bar.
+ * \return true on success; else false.
+ */
+
+bool ro_gui_button_bar_rebuild(struct button_bar *button_bar,
+ struct theme_descriptor *theme, theme_style style,
+ wimp_w window, bool edit);
+
+
+/**
+ * Arrange buttons on a button bar, using an order string to specify the
+ * required button and separator layout.
+ *
+ * \param *button_bar The button bar to update.
+ * \param order[] The button order configuration string.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_button_bar_arrange_buttons(struct button_bar *button_bar,
+ char order[]);
+
+
+/**
+ * Destroy a button bar widget.
+ *
+ * \param *button_bar The button bar to destroy.
+ */
+
+void ro_gui_button_bar_destroy(struct button_bar *button_bar);
+
+
+/**
+ * Return the MINIMUM dimensions required by the button bar, in RO units,
+ * allowing for the current theme.
+ *
+ * \param *button_bar The button bar of interest.
+ * \param *width Return the required width.
+ * \param *height Return the required height.
+ * \return true if values are returned; else false.
+ */
+
+bool ro_gui_button_bar_get_dims(struct button_bar *button_bar,
+ int *width, int *height);
+
+
+/**
+ * Set or update the dimensions to be used by the button bar, in RO units.
+ * If these are greater than the minimum required, the button bar will fill
+ * the extended space; if less, the call will fail.
+ *
+ * \param *button_bar The button bar to update.
+ * \param x0 The minimum X window position.
+ * \param y0 The minimum Y window position.
+ * \param x1 The maximum X window position.
+ * \param y1 The maximum Y window position.
+ * \return true if size updated; else false.
+ */
+
+bool ro_gui_button_bar_set_extent(struct button_bar *button_bar,
+ int x0, int y0, int x1, int y1);
+
+
+/**
+ * Show or hide a button bar.
+ *
+ * \param *button_bar The button bar to hide.
+ * \param hide true to hide the bar; false to show it.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_button_bar_hide(struct button_bar *button_bar, bool hide);
+
+
+/**
+ * Shade or unshade a button in a bar corresponding to the given action.
+ *
+ * \param *button_bar The button bar to update.
+ * \param action The action to update.
+ * \param shaded true to shade the button; false to unshade.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_button_bar_shade_button(struct button_bar *button_bar,
+ button_bar_action action, bool shaded);
+
+
+/**
+ * Handle redraw event rectangles in a button bar.
+ *
+ * \param *button_bar The button bar to use.
+ * \param *redraw The Wimp redraw rectangle to process.
+ */
+
+void ro_gui_button_bar_redraw(struct button_bar *button_bar,
+ wimp_draw *redraw);
+
+
+/**
+ * Handle mouse clicks in a button bar.
+ *
+ * \param *button_bar The button bar to use.
+ * \param *pointer The Wimp mouse click event data.
+ * \param *state The toolbar window state.
+ * \param *action Returns the selected action, or
+ * TOOLBAR_BUTTON_NONE.
+ * \return true if the event was handled exclusively;
+ * else false.
+ */
+
+bool ro_gui_button_bar_click(struct button_bar *button_bar,
+ wimp_pointer *pointer, wimp_window_state *state,
+ button_bar_action *action);
+
+
+/**
+ * Translate mouse data into an interactive help message for a button bar.
+ *
+ * \param *button_bar The button bar to process.
+ * \param i The wimp icon under the pointer.
+ * \param *mouse The mouse position.
+ * \param *state The toolbar window state.
+ * \param buttons The mouse button state.
+ * \param **suffix Return a help token suffix, or "" for none.
+ * \return true if handled exclusively; else false.
+ */
+
+bool ro_gui_button_bar_help_suffix(struct button_bar *button_bar, wimp_i i,
+ os_coord *mouse, wimp_window_state *state,
+ wimp_mouse_state buttons, const char **suffix);
+
+
+/**
+ * Terminate a drag event that was initiated by a button bar.
+ *
+ * \param *drag The drag event data.
+ */
+
+void ro_gui_button_bar_drag_end(wimp_dragged *drag);
+
+
+/**
+ * Return a config string reflecting the configured order of buttons
+ * and spacers. The string is allocated with malloc(), and should be
+ * free()d after use.
+ *
+ * \param *button_bar The button bar of interest.
+ * \return Pointer to a config string, or NULL on failure.
+ */
+
+char *ro_gui_button_bar_get_config(struct button_bar *button_bar);
+
+#endif
+
diff --git a/riscos/gui/throbber.c b/riscos/gui/throbber.c
new file mode 100644
index 000000000..05860a923
--- /dev/null
+++ b/riscos/gui/throbber.c
@@ -0,0 +1,419 @@
+/*
+ * Copyright 2004, 2005 Richard Wilson <info@tinct.net>
+ * Copyright 2011 Stephen Fryatt <stevef@netsurf-browser.org>
+ *
+ * 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
+ * Throbber (implementation).
+ */
+
+#include <alloca.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include "oslib/os.h"
+#include "oslib/osspriteop.h"
+#include "oslib/wimp.h"
+#include "riscos/gui/throbber.h"
+#include "riscos/theme.h"
+#include "riscos/wimp.h"
+#include "utils/log.h"
+#include "utils/utils.h"
+
+#define THROBBER_SPRITE_NAME_LENGTH 12
+#define THROBBER_ANIMATE_INTERVAL 10
+
+struct throbber {
+ /** The applied theme (or NULL to use the default) */
+ struct theme_descriptor *theme;
+
+ /** The widget dimensions. */
+ int x_min, y_min;
+
+ /** The window and icon details. */
+ wimp_w window;
+ wimp_i icon;
+ os_box extent;
+ osspriteop_area *sprites;
+ bool hidden;
+ bool shaded;
+
+ /** The animation details. */
+ int max_frame;
+ int current_frame;
+ os_t last_update;
+ char sprite_name[THROBBER_SPRITE_NAME_LENGTH];
+ bool force_redraw;
+};
+
+/*
+ * Private function prototypes.
+ */
+
+static bool ro_gui_throbber_icon_update(struct throbber *throbber);
+static bool ro_gui_throbber_icon_resize(struct throbber *throbber);
+
+/* This is an exported interface documented in throbber.h */
+
+struct throbber *ro_gui_throbber_create(struct theme_descriptor *theme)
+{
+ struct throbber *throbber;
+
+ /* Allocate memory. */
+
+ throbber = malloc(sizeof(struct throbber));
+ if (throbber == NULL) {
+ LOG(("No memory for malloc()"));
+ return NULL;
+ }
+
+ /* Set up default parameters. If reading the throbber theme data
+ * fails, we give up and return a failure.
+ */
+
+ if (!ro_gui_theme_get_throbber_data(theme, &throbber->max_frame,
+ &throbber->x_min, &throbber->y_min, NULL,
+ &throbber->force_redraw)) {
+ free(throbber);
+ return NULL;
+ }
+
+ throbber->sprites = ro_gui_theme_get_sprites(theme);
+
+ throbber->theme = theme;
+
+ throbber->extent.x0 = 0;
+ throbber->extent.y0 = 0;
+ throbber->extent.x1 = 0;
+ throbber->extent.y1 = 0;
+
+ throbber->current_frame = 0;
+ throbber->last_update = 0;
+
+ throbber->window = NULL;
+ throbber->icon = -1;
+
+ throbber->hidden = false;
+ throbber->shaded = false;
+
+ return throbber;
+}
+
+
+/* This is an exported interface documented in throbber.h */
+
+bool ro_gui_throbber_rebuild(struct throbber *throbber,
+ struct theme_descriptor *theme, theme_style style,
+ wimp_w window, bool shaded)
+{
+ if (throbber == NULL)
+ return false;
+
+ throbber->theme = theme;
+ throbber->window = window;
+ throbber->sprites = ro_gui_theme_get_sprites(theme);
+
+ throbber->icon = -1;
+
+ throbber->shaded = shaded;
+
+ strcpy(throbber->sprite_name, "throbber0");
+
+ if (!ro_gui_theme_get_throbber_data(theme, &throbber->max_frame,
+ &throbber->x_min, &throbber->y_min, NULL,
+ &throbber->force_redraw)) {
+ free(throbber);
+ return false;
+ }
+
+ return ro_gui_throbber_icon_update(throbber);
+}
+
+
+/* This is an exported interface documented in throbber.h */
+
+void ro_gui_throbber_destroy(struct throbber *throbber)
+{
+ if (throbber == NULL)
+ return;
+
+ free(throbber);
+}
+
+
+/* This is an exported interface documented in throbber.h */
+
+bool ro_gui_throbber_get_dims(struct throbber *throbber,
+ int *width, int *height)
+{
+ if (throbber == NULL)
+ return false;
+
+ if (throbber->x_min != -1 && throbber->y_min != -1) {
+ if (width != NULL)
+ *width = throbber->x_min;
+ if (height != NULL)
+ *height = throbber->y_min;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+/* This is an exported interface documented in throbber.h */
+
+bool ro_gui_throbber_set_extent(struct throbber *throbber,
+ int x0, int y0, int x1, int y1)
+{
+ if (throbber == NULL)
+ return false;
+
+ if ((x1 - x0) < throbber->x_min || (y1 - y0) < throbber->y_min)
+ return false;
+
+ if (throbber->extent.x0 == x0 && throbber->extent.y0 == y0 &&
+ throbber->extent.x1 == x1 &&
+ throbber->extent.y1 == y1)
+ return true;
+
+ /* Redraw the relevant bits of the toolbar. */
+
+ if (throbber->window != NULL && throbber->icon != -1) {
+ xwimp_force_redraw(throbber->window,
+ throbber->extent.x0, throbber->extent.y0,
+ throbber->extent.x1, throbber->extent.y1);
+ xwimp_force_redraw(throbber->window, x0, y0, x1, y1);
+ }
+
+ /* Update the throbber position */
+
+ throbber->extent.x0 = x0;
+ throbber->extent.y0 = y0;
+ throbber->extent.x1 = x1;
+ throbber->extent.y1 = y1;
+
+ return ro_gui_throbber_icon_resize(throbber);
+}
+
+
+/**
+ * Create or delete a throbber's icon if required to bring it into sync with
+ * the current hidden setting.
+ *
+ * \param *throbber The throbber to update.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_throbber_icon_update(struct throbber *throbber)
+{
+ wimp_icon_create icon;
+ os_error *error;
+
+ if (throbber == NULL || throbber->window == NULL)
+ return false;
+
+ if (!throbber->hidden && throbber->icon == -1) {
+ icon.w = throbber->window;
+ icon.icon.extent.x0 = throbber->extent.x0;
+ icon.icon.extent.y0 = throbber->extent.y0;
+ icon.icon.extent.x1 = throbber->extent.x1;
+ icon.icon.extent.y1 = throbber->extent.y1;
+ icon.icon.flags = wimp_ICON_SPRITE | wimp_ICON_INDIRECTED |
+ wimp_ICON_HCENTRED | wimp_ICON_VCENTRED;
+ icon.icon.data.indirected_sprite.id =
+ (osspriteop_id) throbber->sprite_name;
+ icon.icon.data.indirected_sprite.area = throbber->sprites;
+ icon.icon.data.indirected_sprite.size =
+ THROBBER_SPRITE_NAME_LENGTH;
+
+ error = xwimp_create_icon(&icon, &throbber->icon);
+ if (error != NULL) {
+ LOG(("xwimp_create_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ throbber->icon = -1;
+ return false;
+ }
+
+ if (!ro_gui_throbber_icon_resize(throbber))
+ return false;
+ } else if (throbber->hidden && throbber->icon != -1) {
+ error = xwimp_delete_icon(throbber->window, throbber->icon);
+ if (error != NULL) {
+ LOG(("xwimp_delete_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return false;
+ }
+
+ throbber->icon = -1;
+ }
+
+ if (throbber->icon != -1)
+ ro_gui_set_icon_shaded_state(throbber->window,
+ throbber->icon, throbber->shaded);
+
+ return true;
+}
+
+
+/**
+ * Position the icons in the throbber to take account of the currently
+ * configured extent.
+ *
+ * \param *throbber The throbber to update.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_throbber_icon_resize(struct throbber *throbber)
+{
+ os_error *error;
+
+ if (throbber->window == NULL)
+ return false;
+
+ if (throbber->icon != -1) {
+ error = xwimp_resize_icon(throbber->window, throbber->icon,
+ throbber->extent.x0, throbber->extent.y0,
+ throbber->extent.x1, throbber->extent.y1);
+ if (error != NULL) {
+ LOG(("xwimp_resize_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ throbber->icon = -1;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+/* This is an exported interface documented in throbber.h */
+
+bool ro_gui_throbber_hide(struct throbber *throbber, bool hide)
+{
+ if (throbber == NULL || throbber->hidden == hide)
+ return (throbber == NULL) ? false : true;
+
+ throbber->hidden = hide;
+
+ return ro_gui_throbber_icon_update(throbber);
+}
+
+
+/* This is an exported interface documented in throbber.h */
+
+bool ro_gui_throbber_help_suffix(struct throbber *throbber, wimp_i i,
+ os_coord *mouse, wimp_window_state *state,
+ wimp_mouse_state buttons, const char **suffix)
+{
+ os_coord pos;
+
+ if (throbber == NULL || throbber->hidden)
+ return false;
+
+ /* Check that the click was within our part of the window. */
+
+ pos.x = mouse->x - state->visible.x0 + state->xscroll;
+ pos.y = mouse->y - state->visible.y1 + state->yscroll;
+
+ if (pos.x < throbber->extent.x0 || pos.x > throbber->extent.x1 ||
+ pos.y < throbber->extent.y0 ||
+ pos.y > throbber->extent.y1)
+ return false;
+
+ /* Return a hard-coded icon number that matches the one that was
+ * always allocated to the throbber in a previous implementation.
+ * If Messages can be updated, this could be changed.
+ */
+
+ if (i == throbber->icon)
+ *suffix = "16";
+ else
+ *suffix = "";
+
+ return true;
+}
+
+
+/* This is an exported interface documented in throbber.h */
+
+bool ro_gui_throbber_animate(struct throbber *throbber)
+{
+ os_t t;
+ char sprite_name[THROBBER_SPRITE_NAME_LENGTH];
+
+ if (throbber == NULL || throbber->hidden)
+ return (throbber == NULL) ? false : true;
+
+ xos_read_monotonic_time(&t);
+
+ /* Drop out if we're not ready for the next frame, unless this
+ * call is to start animation from a stopped throbber (ie. if
+ * the current frame is 0).
+ */
+
+ if ((t < (throbber->last_update + THROBBER_ANIMATE_INTERVAL)) &&
+ (throbber->current_frame > 0))
+ return true;
+
+ throbber->last_update = t;
+ throbber->current_frame++;
+
+ if (throbber->current_frame > throbber->max_frame)
+ throbber->current_frame = 1;
+
+ snprintf(sprite_name, THROBBER_SPRITE_NAME_LENGTH,
+ "throbber%i", throbber->current_frame);
+ ro_gui_set_icon_string(throbber->window, throbber->icon,
+ sprite_name, true);
+
+ if (throbber->force_redraw)
+ ro_gui_force_redraw_icon(throbber->window, throbber->icon);
+
+ return true;
+}
+
+
+/* This is an exported interface documented in throbber.h */
+
+bool ro_gui_throbber_stop(struct throbber *throbber)
+{
+ char sprite_name[THROBBER_SPRITE_NAME_LENGTH];
+
+ if (throbber == NULL || throbber->hidden ||
+ throbber->current_frame == 0)
+ return (throbber == FALSE) ? false : true;
+
+ throbber->current_frame = 0;
+ throbber->last_update = 0;
+
+ strcpy(sprite_name, "throbber0");
+ ro_gui_set_icon_string(throbber->window, throbber->icon,
+ sprite_name, true);
+
+ if (throbber->force_redraw)
+ ro_gui_force_redraw_icon(throbber->window, throbber->icon);
+
+ return true;
+}
+
diff --git a/riscos/gui/throbber.h b/riscos/gui/throbber.h
new file mode 100644
index 000000000..10d39ebfd
--- /dev/null
+++ b/riscos/gui/throbber.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2005 Richard Wilson <info@tinct.net>
+ * Copyright 2011 Stephen Fryatt <stevef@netsurf-browser.org>
+ *
+ * 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
+ * Throbber (interface).
+ */
+
+#ifndef _NETSURF_RISCOS_THROBBER_H_
+#define _NETSURF_RISCOS_THROBBER_H_
+
+#include <stdbool.h>
+#include "riscos/theme.h"
+
+struct throbber;
+
+
+/**
+ * Create a new throbber widget.
+ *
+ * \param *theme The theme to apply (or NULL for the default).
+ * \return A throbber handle, or NULL on failure.
+ */
+
+struct throbber *ro_gui_throbber_create(struct theme_descriptor *theme);
+
+/**
+ * Place a throbber into a toolbar window and initialise any theme-specific
+ * settings. Any previous incarnation of the throbber will be forgotten: this
+ * is for use when a new toolbar is being created, or when a toolbar has been
+ * deleted and rebuilt following a theme change.
+ *
+ * \param *throbber The throbber to rebuild.
+ * \param *theme The theme to apply (or NULL for current).
+ * \param style The theme style to apply.
+ * \param window The window that the throbber is in.
+ * \param shaded true if the bar should be throbber; else false.
+ * \return true on success; else false.
+ */
+
+bool ro_gui_throbber_rebuild(struct throbber *throbber,
+ struct theme_descriptor *theme, theme_style style,
+ wimp_w window, bool shaded);
+
+
+/**
+ * Destroy a throbber widget.
+ *
+ * \param *throbber The throbber to destroy.
+ */
+
+void ro_gui_throbber_destroy(struct throbber *throbber);
+
+
+/**
+ * Return the MINIMUM dimensions required by the throbber, in RO units,
+ * allowing for the current theme.
+ *
+ * \param *throbber The throbber of interest.
+ * \param *width Return the required width.
+ * \param *height Return the required height.
+ * \return true if values are returned; else false.
+ */
+
+bool ro_gui_throbber_get_dims(struct throbber *throbber,
+ int *width, int *height);
+
+
+/**
+ * Set or update the dimensions to be used by the throbber, in RO units.
+ * If these are greater than the minimum required, the throbber will fill
+ * the extended space; if less, the call will fail.
+ *
+ * \param *throbber The throbber to update.
+ * \param width The desired width.
+ * \param height The desired height.
+ * \return true if size updated; else false.
+ */
+
+bool ro_gui_throbber_set_extent(struct throbber *throbber,
+ int x0, int y0, int x1, int y1);
+
+
+/**
+ * Show or hide a throbber.
+ *
+ * \param *throbber The throbber to hide.
+ * \param hide true to hide the throbber; false to show it.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_throbber_hide(struct throbber *throbber, bool hide);
+
+
+/**
+ * Translate mouse data into an interactive help message for the throbber.
+ *
+ * \param *throbber The throbber to process.
+ * \param i The wimp icon under the pointer.
+ * \param *mouse The mouse position.
+ * \param *state The toolbar window state.
+ * \param buttons The mouse button state.
+ * \param **suffix Return a help token suffix, or "" for none.
+ * \return true if handled exclusively; else false.
+ */
+
+bool ro_gui_throbber_help_suffix(struct throbber *throbber, wimp_i i,
+ os_coord *screenpos, wimp_window_state *state,
+ wimp_mouse_state buttons, const char **suffix);
+
+/**
+ * Start or update the amimation of a throbber.
+ *
+ * \param *throbber The throbber to amimate.
+ */
+
+bool ro_gui_throbber_animate(struct throbber *throbber);
+
+
+/**
+ * Stop the amimation of a throbber.
+ *
+ * \param *throbber The throbber to amimate.
+ */
+
+bool ro_gui_throbber_stop(struct throbber *throbber);
+
+#endif
+
diff --git a/riscos/gui/url_bar.c b/riscos/gui/url_bar.c
new file mode 100644
index 000000000..df4e7c06c
--- /dev/null
+++ b/riscos/gui/url_bar.c
@@ -0,0 +1,984 @@
+/*
+ * Copyright 2004, 2005 Richard Wilson <info@tinct.net>
+ * Copyright 2011 Stephen Fryatt <stevef@netsurf-browser.org>
+ *
+ * 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
+ * URL bars (implementation).
+ */
+
+#include <alloca.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include "oslib/os.h"
+#include "oslib/osspriteop.h"
+#include "oslib/wimp.h"
+#include "riscos/gui/url_bar.h"
+#include "riscos/theme.h"
+#include "riscos/url_suggest.h"
+#include "riscos/wimp.h"
+#include "riscos/wimp_event.h"
+#include "utils/log.h"
+#include "utils/utils.h"
+
+#define URLBAR_HEIGHT 52
+#define URLBAR_FAVICON_WIDTH 52
+#define URLBAR_MIN_WIDTH 52
+#define URLBAR_GRIGHT_GUTTER 8
+#define URLBAR_FAVICON_NAME_LENGTH 12
+#define URLBAR_INITIAL_LENGTH 256
+#define URLBAR_EXTEND_LENGTH 128
+#define URLBAR_FAVICON_SIZE 16
+
+struct url_bar {
+ /** The applied theme (or NULL to use the default) */
+ struct theme_descriptor *theme;
+
+ /** The widget dimensions. */
+ int x_min, y_min;
+
+ /** The window and icon details. */
+ wimp_w window;
+ os_box extent;
+
+ wimp_i container_icon;
+
+ char favicon_sprite[URLBAR_FAVICON_NAME_LENGTH];
+ int favicon_type;
+ struct hlcache_handle *favicon_content;
+ os_box favicon_extent;
+ os_coord favicon_offset;
+ int favicon_width, favicon_height;
+
+ wimp_i text_icon;
+ char *text_buffer;
+ size_t text_size;
+
+ wimp_i suggest_icon;
+ int suggest_x, suggest_y;
+
+ bool hidden;
+ bool display;
+ bool shaded;
+};
+
+static char text_validation[] = "Pptr_write;KN";
+static char suggest_icon[] = "gright";
+static char suggest_validation[] = "R5;Sgright,pgright";
+static char null_text_string[] = "";
+
+
+/*
+ * Private function prototypes.
+ */
+
+static bool ro_gui_url_bar_icon_update(struct url_bar *url_bar);
+static bool ro_gui_url_bar_icon_resize(struct url_bar *url_bar, bool full);
+
+/* This is an exported interface documented in url_bar.h */
+
+struct url_bar *ro_gui_url_bar_create(struct theme_descriptor *theme)
+{
+ struct url_bar *url_bar;
+
+ /* Allocate memory. */
+
+ url_bar = malloc(sizeof(struct url_bar));
+ if (url_bar == NULL) {
+ LOG(("No memory for malloc()"));
+ return NULL;
+ }
+
+ /* Set up default parameters. */
+
+ url_bar->theme = theme;
+
+ url_bar->display = false;
+ url_bar->shaded = false;
+
+ url_bar->x_min = URLBAR_FAVICON_WIDTH + URLBAR_MIN_WIDTH;
+ url_bar->y_min = URLBAR_HEIGHT;
+
+ url_bar->extent.x0 = 0;
+ url_bar->extent.y0 = 0;
+ url_bar->extent.x1 = 0;
+ url_bar->extent.y1 = 0;
+
+ url_bar->window = NULL;
+ url_bar->container_icon = -1;
+ url_bar->text_icon = -1;
+ url_bar->suggest_icon = -1;
+
+ url_bar->favicon_extent.x0 = 0;
+ url_bar->favicon_extent.y0 = 0;
+ url_bar->favicon_extent.x1 = 0;
+ url_bar->favicon_extent.y1 = 0;
+ url_bar->favicon_width = 0;
+ url_bar->favicon_height = 0;
+ url_bar->favicon_content = NULL;
+ url_bar->favicon_type = 0;
+ strncpy(url_bar->favicon_sprite, "Ssmall_xxx",
+ URLBAR_FAVICON_NAME_LENGTH);
+
+ url_bar->text_size = URLBAR_INITIAL_LENGTH;
+ url_bar->text_buffer = malloc(url_bar->text_size);
+ strncpy(url_bar->text_buffer, "", url_bar->text_size);
+
+ url_bar->hidden = false;
+
+ return url_bar;
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_rebuild(struct url_bar *url_bar,
+ struct theme_descriptor *theme, theme_style style,
+ wimp_w window, bool display, bool shaded)
+{
+ if (url_bar == NULL)
+ return false;
+
+ url_bar->theme = theme;
+ url_bar->window = window;
+
+ url_bar->display = display;
+ url_bar->shaded = shaded;
+
+ url_bar->container_icon = -1;
+ url_bar->text_icon = -1;
+ url_bar->suggest_icon = -1;
+
+ ro_gui_wimp_get_sprite_dimensions((osspriteop_area *) -1,
+ suggest_icon, &url_bar->suggest_x, &url_bar->suggest_y);
+
+ url_bar->x_min = URLBAR_FAVICON_WIDTH + URLBAR_MIN_WIDTH +
+ URLBAR_GRIGHT_GUTTER + url_bar->suggest_x;
+ url_bar->y_min = (url_bar->suggest_y > URLBAR_HEIGHT) ?
+ url_bar->suggest_y : URLBAR_HEIGHT;
+
+ return ro_gui_url_bar_icon_update(url_bar);
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+void ro_gui_url_bar_destroy(struct url_bar *url_bar)
+{
+ if (url_bar == NULL)
+ return;
+
+ free(url_bar);
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_get_dims(struct url_bar *url_bar,
+ int *width, int *height)
+{
+ if (url_bar == NULL)
+ return false;
+
+ if (url_bar->x_min != -1 && url_bar->y_min != -1) {
+ if (width != NULL)
+ *width = url_bar->x_min;
+ if (height != NULL)
+ *height = url_bar->y_min;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_set_extent(struct url_bar *url_bar,
+ int x0, int y0, int x1, int y1)
+{
+ bool stretch;
+
+ if (url_bar == NULL)
+ return false;
+
+ if ((x1 - x0) < url_bar->x_min || (y1 - y0) < url_bar->y_min)
+ return false;
+
+ if (url_bar->extent.x0 == x0 && url_bar->extent.y0 == y0 &&
+ url_bar->extent.x1 == x1 &&
+ url_bar->extent.y1 == y1)
+ return true;
+
+ /* If it's only the length that changes, less needs to be updated. */
+
+ stretch = (url_bar->extent.x0 == x0 && url_bar->extent.y0 == y0 &&
+ url_bar->extent.y1 == y1) ? true : false;
+
+ /* Redraw the relevant bits of the toolbar. */
+
+ if (url_bar->window != NULL && url_bar->container_icon != -1) {
+ xwimp_force_redraw(url_bar->window,
+ url_bar->extent.x0 +
+ (stretch) ? URLBAR_FAVICON_WIDTH : 0,
+ url_bar->extent.y0,
+ url_bar->extent.x1, url_bar->extent.y1);
+ xwimp_force_redraw(url_bar->window,
+ x0 + (stretch) ? URLBAR_FAVICON_WIDTH : 0,
+ y0, x1, y1);
+ }
+
+ /* Reposition the URL bar icons. */
+
+ url_bar->extent.x0 = x0;
+ url_bar->extent.y0 = y0;
+ url_bar->extent.x1 = x1;
+ url_bar->extent.y1 = y1;
+
+ return ro_gui_url_bar_icon_resize(url_bar, !stretch);
+}
+
+
+/**
+ * Create or delete a URL bar's icons if required to bring it into sync with
+ * the current hidden setting.
+ *
+ * \param *url_bar The URL bar to update.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_url_bar_icon_update(struct url_bar *url_bar)
+{
+ wimp_icon_create icon;
+ os_error *error;
+ bool resize;
+
+ if (url_bar == NULL || url_bar->window == NULL)
+ return false;
+
+ icon.w = url_bar->window;
+ icon.icon.extent.x0 = 0;
+ icon.icon.extent.y0 = 0;
+ icon.icon.extent.x1 = 0;
+ icon.icon.extent.y1 = 0;
+
+ resize = false;
+
+ /* Create or delete the container icon. */
+
+ if (!url_bar->hidden && url_bar->container_icon == -1) {
+ icon.icon.flags = wimp_ICON_BORDER |
+ (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT);
+ error = xwimp_create_icon(&icon, &url_bar->container_icon);
+ if (error != NULL) {
+ LOG(("xwimp_create_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ url_bar->container_icon = -1;
+ return false;
+ }
+
+ resize = true;
+ } else if (url_bar->hidden && url_bar->container_icon != -1){
+ error = xwimp_delete_icon(url_bar->window,
+ url_bar->container_icon);
+ if (error != NULL) {
+ LOG(("xwimp_delete_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return false;
+ }
+
+ url_bar->container_icon = -1;
+ }
+
+ /* Create or delete the text icon. */
+
+ if (!url_bar->hidden && url_bar->text_icon == -1) {
+ icon.icon.data.indirected_text.text = url_bar->text_buffer;
+ icon.icon.data.indirected_text.validation = text_validation;
+ icon.icon.data.indirected_text.size = url_bar->text_size;
+ icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED |
+ wimp_ICON_VCENTRED | wimp_ICON_FILLED |
+ (wimp_COLOUR_BLACK <<
+ wimp_ICON_FG_COLOUR_SHIFT);
+ if (url_bar->display)
+ icon.icon.flags |= (wimp_BUTTON_NEVER <<
+ wimp_ICON_BUTTON_TYPE_SHIFT);
+ else
+ icon.icon.flags |= (wimp_BUTTON_WRITE_CLICK_DRAG <<
+ wimp_ICON_BUTTON_TYPE_SHIFT);
+ error = xwimp_create_icon(&icon, &url_bar->text_icon);
+ if (error) {
+ LOG(("xwimp_create_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ url_bar->text_icon = -1;
+ return false;
+ }
+
+ resize = true;
+ } else if (url_bar->hidden && url_bar->text_icon != -1) {
+ error = xwimp_delete_icon(url_bar->window,
+ url_bar->text_icon);
+ if (error != NULL) {
+ LOG(("xwimp_delete_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return false;
+ }
+
+ url_bar->text_icon = -1;
+ }
+
+ /* Create or delete the suggest icon. */
+
+ if (!url_bar->hidden && url_bar->suggest_icon == -1) {
+ icon.icon.data.indirected_text.text = null_text_string;
+ icon.icon.data.indirected_text.size = 1;
+ icon.icon.data.indirected_text.validation = suggest_validation;
+ icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE |
+ wimp_ICON_INDIRECTED | wimp_ICON_HCENTRED |
+ wimp_ICON_VCENTRED | (wimp_BUTTON_CLICK <<
+ wimp_ICON_BUTTON_TYPE_SHIFT);
+ error = xwimp_create_icon(&icon, &url_bar->suggest_icon);
+ if (error) {
+ LOG(("xwimp_create_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return false;
+ }
+
+ if (!url_bar->display)
+ ro_gui_wimp_event_register_menu_gright(url_bar->window,
+ wimp_ICON_WINDOW, url_bar->suggest_icon,
+ ro_gui_url_suggest_menu);
+
+ if (!ro_gui_url_bar_update_urlsuggest(url_bar))
+ return false;
+
+ resize = true;
+ } else if (url_bar->hidden && url_bar->suggest_icon != -1) {
+ ro_gui_wimp_event_deregister(url_bar->window,
+ url_bar->suggest_icon);
+ error = xwimp_delete_icon(url_bar->window,
+ url_bar->suggest_icon);
+ if (error != NULL) {
+ LOG(("xwimp_delete_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return false;
+ }
+
+ url_bar->suggest_icon = -1;
+ }
+
+ /* If any icons were created, resize the bar. */
+
+ if (resize && !ro_gui_url_bar_icon_resize(url_bar, true))
+ return false;
+
+ /* If there are any icons, apply shading as necessary. */
+
+ if (url_bar->container_icon != -1)
+ ro_gui_set_icon_shaded_state(url_bar->window,
+ url_bar->container_icon, url_bar->shaded);
+
+ if (url_bar->text_icon != -1)
+ ro_gui_set_icon_shaded_state(url_bar->window,
+ url_bar->text_icon, url_bar->shaded);
+
+ if (url_bar->suggest_icon != -1)
+ ro_gui_set_icon_shaded_state(url_bar->window,
+ url_bar->suggest_icon, url_bar->shaded);
+
+ return true;
+}
+
+
+/**
+ * Position the icons in the URL bar to take account of the currently
+ * configured extent.
+ *
+ * \param *url_bar The URL bar to update.
+ * \param full true to resize everything; false to move only
+ * the right-hand end of the bar.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_url_bar_icon_resize(struct url_bar *url_bar, bool full)
+{
+ int x0, y0, x1, y1;
+ int centre;
+ os_error *error;
+ os_coord eig = {1, 1};
+ wimp_caret caret;
+
+ if (url_bar == NULL || url_bar->window == NULL)
+ return false;
+
+ /* calculate 1px in OS units */
+ ro_convert_pixels_to_os_units(&eig, (os_mode) -1);
+
+ /* The vertical centre line of the widget's extent. */
+
+ centre = url_bar->extent.y0 +
+ (url_bar->extent.y1 - url_bar->extent.y0) / 2;
+
+ /* Position the container icon. */
+
+ if (url_bar->container_icon != -1) {
+ x0 = url_bar->extent.x0;
+ x1 = url_bar->extent.x1 -
+ url_bar->suggest_x - URLBAR_GRIGHT_GUTTER;
+
+ y0 = centre - (URLBAR_HEIGHT / 2);
+ y1 = y0 + URLBAR_HEIGHT;
+
+ error = xwimp_resize_icon(url_bar->window,
+ url_bar->container_icon,
+ x0, y0, x1, y1);
+ if (error != NULL) {
+ LOG(("xwimp_resize_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ url_bar->container_icon = -1;
+ return false;
+ }
+ }
+
+ /* Position the URL Suggest icon. */
+
+ if (url_bar->suggest_icon != -1) {
+ x0 = url_bar->extent.x1 - url_bar->suggest_x;
+ x1 = url_bar->extent.x1;
+
+ y0 = centre - (url_bar->suggest_y / 2);
+ y1 = y0 + url_bar->suggest_y;
+
+ error = xwimp_resize_icon(url_bar->window,
+ url_bar->suggest_icon,
+ x0, y0, x1, y1);
+ if (error != NULL) {
+ LOG(("xwimp_resize_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ url_bar->suggest_icon = -1;
+ return false;
+ }
+ }
+
+ /* Position the Text icon. */
+
+ if (url_bar->text_icon != -1) {
+ x0 = url_bar->extent.x0 + URLBAR_FAVICON_WIDTH;
+ x1 = url_bar->extent.x1 - eig.x -
+ url_bar->suggest_x - URLBAR_GRIGHT_GUTTER;
+
+ y0 = centre - (URLBAR_HEIGHT / 2) + eig.y;
+ y1 = y0 + URLBAR_HEIGHT - 2 * eig.y;
+
+ error = xwimp_resize_icon(url_bar->window,
+ url_bar->text_icon,
+ x0, y0, x1, y1);
+ if (error != NULL) {
+ LOG(("xwimp_resize_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ url_bar->text_icon = -1;
+ return false;
+ }
+
+ if (xwimp_get_caret_position(&caret) == NULL) {
+ if ((caret.w == url_bar->window) &&
+ (caret.i == url_bar->text_icon)) {
+ xwimp_set_caret_position(url_bar->window,
+ url_bar->text_icon, caret.pos.x,
+ caret.pos.y, -1, caret.index);
+ }
+ }
+ }
+
+ /* Position the Favicon icon. */
+
+ url_bar->favicon_extent.x0 = url_bar->extent.x0 + eig.x;
+ url_bar->favicon_extent.x1 = url_bar->extent.x0 + URLBAR_FAVICON_WIDTH;
+ url_bar->favicon_extent.y0 = centre - (URLBAR_HEIGHT / 2) + eig.y;
+ url_bar->favicon_extent.y1 = url_bar->favicon_extent.y0 + URLBAR_HEIGHT
+ - 2 * eig.y;
+
+ return true;
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_hide(struct url_bar *url_bar, bool hide)
+{
+ if (url_bar == NULL || url_bar->hidden == hide)
+ return (url_bar == NULL) ? false : true;
+
+ url_bar->hidden = hide;
+
+ return ro_gui_url_bar_icon_update(url_bar);
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+void ro_gui_url_bar_redraw(struct url_bar *url_bar, wimp_draw *redraw)
+{
+ wimp_icon icon;
+ struct rect clip;
+
+ /* Test for a valid URL bar, and then check that the redraw box
+ * coincides with the bar's favicon extent.
+ */
+
+ if (url_bar == NULL || url_bar->hidden ||
+ (redraw->clip.x0 - (redraw->box.x0 - redraw->xscroll))
+ > (url_bar->favicon_extent.x1) ||
+ (redraw->clip.y0 - (redraw->box.y1 - redraw->yscroll))
+ > url_bar->favicon_extent.y1 ||
+ (redraw->clip.x1 - (redraw->box.x0 - redraw->xscroll))
+ < url_bar->favicon_extent.x0 ||
+ (redraw->clip.y1 - (redraw->box.y1 - redraw->yscroll))
+ < url_bar->favicon_extent.y0)
+ return;
+
+ if (url_bar->favicon_content == NULL) {
+ icon.data.indirected_text.text = null_text_string;
+ icon.data.indirected_text.validation = url_bar->favicon_sprite;
+ icon.data.indirected_text.size = 1;
+ icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE |
+ wimp_ICON_INDIRECTED | wimp_ICON_FILLED |
+ wimp_ICON_HCENTRED | wimp_ICON_VCENTRED;
+ icon.extent.x0 = url_bar->favicon_extent.x0;
+ icon.extent.x1 = url_bar->favicon_extent.x1;
+ icon.extent.y0 = url_bar->favicon_extent.y0;
+ icon.extent.y1 = url_bar->favicon_extent.y1;
+
+ xwimp_plot_icon(&icon);
+ } else {
+ xwimp_set_colour(wimp_COLOUR_WHITE);
+ xos_plot(os_MOVE_TO,
+ (redraw->box.x0 - redraw->xscroll) +
+ url_bar->favicon_extent.x0,
+ (redraw->box.y1 - redraw->yscroll) +
+ url_bar->favicon_extent.y0);
+ xos_plot(os_PLOT_TO | os_PLOT_RECTANGLE,
+ (redraw->box.x0 - redraw->xscroll) +
+ url_bar->favicon_extent.x1,
+ (redraw->box.y1 - redraw->yscroll) +
+ url_bar->favicon_extent.y1);
+
+ clip.x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2;
+ clip.y0 = (ro_plot_origin_y - redraw->clip.y0) / 2;
+ clip.x1 = (redraw->clip.x1 - ro_plot_origin_x) / 2;
+ clip.y1 = (ro_plot_origin_y - redraw->clip.y1) / 2;
+
+ content_redraw(url_bar->favicon_content,
+ (url_bar->favicon_extent.x0 +
+ url_bar->favicon_offset.x) / 2,
+ (url_bar->favicon_offset.y -
+ url_bar->favicon_extent.y1) / 2,
+ url_bar->favicon_width, url_bar->favicon_height,
+ &clip, 1, 0);
+ }
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_click(struct url_bar *url_bar,
+ wimp_pointer *pointer, wimp_window_state *state,
+ url_bar_action *action)
+{
+ os_coord pos;
+
+ if (url_bar == NULL || url_bar->hidden ||
+ url_bar->display || url_bar->shaded)
+ return false;
+
+ /* Check that the click was within our part of the window. */
+
+ pos.x = pointer->pos.x - state->visible.x0 + state->xscroll;
+ pos.y = pointer->pos.y - state->visible.y1 + state->yscroll;
+
+ if (pos.x < url_bar->extent.x0 || pos.x > url_bar->extent.x1 ||
+ pos.y < url_bar->extent.y0 ||
+ pos.y > url_bar->extent.y1)
+ return false;
+
+ /* If we find a Select or Adjust drag, check if it originated on the
+ * URL bar or over the favicon. If either, then return an event.
+ */
+
+ if (pointer->buttons == wimp_DRAG_SELECT ||
+ pointer->buttons == wimp_DRAG_ADJUST) {
+ if (pointer->i == url_bar->text_icon) {
+ if (action != NULL)
+ *action = TOOLBAR_URL_DRAG_URL;
+ return true;
+ }
+
+ if (pos.x >= url_bar->favicon_extent.x0 &&
+ pos.x <= url_bar->favicon_extent.x1 &&
+ pos.y >= url_bar->favicon_extent.y0 &&
+ pos.y <=url_bar->favicon_extent.y1) {
+ if (action != NULL)
+ *action = TOOLBAR_URL_DRAG_FAVICON;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_menu_prepare(struct url_bar *url_bar, wimp_i i,
+ wimp_menu *menu, wimp_pointer *pointer)
+{
+ if (url_bar == NULL || url_bar->suggest_icon != i ||
+ menu != ro_gui_url_suggest_menu)
+ return false;
+
+ if (pointer != NULL)
+ return ro_gui_url_suggest_prepare_menu();
+
+ return true;
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_menu_select(struct url_bar *url_bar, wimp_i i,
+ wimp_menu *menu, wimp_selection *selection, menu_action action)
+{
+ const char *url;
+ struct gui_window *g;
+
+ if (url_bar == NULL || url_bar->suggest_icon != i ||
+ menu != ro_gui_url_suggest_menu)
+ return false;
+
+ url = ro_gui_url_suggest_get_selection(selection);
+ g = ro_gui_toolbar_lookup(url_bar->window);
+
+ if (url != NULL && g != NULL && g->bw != NULL) {
+ gui_window_set_url(g, url);
+ browser_window_go(g->bw, url, 0, true);
+ }
+
+ return true;
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_help_suffix(struct url_bar *url_bar, wimp_i i,
+ os_coord *mouse, wimp_window_state *state,
+ wimp_mouse_state buttons, const char **suffix)
+{
+ os_coord pos;
+
+ if (url_bar == NULL || url_bar->hidden)
+ return false;
+
+ /* Check that the click was within our part of the window. */
+
+ pos.x = mouse->x - state->visible.x0 + state->xscroll;
+ pos.y = mouse->y - state->visible.y1 + state->yscroll;
+
+ if (pos.x < url_bar->extent.x0 || pos.x > url_bar->extent.x1 ||
+ pos.y < url_bar->extent.y0 ||
+ pos.y > url_bar->extent.y1)
+ return false;
+
+ /* Return hard-coded icon numbers that match the ones that were
+ * always allocated to the URL bar in a previous implementation.
+ * If Messages can be updated, this could be changed.
+ */
+
+ if (i == url_bar->text_icon)
+ *suffix = "14";
+ else if (i == url_bar->suggest_icon)
+ *suffix = "15";
+ else
+ *suffix = "";
+
+ return true;
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_take_caret(struct url_bar *url_bar)
+{
+ os_error *error;
+
+ if (url_bar == NULL || url_bar->hidden)
+ return false;
+
+ error = xwimp_set_caret_position(url_bar->window, url_bar->text_icon,
+ -1, -1, -1, 0);
+ if (error) {
+ LOG(("xwimp_set_caret_position: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+
+ return false;
+ }
+
+ return true;
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+void ro_gui_url_bar_set_url(struct url_bar *url_bar, const char *url,
+ bool is_utf8, bool set_caret)
+{
+ wimp_caret caret;
+ os_error *error;
+ const char *set_url;
+
+ if (url_bar == NULL || url_bar->text_buffer == NULL)
+ return;
+
+ if (url_bar->text_icon == -1) {
+ strncpy(url_bar->text_buffer, url, url_bar->text_size);
+ return;
+ }
+
+ ro_gui_set_icon_string(url_bar->window, url_bar->text_icon,
+ url, is_utf8);
+
+ error = xwimp_get_caret_position(&caret);
+ if (error) {
+ LOG(("xwimp_get_caret_position: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return;
+ }
+
+ if (set_caret || (caret.w == url_bar->window &&
+ caret.i == url_bar->text_icon)) {
+ set_url = ro_gui_get_icon_string(url_bar->window,
+ url_bar->text_icon);
+
+ error = xwimp_set_caret_position(url_bar->window,
+ url_bar->text_icon, 0, 0, -1, strlen(set_url));
+ if (error) {
+ LOG(("xwimp_set_caret_position: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+ }
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+const char *ro_gui_url_bar_get_url(struct url_bar *url_bar)
+{
+ if (url_bar == NULL)
+ return NULL;
+
+ return (const char *) url_bar->text_buffer;
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_get_url_extent(struct url_bar *url_bar, os_box *extent)
+{
+ wimp_icon_state state;
+ os_error *error;
+
+ if (url_bar == NULL || url_bar->hidden)
+ return false;
+
+ if (extent == NULL)
+ return true;
+
+ state.w = url_bar->window;
+ state.i = url_bar->container_icon;
+ error = xwimp_get_icon_state(&state);
+ if (error) {
+ LOG(("xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return false;
+ }
+
+ extent->x0 = state.icon.extent.x0;
+ extent->y0 = state.icon.extent.y0;
+ extent->x1 = state.icon.extent.x1;
+ extent->y1 = state.icon.extent.y1;
+
+ return true;
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_test_for_text_field_click(struct url_bar *url_bar,
+ wimp_pointer *pointer)
+{
+ if (url_bar == NULL || url_bar->hidden || pointer == NULL)
+ return false;
+
+ return (pointer->w == url_bar->window &&
+ pointer->i == url_bar->text_icon) ? true : false;
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_test_for_text_field_keypress(struct url_bar *url_bar,
+ wimp_key *key)
+{
+ if (url_bar == NULL || url_bar->hidden || key == NULL)
+ return false;
+
+ return (key->w == url_bar->window &&
+ key->i == url_bar->text_icon) ? true : false;
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_set_site_favicon(struct url_bar *url_bar,
+ struct hlcache_handle *h)
+{
+ content_type type = CONTENT_OTHER;
+
+ if (url_bar == NULL)
+ return false;
+
+ if (h != NULL)
+ type = content_get_type(h);
+
+ // \TODO -- Maybe test for CONTENT_ICO ???
+
+ if (type != CONTENT_OTHER && type != CONTENT_UNKNOWN) {
+ url_bar->favicon_content = h;
+ url_bar->favicon_width = content_get_width(h);
+ url_bar->favicon_height = content_get_height(h);
+
+ if (url_bar->favicon_width > URLBAR_FAVICON_SIZE)
+ url_bar->favicon_width = URLBAR_FAVICON_SIZE;
+
+ if (url_bar->favicon_height > URLBAR_FAVICON_SIZE)
+ url_bar->favicon_height = URLBAR_FAVICON_SIZE;
+
+ url_bar->favicon_offset.x = ((url_bar->favicon_extent.x1 -
+ url_bar->favicon_extent.x0) -
+ (url_bar->favicon_width * 2)) / 2;
+ url_bar->favicon_offset.y = ((url_bar->favicon_extent.y1 -
+ url_bar->favicon_extent.y0) -
+ (url_bar->favicon_height * 2)) / 2;
+ } else {
+ url_bar->favicon_content = NULL;
+
+ if (url_bar->favicon_type != 0)
+ snprintf(url_bar->favicon_sprite,
+ URLBAR_FAVICON_NAME_LENGTH,
+ "Ssmall_%.3x", url_bar->favicon_type);
+ else
+ snprintf(url_bar->favicon_sprite,
+ URLBAR_FAVICON_NAME_LENGTH,
+ "Ssmall_xxx");
+ }
+
+ if (!url_bar->hidden)
+ xwimp_force_redraw(url_bar->window,
+ url_bar->favicon_extent.x0,
+ url_bar->favicon_extent.y0,
+ url_bar->favicon_extent.x1,
+ url_bar->favicon_extent.y1);
+
+ return true;
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_set_content_favicon(struct url_bar *url_bar,
+ struct hlcache_handle *h)
+{
+ int type = 0;
+ char sprite[URLBAR_FAVICON_NAME_LENGTH];
+
+ if (url_bar == NULL)
+ return false;
+
+ if (h != NULL)
+ type = ro_content_filetype_from_type(content_get_type(h));
+
+ if (type != 0) {
+ snprintf(sprite, URLBAR_FAVICON_NAME_LENGTH,
+ "small_%.3x", type);
+
+ if (!ro_gui_wimp_sprite_exists(sprite))
+ type = 0;
+ }
+
+ url_bar->favicon_type = type;
+
+ if (url_bar->favicon_content == NULL) {
+ if (type == 0)
+ snprintf(url_bar->favicon_sprite,
+ URLBAR_FAVICON_NAME_LENGTH, "Ssmall_xxx");
+ else
+ snprintf(url_bar->favicon_sprite,
+ URLBAR_FAVICON_NAME_LENGTH, "S%s", sprite);
+
+ if (!url_bar->hidden)
+ xwimp_force_redraw(url_bar->window,
+ url_bar->favicon_extent.x0,
+ url_bar->favicon_extent.y0,
+ url_bar->favicon_extent.x1,
+ url_bar->favicon_extent.y1);
+ }
+
+ return true;
+}
+
+
+/* This is an exported interface documented in url_bar.h */
+
+bool ro_gui_url_bar_update_urlsuggest(struct url_bar *url_bar)
+{
+ if (url_bar == NULL || url_bar->hidden)
+ return (url_bar == NULL) ? false : true;
+
+ if (url_bar->window != NULL && url_bar->suggest_icon != -1)
+ ro_gui_set_icon_shaded_state(url_bar->window,
+ url_bar->suggest_icon,
+ !ro_gui_url_suggest_get_menu_available());
+
+ return true;
+}
+
diff --git a/riscos/gui/url_bar.h b/riscos/gui/url_bar.h
new file mode 100644
index 000000000..0f5c6bc14
--- /dev/null
+++ b/riscos/gui/url_bar.h
@@ -0,0 +1,302 @@
+/*
+ * Copyright 2005 Richard Wilson <info@tinct.net>
+ * Copyright 2011 Stephen Fryatt <stevef@netsurf-browser.org>
+ *
+ * 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
+ * URL bars (interface).
+ */
+
+#ifndef _NETSURF_RISCOS_URLBAR_H_
+#define _NETSURF_RISCOS_URLBAR_H_
+
+#include <stdbool.h>
+#include "riscos/menus.h"
+#include "riscos/theme.h"
+
+/* A list of possible URL bar actions. */
+
+typedef enum {
+ TOOLBAR_URL_NONE = 0, /* Special case: no action */
+ TOOLBAR_URL_DRAG_URL,
+ TOOLBAR_URL_DRAG_FAVICON,
+} url_bar_action;
+
+struct url_bar;
+
+/**
+ * Create a new url bar widget.
+ *
+ * \param *theme The theme to apply (or NULL for the default).
+ * \return A url bar handle, or NULL on failure.
+ */
+
+struct url_bar *ro_gui_url_bar_create(struct theme_descriptor *theme);
+
+
+/**
+ * Place a URL bar into a toolbar window and initialise any theme-specific
+ * settings. Any previous incarnation of the bar will be forgotten: this
+ * is for use when a new toolbar is being created, or when a toolbar has been
+ * deleted and rebuilt following a theme change.
+ *
+ * \param *url_bar The URL bar to rebuild.
+ * \param *theme The theme to apply (or NULL for current).
+ * \param style The theme style to apply.
+ * \param window The window that the bar is in.
+ * \param display true if the bar should be for display only.
+ * \param shaded true if the bar should be shaded; else false.
+ * \return true on success; else false.
+ */
+
+bool ro_gui_url_bar_rebuild(struct url_bar *url_bar,
+ struct theme_descriptor *theme, theme_style style,
+ wimp_w window, bool display, bool shaded);
+
+
+/**
+ * Destroy a url bar widget.
+ *
+ * \param *url_bar The url bar to destroy.
+ */
+
+void ro_gui_url_bar_destroy(struct url_bar *url_bar);
+
+
+/**
+ * Return the MINIMUM dimensions required by the URL bar, in RO units,
+ * allowing for the current theme.
+ *
+ * \param *url_bar The URL bar of interest.
+ * \param *width Return the required width.
+ * \param *height Return the required height.
+ * \return true if values are returned; else false.
+ */
+
+bool ro_gui_url_bar_get_dims(struct url_bar *url_bar,
+ int *width, int *height);
+
+
+/**
+ * Set or update the dimensions to be used by the URL bar, in RO units.
+ * If these are greater than the minimum required, the URL bar will fill
+ * the extended space; if less, the call will fail.
+ *
+ * \param *url_bar The URL bar to update.
+ * \param x0 The minimum X window position.
+ * \param y0 The minimum Y window position.
+ * \param x1 The maximum X window position.
+ * \param y1 The maximum Y window position.
+ * \return true if size updated; else false.
+ */
+
+bool ro_gui_url_bar_set_extent(struct url_bar *url_bar,
+ int x0, int y0, int x1, int y1);
+
+
+/**
+ * Show or hide a URL bar.
+ *
+ * \param *url_bar The URL bar to hide.
+ * \param hide true to hide the bar; false to show it.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_url_bar_hide(struct url_bar *url_bar, bool hide);
+
+
+/**
+ * Handle redraw event rectangles in a URL bat.
+ *
+ * \param *url_bar The URL bar to use.
+ * \param *redraw The Wimp redraw rectangle to process.
+ */
+
+void ro_gui_url_bar_redraw(struct url_bar *url_bar, wimp_draw *redraw);
+
+
+/**
+ * Handle mouse clicks in a URL bar.
+ *
+ * \param *url_bar The URL bar to use.
+ * \param *pointer The Wimp mouse click event data.
+ * \param *state The toolbar window state.
+ * \param *action Returns the selected action, or
+ * TOOLBAR_URL_NONE.
+ * \return true if the event was handled exclusively;
+ * else false.
+ */
+
+bool ro_gui_url_bar_click(struct url_bar *url_bar,
+ wimp_pointer *pointer, wimp_window_state *state,
+ url_bar_action *action);
+
+
+/**
+ * Process offered menu prepare events from the parent window.
+ *
+ * \param *url_bar The URL bar in question.
+ * \param i The icon owning the menu.
+ * \param *menu The menu to be prepared.
+ * \param *pointer The Wimp Pointer data from the event.
+ * \return true if the event is claimed; else false.
+ */
+
+bool ro_gui_url_bar_menu_prepare(struct url_bar *url_bar, wimp_i i,
+ wimp_menu *menu, wimp_pointer *pointer);
+
+
+/**
+ * Process offered menu select events from the parent window.
+ *
+ * \param *url_bar The URL bar in question.
+ * \param i The icon owning the menu.
+ * \param *menu The menu to be prepared.
+ * \param *selection The wimp menu selection data.
+ * \param action The selected menu action.
+ * \return true if the event is claimed; else false.
+ */
+
+bool ro_gui_url_bar_menu_select(struct url_bar *url_bar, wimp_i i,
+ wimp_menu *menu, wimp_selection *selection, menu_action action);
+
+
+/**
+ * Translate mouse data into an interactive help message for the URL bar.
+ *
+ * \param *url_bar The URL bar to process.
+ * \param i The wimp icon under the pointer.
+ * \param *mouse The mouse position.
+ * \param *state The toolbar window state.
+ * \param buttons The mouse button state.
+ * \param **suffix Return a help token suffix, or "" for none.
+ * \return true if handled exclusively; else false.
+ */
+
+bool ro_gui_url_bar_help_suffix(struct url_bar *url_bar, wimp_i i,
+ os_coord *mouse, wimp_window_state *state,
+ wimp_mouse_state buttons, const char **suffix);
+
+
+/**
+ * Give a URL bar input focus.
+ *
+ * \param *url_bar The URL bar to give focus to.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_url_bar_take_caret(struct url_bar *url_bar);
+
+
+/**
+ * Set the content of a URL Bar field.
+ *
+ * \param *url_bar The URL Bar to update.
+ * \param *url The new url to insert.
+ * \param is_utf8 true if the string is in utf8 encoding; false
+ * if it is in local encoding.
+ * \param set_caret true if the caret should be placed in the field;
+ * else false.
+ */
+
+void ro_gui_url_bar_set_url(struct url_bar *url_bar, const char *url,
+ bool is_utf8, bool set_caret);
+
+
+/**
+ * Return a pointer to the URL contained in a URL bar.
+ *
+ * \param *url_bar The URL Bar to look up the URL from.
+ * \return Pointer to the URL, or NULL.
+ */
+
+const char *ro_gui_url_bar_get_url(struct url_bar *url_bar);
+
+
+/**
+ * Return the current work area coordinates of the URL and favicon field's
+ * bounding box.
+ *
+ * \param *url_bar The URL bar to check.
+ * \param *extent Returns the field extent.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_url_bar_get_url_extent(struct url_bar *url_bar, os_box *extent);
+
+
+/**
+ * Test a pointer click to see if it was in the URL bar's text field.
+ *
+ * \param *url_bar The URL Bar to test.
+ * \param *pointer The pointer event data to test.
+ * \return true if the click was in the field; else false.
+ */
+
+bool ro_gui_url_bar_test_for_text_field_click(struct url_bar *url_bar,
+ wimp_pointer *pointer);
+
+
+/**
+ * Test a keypress to see if it was in the URL bar's text field.
+ *
+ * \param *url_bar The URL Bar to test.
+ * \param *pointer The pointer event data to test.
+ * \return true if the click was in the field; else false.
+ */
+
+bool ro_gui_url_bar_test_for_text_field_keypress(struct url_bar *url_bar,
+ wimp_key *key);
+
+
+/**
+ * Set the favicon to a site supplied favicon image, or remove the image
+ * and return to using filetype-based icons.
+ *
+ * \param *url_bar The URL Bar to update the favicon on.
+ * \param *h The content to use, or NULL to unset.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_url_bar_set_site_favicon(struct url_bar *url_bar,
+ struct hlcache_handle *h);
+
+
+/**
+ * Set the favicon to a RISC OS filetype sprite based on the type of the
+ * supplied content.
+ *
+ * \param *url_bar The URL Bar to update the favicon on.
+ * \param *h The content to use.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_url_bar_set_content_favicon(struct url_bar *url_bar,
+ struct hlcache_handle *h);
+
+
+/**
+ * Update the state of the URL suggestion pop-up menu icon on a URL bar.
+ *
+ * \param *url_bar The URL bar to update.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_url_bar_update_urlsuggest(struct url_bar *url_bar);
+
+#endif
+
diff --git a/riscos/help.c b/riscos/help.c
index 968fcb7c4..6a71fb1ec 100644
--- a/riscos/help.c
+++ b/riscos/help.c
@@ -33,12 +33,13 @@
#include "riscos/gui.h"
#include "riscos/hotlist.h"
#include "riscos/help.h"
+#include "riscos/iconbar.h"
#include "riscos/menus.h"
#include "riscos/options.h"
-#include "riscos/theme.h"
#include "riscos/treeview.h"
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
+#include "riscos/window.h"
#include "utils/messages.h"
#include "utils/log.h"
#include "utils/utf8.h"
@@ -91,18 +92,18 @@ static os_t help_time = 0;
*/
void ro_gui_interactive_help_request(wimp_message *message)
{
- char message_token[32];
- char menu_buffer[4];
- wimp_selection menu_tree;
- help_full_message_request *message_data;
- wimp_w window;
- wimp_i icon;
- unsigned int index;
- bool greyed = false;
- wimp_menu *test_menu;
- os_error *error;
- const char *auto_text;
- int i;
+ char message_token[32];
+ char menu_buffer[4];
+ wimp_selection menu_tree;
+ help_full_message_request *message_data;
+ wimp_w window;
+ wimp_i icon;
+ unsigned int index;
+ bool greyed = false;
+ wimp_menu *test_menu;
+ os_error *error;
+ const char *auto_text, *auto_suffix;
+ int i;
/* check we aren't turned off */
if (!option_interactive_help)
@@ -123,9 +124,15 @@ void ro_gui_interactive_help_request(wimp_message *message)
/* do the basic window checks */
auto_text = ro_gui_wimp_event_get_help_prefix(window);
- if (auto_text)
- sprintf(message_token, "%s%i", auto_text, (int)icon);
- else if (window == wimp_ICON_BAR)
+ if (auto_text != NULL) {
+ auto_suffix = ro_gui_wimp_event_get_help_suffix(window, icon,
+ &message_data->pos, message_data->buttons);
+
+ if (auto_suffix == NULL)
+ sprintf(message_token, "%s%i", auto_text, (int)icon);
+ else
+ sprintf(message_token, "%s%s", auto_text, auto_suffix);
+ } else if (window == wimp_ICON_BAR)
sprintf(message_token, "HelpIconbar");
else if (ro_gui_hotlist_check_window(message->data.data_xfer.w)) {
i = ro_treeview_get_help(message_data);
@@ -171,9 +178,9 @@ void ro_gui_interactive_help_request(wimp_message *message)
return;
/* get the menu prefix */
- if (current_menu == iconbar_menu)
+ if (ro_gui_iconbar_check_menu(current_menu))
sprintf(message_token, "HelpIconMenu");
- else if (current_menu == browser_menu)
+ else if (ro_gui_window_check_menu(current_menu))
sprintf(message_token, "HelpBrowserMenu");
else if (ro_gui_hotlist_check_menu(current_menu))
sprintf(message_token, "HelpHotlistMenu");
diff --git a/riscos/hotlist.c b/riscos/hotlist.c
index 42976b893..3bb2c59e7 100644
--- a/riscos/hotlist.c
+++ b/riscos/hotlist.c
@@ -39,7 +39,7 @@
#include "riscos/menus.h"
#include "riscos/options.h"
#include "riscos/save.h"
-#include "riscos/theme.h"
+#include "riscos/toolbar.h"
#include "riscos/treeview.h"
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
@@ -48,6 +48,22 @@
#include "utils/utils.h"
#include "utils/url.h"
+static void ro_gui_hotlist_toolbar_update_buttons(void);
+static void ro_gui_hotlist_toolbar_save_buttons(char *config);
+static bool ro_gui_hotlist_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer);
+static void ro_gui_hotlist_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action);
+static bool ro_gui_hotlist_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action);
+static void ro_gui_hotlist_toolbar_click(button_bar_action action);
+
+struct ro_treeview_callbacks ro_hotlist_treeview_callbacks = {
+ ro_gui_hotlist_toolbar_click,
+ ro_gui_hotlist_toolbar_update_buttons,
+ ro_gui_hotlist_toolbar_save_buttons
+};
+
/* The RISC OS hotlist window, toolbar and treeview data. */
static struct ro_hotlist {
@@ -79,21 +95,30 @@ void ro_gui_hotlist_postinitialise(void)
{
/* Create our toolbar. */
- hotlist_window.toolbar = ro_gui_theme_create_toolbar(NULL,
- THEME_HOTLIST_TOOLBAR);
- if (hotlist_window.toolbar)
- ro_gui_theme_attach_toolbar(hotlist_window.toolbar,
- hotlist_window.window);
+ hotlist_window.toolbar = ro_toolbar_create(NULL, hotlist_window.window,
+ THEME_STYLE_HOTLIST_TOOLBAR, TOOLBAR_FLAGS_NONE,
+ ro_treeview_get_toolbar_callbacks(), NULL,
+ "HelpHotToolbar");
+ if (hotlist_window.toolbar != NULL) {
+ ro_toolbar_add_buttons(hotlist_window.toolbar,
+ hotlist_toolbar_buttons,
+ option_toolbar_hotlist);
+ ro_toolbar_rebuild(hotlist_window.toolbar);
+ }
/* Create the treeview with the window and toolbar. */
hotlist_window.tv = ro_treeview_create(hotlist_window.window,
- hotlist_window.toolbar, hotlist_get_tree_flags());
+ hotlist_window.toolbar, &ro_hotlist_treeview_callbacks,
+ hotlist_get_tree_flags());
if (hotlist_window.tv == NULL) {
LOG(("Failed to allocate treeview"));
return;
}
+ ro_toolbar_update_client_data(hotlist_window.toolbar,
+ hotlist_window.tv);
+
/* Initialise the hotlist into the tree. */
hotlist_initialise(ro_treeview_get_tree(hotlist_window.tv),
@@ -133,10 +158,14 @@ void ro_gui_hotlist_postinitialise(void)
hotlist_window.menu = ro_gui_menu_define_menu(&hotlist_definition);
- ro_gui_wimp_event_register_window_menu(hotlist_window.window,
- hotlist_window.menu, ro_gui_hotlist_menu_prepare,
- ro_gui_hotlist_menu_select, NULL,
- ro_gui_hotlist_menu_warning, false);
+ ro_gui_wimp_event_register_menu(hotlist_window.window,
+ hotlist_window.menu, false, false);
+ ro_gui_wimp_event_register_menu_prepare(hotlist_window.window,
+ ro_gui_hotlist_menu_prepare);
+ ro_gui_wimp_event_register_menu_selection(hotlist_window.window,
+ ro_gui_hotlist_menu_select);
+ ro_gui_wimp_event_register_menu_warning(hotlist_window.window,
+ ro_gui_hotlist_menu_warning);
}
@@ -149,82 +178,86 @@ void ro_gui_hotlist_open(void)
{
tree_set_redraw(ro_treeview_get_tree(hotlist_window.tv), true);
+ ro_gui_hotlist_toolbar_update_buttons();
+
if (!ro_gui_dialog_open_top(hotlist_window.window,
hotlist_window.toolbar, 600, 800)) {
-
- xwimp_set_caret_position(hotlist_window.window, -1, -100, -100, 32, -1);
-// \todo ro_gui_theme_process_toolbar(hotlist_window.toolbar, -1);
ro_treeview_set_origin(hotlist_window.tv, 0,
- -(ro_gui_theme_toolbar_height(
- hotlist_window.toolbar)));
-// ro_gui_tree_stop_edit(tree);
-//
-// if (tree->root->child) {
-// tree_set_node_selected(tree, tree->root, false);
-// tree_handle_node_changed(tree, tree->root,
-// false, true);
-// }
+ -(ro_toolbar_height(hotlist_window.toolbar)));
}
}
/**
- * Handle Mouse Click events on the toolbar.
+ * Handle toolbar button clicks.
*
- * \param *pointer Pointer to the Mouse Click Event block.
- * \return Return true if click handled; else false.
+ * \param action The action to handle
*/
-bool ro_gui_hotlist_toolbar_click(wimp_pointer *pointer)
+void ro_gui_hotlist_toolbar_click(button_bar_action action)
{
- if (pointer->buttons == wimp_CLICK_MENU)
- return ro_gui_wimp_event_process_window_menu_click(pointer);
+ switch (action) {
+ case TOOLBAR_BUTTON_DELETE:
+ hotlist_delete_selected();
+ break;
- if (hotlist_window.toolbar->editor != NULL) {
- ro_gui_theme_toolbar_editor_click(hotlist_window.toolbar,
- pointer);
- return true;
- }
+ case TOOLBAR_BUTTON_EXPAND:
+ hotlist_expand_addresses();
+ break;
- switch (pointer->i) {
- case ICON_TOOLBAR_DELETE:
- if (pointer->buttons == wimp_CLICK_SELECT) {
- hotlist_delete_selected();
- return true;
- }
+ case TOOLBAR_BUTTON_COLLAPSE:
+ hotlist_collapse_addresses();
break;
- case ICON_TOOLBAR_EXPAND:
- if (pointer->buttons == wimp_CLICK_SELECT) {
- hotlist_expand_addresses();
- return true;
- } else if (pointer->buttons == wimp_CLICK_ADJUST) {
- hotlist_collapse_addresses();
- return true;
- }
+
+ case TOOLBAR_BUTTON_OPEN:
+ hotlist_expand_directories();
break;
- case ICON_TOOLBAR_OPEN:
- if (pointer->buttons == wimp_CLICK_SELECT) {
- hotlist_expand_directories();
- return true;
- } else if (pointer->buttons == wimp_CLICK_ADJUST) {
- hotlist_collapse_directories();
- return true;
- }
+
+ case TOOLBAR_BUTTON_CLOSE:
+ hotlist_collapse_directories();
break;
- case ICON_TOOLBAR_LAUNCH:
- if (pointer->buttons == wimp_CLICK_SELECT) {
- hotlist_launch_selected();
- return true;
- }
+
+ case TOOLBAR_BUTTON_LAUNCH:
+ hotlist_launch_selected();
break;
- case ICON_TOOLBAR_CREATE:
- if (pointer->buttons == wimp_CLICK_SELECT) {
- hotlist_add_folder();
- return true;
- }
+
+ case TOOLBAR_BUTTON_CREATE:
+ hotlist_add_folder();
+ break;
+
+ default:
break;
}
+}
- return true;
+
+/**
+ * Update the button state in the hotlist toolbar.
+ */
+
+void ro_gui_hotlist_toolbar_update_buttons(void)
+{
+ ro_toolbar_set_button_shaded_state(hotlist_window.toolbar,
+ TOOLBAR_BUTTON_DELETE,
+ !ro_treeview_has_selection(hotlist_window.tv));
+
+ ro_toolbar_set_button_shaded_state(hotlist_window.toolbar,
+ TOOLBAR_BUTTON_LAUNCH,
+ !ro_treeview_has_selection(hotlist_window.tv));
+}
+
+
+/**
+ * Save a new button arrangement in the hotlist toolbar.
+ *
+ * \param *config The new button configuration string.
+ */
+
+void ro_gui_hotlist_toolbar_save_buttons(char *config)
+{
+ if (option_toolbar_hotlist != NULL)
+ free(option_toolbar_hotlist);
+ option_toolbar_hotlist = config;
+ ro_gui_save_options();
}
@@ -233,53 +266,54 @@ bool ro_gui_hotlist_toolbar_click(wimp_pointer *pointer)
*
* \param window The window owning the menu.
* \param *menu The menu about to be opened.
+ * \param *pointer Pointer to the relevant wimp event block, or
+ * NULL for an Adjust click.
+ * \return true if the event was handled; else false.
*/
-void ro_gui_hotlist_menu_prepare(wimp_w window, wimp_menu *menu)
+bool ro_gui_hotlist_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer)
{
bool selection;
- if (menu != hotlist_window.menu && menu != tree_toolbar_menu)
- return;
+ if (menu != hotlist_window.menu)
+ return false;
- if (menu == hotlist_window.menu) {
- selection = ro_treeview_has_selection(hotlist_window.tv);
+ selection = ro_treeview_has_selection(hotlist_window.tv);
- ro_gui_menu_set_entry_shaded(hotlist_window.menu,
- TREE_SELECTION, !selection);
- ro_gui_menu_set_entry_shaded(hotlist_window.menu,
- TREE_CLEAR_SELECTION, !selection);
+ ro_gui_menu_set_entry_shaded(hotlist_window.menu,
+ TREE_SELECTION, !selection);
+ ro_gui_menu_set_entry_shaded(hotlist_window.menu,
+ TREE_CLEAR_SELECTION, !selection);
- ro_gui_save_prepare(GUI_SAVE_HOTLIST_EXPORT_HTML,
- NULL, NULL, NULL, NULL);
- }
+ ro_gui_save_prepare(GUI_SAVE_HOTLIST_EXPORT_HTML,
+ NULL, NULL, NULL, NULL);
ro_gui_menu_set_entry_shaded(menu, TOOLBAR_BUTTONS,
- (hotlist_window.toolbar == NULL ||
- hotlist_window.toolbar->editor != NULL));
+ ro_toolbar_menu_option_shade(hotlist_window.toolbar));
ro_gui_menu_set_entry_ticked(menu, TOOLBAR_BUTTONS,
- (hotlist_window.toolbar != NULL &&
- (hotlist_window.toolbar->display_buttons ||
- (hotlist_window.toolbar->editor != NULL))));
+ ro_toolbar_menu_buttons_tick(hotlist_window.toolbar));
ro_gui_menu_set_entry_shaded(menu, TOOLBAR_EDIT,
- hotlist_window.toolbar == NULL);
+ ro_toolbar_menu_edit_shade(hotlist_window.toolbar));
ro_gui_menu_set_entry_ticked(menu, TOOLBAR_EDIT,
- (hotlist_window.toolbar != NULL &&
- hotlist_window.toolbar->editor != NULL));
+ ro_toolbar_menu_edit_tick(hotlist_window.toolbar));
+
+ return true;
}
/**
* Handle submenu warnings for the hotlist menu
*
- * \param window The window owning the menu.
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
* \param *menu The menu to which the warning applies.
* \param *selection The wimp menu selection data.
* \param action The selected menu action.
*/
-void ro_gui_hotlist_menu_warning(wimp_w window, wimp_menu *menu,
+void ro_gui_hotlist_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
wimp_selection *selection, menu_action action)
{
/* Do nothing */
@@ -288,19 +322,20 @@ void ro_gui_hotlist_menu_warning(wimp_w window, wimp_menu *menu,
/**
* Handle selections from the hotlist menu
*
- * \param window The window owning the menu.
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
* \param *menu The menu from which the selection was made.
* \param *selection The wimp menu selection data.
* \param action The selected menu action.
* \return true if action accepted; else false.
*/
-bool ro_gui_hotlist_menu_select(wimp_w window, wimp_menu *menu,
+bool ro_gui_hotlist_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
wimp_selection *selection, menu_action action)
{
switch (action) {
case HOTLIST_EXPORT:
- ro_gui_dialog_open_persistent(window, dialog_saveas, true);
+ ro_gui_dialog_open_persistent(w, dialog_saveas, true);
return true;
case TREE_NEW_FOLDER:
hotlist_add_folder();
@@ -342,12 +377,12 @@ bool ro_gui_hotlist_menu_select(wimp_w window, wimp_menu *menu,
hotlist_clear_selection();
return true;
case TOOLBAR_BUTTONS:
- hotlist_window.toolbar->display_buttons =
- !hotlist_window.toolbar->display_buttons;
- ro_gui_theme_refresh_toolbar(hotlist_window.toolbar);
+ ro_toolbar_set_display_buttons(hotlist_window.toolbar,
+ !ro_toolbar_get_display_buttons(
+ hotlist_window.toolbar));
return true;
case TOOLBAR_EDIT:
- ro_gui_theme_toggle_edit(hotlist_window.toolbar);
+ ro_toolbar_toggle_edit(hotlist_window.toolbar);
return true;
default:
return false;
@@ -357,21 +392,6 @@ bool ro_gui_hotlist_menu_select(wimp_w window, wimp_menu *menu,
}
/**
- * Update the theme details of the hotlist window.
- *
- * \param full_update true to force a full theme change; false to
- * refresh the toolbar size.
- */
-
-void ro_gui_hotlist_update_theme(bool full_update)
-{
- if (full_update)
- ro_treeview_update_theme(hotlist_window.tv);
- else
- ro_treeview_update_toolbar(hotlist_window.tv);
-}
-
-/**
* Check if a particular window handle is the hotlist window
*
* \param window The window in question
diff --git a/riscos/hotlist.h b/riscos/hotlist.h
index d6126bbd5..e47c140a1 100644
--- a/riscos/hotlist.h
+++ b/riscos/hotlist.h
@@ -30,15 +30,8 @@ void ro_gui_hotlist_preinitialise(void);
void ro_gui_hotlist_postinitialise(void);
void ro_gui_hotlist_open(void);
void ro_gui_hotlist_save(void);
-void ro_gui_hotlist_update_theme(bool full_update);
bool ro_gui_hotlist_check_window(wimp_w window);
bool ro_gui_hotlist_check_menu(wimp_menu *menu);
-bool ro_gui_hotlist_toolbar_click(wimp_pointer *pointer);
-void ro_gui_hotlist_menu_prepare(wimp_w window, wimp_menu *menu);
-bool ro_gui_hotlist_menu_select(wimp_w window, wimp_menu *menu,
- wimp_selection *selection, menu_action action);
-void ro_gui_hotlist_menu_warning(wimp_w window, wimp_menu *menu,
- wimp_selection *selection, menu_action action);
#endif
diff --git a/riscos/iconbar.c b/riscos/iconbar.c
new file mode 100644
index 000000000..77c05fe23
--- /dev/null
+++ b/riscos/iconbar.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
+ *
+ * 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
+ * Iconbar icon and menus (implementation).
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <features.h>
+#include "oslib/os.h"
+#include "oslib/osbyte.h"
+#include "oslib/wimp.h"
+#include "riscos/configure.h"
+#include "riscos/cookies.h"
+#include "riscos/dialog.h"
+#include "riscos/global_history.h"
+#include "riscos/hotlist.h"
+#include "riscos/iconbar.h"
+#include "riscos/options.h"
+#include "riscos/wimp_event.h"
+#include "utils/log.h"
+#include "utils/utils.h"
+
+static bool ro_gui_iconbar_click(wimp_pointer *pointer);
+
+static bool ro_gui_iconbar_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action);
+static void ro_gui_iconbar_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action);
+
+
+static wimp_menu *ro_gui_iconbar_menu = NULL; /**< Iconbar menu handle */
+
+/**
+ * Initialise the iconbar menus, create an icon and register the necessary
+ * handlers to look after them all.
+ */
+
+void ro_gui_iconbar_initialise(void)
+{
+ os_error *error;
+
+ /* Build the iconbar menu */
+
+ static const struct ns_menu iconbar_definition = {
+ "NetSurf", {
+ { "Info", NO_ACTION, &dialog_info },
+ { "AppHelp", HELP_OPEN_CONTENTS, 0 },
+ { "Open", BROWSER_NAVIGATE_URL, 0 },
+ { "Open.OpenURL", BROWSER_NAVIGATE_URL, &dialog_openurl },
+ { "Open.HotlistShow", HOTLIST_SHOW, 0 },
+ { "Open.HistGlobal", HISTORY_SHOW_GLOBAL, 0 },
+ { "Open.ShowCookies", COOKIES_SHOW, 0 },
+ { "Choices", CHOICES_SHOW, 0 },
+ { "Quit", APPLICATION_QUIT, 0 },
+ {NULL, 0, 0}
+ }
+ };
+ ro_gui_iconbar_menu = ro_gui_menu_define_menu(&iconbar_definition);
+
+ /* Create an iconbar icon. */
+
+ wimp_icon_create icon = {
+ wimp_ICON_BAR_RIGHT,
+ { { 0, 0, 68, 68 },
+ wimp_ICON_SPRITE | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED |
+ (wimp_BUTTON_CLICK << wimp_ICON_BUTTON_TYPE_SHIFT),
+ { "!netsurf" } } };
+ error = xwimp_create_icon(&icon, 0);
+ if (error) {
+ LOG(("xwimp_create_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ die(error->errmess);
+ }
+
+ /* Register handlers to look after clicks and menu actions. */
+
+ ro_gui_wimp_event_register_mouse_click(wimp_ICON_BAR,
+ ro_gui_iconbar_click);
+
+ ro_gui_wimp_event_register_menu(wimp_ICON_BAR, ro_gui_iconbar_menu,
+ true, true);
+ ro_gui_wimp_event_register_menu_selection(wimp_ICON_BAR,
+ ro_gui_iconbar_menu_select);
+ ro_gui_wimp_event_register_menu_warning(wimp_ICON_BAR,
+ ro_gui_iconbar_menu_warning);
+}
+
+
+/**
+ * Handle Mouse_Click events on the iconbar icon.
+ *
+ * \param *pointer The wimp event block to be processed.
+ * \return true if the event was handled; else false.
+ */
+
+bool ro_gui_iconbar_click(wimp_pointer *pointer)
+{
+ char url[80];
+ int key_down = 0;
+
+ switch (pointer->buttons) {
+ case wimp_CLICK_SELECT:
+ if (option_homepage_url && option_homepage_url[0]) {
+ browser_window_create(option_homepage_url, NULL, 0,
+ true, false);
+ } else {
+ snprintf(url, sizeof url,
+ "file:///<NetSurf$Dir>/Docs/welcome/index_%s",
+ option_language);
+ browser_window_create(url, NULL, 0, true, false);
+ }
+ break;
+
+ case wimp_CLICK_ADJUST:
+ xosbyte1(osbyte_SCAN_KEYBOARD, 0 ^ 0x80, 0, &key_down);
+ if (key_down == 0)
+ ro_gui_hotlist_open();
+ else
+ ro_gui_debugwin_open();
+ break;
+ }
+
+ return true;
+}
+
+/**
+ * Handle submenu warnings for the iconbar menu
+ *
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param *menu The menu to which the warning applies.
+ * \param *selection The wimp menu selection data.
+ * \param action The selected menu action.
+ */
+
+void ro_gui_iconbar_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action)
+{
+ if (w != wimp_ICON_BAR || i != wimp_ICON_WINDOW)
+ return;
+
+ switch (action) {
+ case BROWSER_NAVIGATE_URL:
+ ro_gui_dialog_prepare_open_url();
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Handle selections from the iconbar menu
+ *
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param *selection The wimp menu selection data.
+ * \param action The selected menu action.
+ * \return true if action accepted; else false.
+ */
+
+bool ro_gui_iconbar_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action)
+{
+ if (w != wimp_ICON_BAR || i != wimp_ICON_WINDOW)
+ return false;
+
+ switch (action) {
+ case HELP_OPEN_CONTENTS:
+ ro_gui_open_help_page("documentation/index");
+ return true;
+ case BROWSER_NAVIGATE_URL:
+ ro_gui_dialog_prepare_open_url();
+ ro_gui_dialog_open_persistent(NULL, dialog_openurl, true);
+ return true;
+ case HOTLIST_SHOW:
+ ro_gui_hotlist_open();
+ return true;
+ case HISTORY_SHOW_GLOBAL:
+ ro_gui_global_history_open();
+ return true;
+ case COOKIES_SHOW:
+ ro_gui_cookies_open();
+ return true;
+ case CHOICES_SHOW:
+ ro_gui_configure_show();
+ return true;
+ case APPLICATION_QUIT:
+ if (ro_gui_prequit()) {
+ LOG(("QUIT in response to user request"));
+ netsurf_quit = true;
+ }
+ return true;
+ default:
+ return false;
+ }
+
+ return false;
+}
+
+/**
+ * Check if a particular menu handle is the iconbar menu
+ *
+ * \param *menu The menu in question.
+ * \return true if this menu is the iconbar menu
+ */
+
+bool ro_gui_iconbar_check_menu(wimp_menu *menu)
+{
+ return (ro_gui_iconbar_menu == menu) ? true : false;
+}
+
diff --git a/riscos/iconbar.h b/riscos/iconbar.h
new file mode 100644
index 000000000..e40f9acd8
--- /dev/null
+++ b/riscos/iconbar.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
+ *
+ * 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
+ * Iconbar icon and menus (interface).
+ */
+
+#include <stdbool.h>
+
+#ifndef _NETSURF_RISCOS_ICONBAR_H_
+#define _NETSURF_RISCOS_ICONBAR_H_
+
+void ro_gui_iconbar_initialise(void);
+bool ro_gui_iconbar_check_menu(wimp_menu *menu);
+
+#endif
+
diff --git a/riscos/menus.c b/riscos/menus.c
index af16127bc..133aa9d6d 100644
--- a/riscos/menus.c
+++ b/riscos/menus.c
@@ -57,7 +57,7 @@
#include "riscos/options.h"
#include "riscos/save.h"
#include "riscos/tinct.h"
-#include "riscos/theme.h"
+#include "riscos/toolbar.h"
#include "riscos/treeview.h"
#include "riscos/url_suggest.h"
#include "riscos/wimp.h"
@@ -93,14 +93,7 @@ static struct menu_definition_entry *ro_gui_menu_find_entry(wimp_menu *menu,
menu_action action);
static menu_action ro_gui_menu_find_action(wimp_menu *menu,
wimp_menu_entry *menu_entry);
-static void ro_gui_menu_get_window_details(wimp_w w, struct gui_window **g,
- struct browser_window **bw, hlcache_handle **h,
- struct toolbar **toolbar,
- bool *is_cookies, bool *is_hotlist, bool *is_global_history);
static int ro_gui_menu_get_checksum(void);
-static void ro_gui_menu_prepare_pageinfo(struct gui_window *g);
-static void ro_gui_menu_prepare_objectinfo(hlcache_handle *object,
- const char *href);
static bool ro_gui_menu_translate(struct menu_definition *menu);
@@ -115,27 +108,12 @@ static struct menu_definition *ro_gui_menu_definitions;
wimp_menu *current_menu;
/** Whether a menu is currently open */
bool current_menu_open = false;
-/** Object under menu, or 0 if no object. */
-static hlcache_handle *current_menu_object = 0;
-/** URL of link under menu, or 0 if no link. */
-static const char *current_menu_url = 0;
-/** Menu of options for form select controls. */
-static wimp_menu *gui_form_select_menu = 0;
-/** Form control which gui_form_select_menu is for. */
-static struct form_control *gui_form_select_control;
/** Window that owns the current menu */
wimp_w current_menu_window;
/** Icon that owns the current menu (only valid for popup menus) */
static wimp_i current_menu_icon;
-/** The height of the iconbar menu */
-int iconbar_menu_height = 5 * 44;
/** The available menus */
-wimp_menu *iconbar_menu, *browser_menu, *image_quality_menu,
- *browser_toolbar_menu, *tree_toolbar_menu,
- *proxy_type_menu, *languages_menu;
-
-static wimp_MENU(URL_SUGGEST_MAX_URLS) url_suggest_menu_block;
-wimp_menu *url_suggest_menu = (wimp_menu *) &url_suggest_menu_block;
+wimp_menu *image_quality_menu, *proxy_type_menu, *languages_menu;
/* the values given in PRM 3-157 for how to check menus/windows are
* incorrect so we use a hack of checking if the sub-menu has bit 0
@@ -148,122 +126,6 @@ wimp_menu *url_suggest_menu = (wimp_menu *) &url_suggest_menu_block;
*/
void ro_gui_menu_init(void)
{
- /* iconbar menu */
- static const struct ns_menu iconbar_definition = {
- "NetSurf", {
- { "Info", NO_ACTION, &dialog_info },
- { "AppHelp", HELP_OPEN_CONTENTS, 0 },
- { "Open", BROWSER_NAVIGATE_URL, 0 },
- { "Open.OpenURL", BROWSER_NAVIGATE_URL, &dialog_openurl },
- { "Open.HotlistShow", HOTLIST_SHOW, 0 },
- { "Open.HistGlobal", HISTORY_SHOW_GLOBAL, 0 },
- { "Open.ShowCookies", COOKIES_SHOW, 0 },
- { "Choices", CHOICES_SHOW, 0 },
- { "Quit", APPLICATION_QUIT, 0 },
- {NULL, 0, 0}
- }
- };
- iconbar_menu = ro_gui_menu_define_menu(&iconbar_definition);
-
- /* browser menu */
- static const struct ns_menu browser_definition = {
- "NetSurf", {
- { "Page", BROWSER_PAGE, 0 },
- { "Page.PageInfo",BROWSER_PAGE_INFO, &dialog_pageinfo },
- { "Page.Save", BROWSER_SAVE, &dialog_saveas },
- { "Page.SaveComp", BROWSER_SAVE_COMPLETE, &dialog_saveas },
- { "Page.Export", NO_ACTION, 0 },
-#ifdef WITH_DRAW_EXPORT
- { "Page.Export.Draw", BROWSER_EXPORT_DRAW, &dialog_saveas },
-#endif
-#ifdef WITH_PDF_EXPORT
- { "Page.Export.PDF", BROWSER_EXPORT_PDF, &dialog_saveas },
-#endif
- { "Page.Export.Text", BROWSER_EXPORT_TEXT, &dialog_saveas },
- { "Page.SaveURL", NO_ACTION, 0 },
- { "Page.SaveURL.URI", BROWSER_SAVE_URL_URI, &dialog_saveas },
- { "Page.SaveURL.URL", BROWSER_SAVE_URL_URL, &dialog_saveas },
- { "Page.SaveURL.LinkText", BROWSER_SAVE_URL_TEXT, &dialog_saveas },
- { "_Page.Print", BROWSER_PRINT, &dialog_print },
- { "Page.NewWindow", BROWSER_NEW_WINDOW, 0 },
- { "Page.FindText", BROWSER_FIND_TEXT, &dialog_search },
- { "Page.ViewSrc", BROWSER_VIEW_SOURCE, 0 },
- { "Object", BROWSER_OBJECT, 0 },
- { "Object.Object", BROWSER_OBJECT_OBJECT, 0 },
- { "Object.Object.ObjInfo", BROWSER_OBJECT_INFO, &dialog_objinfo },
- { "Object.Object.ObjSave", BROWSER_OBJECT_SAVE, &dialog_saveas },
- { "Object.Object.Export", BROWSER_OBJECT_EXPORT, 0 },
- { "Object.Object.Export.Sprite", BROWSER_OBJECT_EXPORT_SPRITE, &dialog_saveas },
-#ifdef WITH_DRAW_EXPORT
- { "Object.Object.Export.ObjDraw", BROWSER_OBJECT_EXPORT_DRAW, &dialog_saveas },
-#endif
- { "Object.Object.SaveURL", NO_ACTION, 0 },
- { "Object.Object.SaveURL.URI", BROWSER_OBJECT_SAVE_URL_URI, &dialog_saveas },
- { "Object.Object.SaveURL.URL", BROWSER_OBJECT_SAVE_URL_URL, &dialog_saveas },
- { "Object.Object.SaveURL.LinkText", BROWSER_OBJECT_SAVE_URL_TEXT, &dialog_saveas },
- { "Object.Object.ObjPrint", BROWSER_OBJECT_PRINT, 0 },
- { "Object.Object.ObjReload", BROWSER_OBJECT_RELOAD, 0 },
- { "Object.Link", BROWSER_OBJECT_LINK, 0 },
- { "Object.Link.LinkSave", BROWSER_LINK_SAVE, 0 },
- { "Object.Link.LinkSave.URI", BROWSER_LINK_SAVE_URI, &dialog_saveas },
- { "Object.Link.LinkSave.URL", BROWSER_LINK_SAVE_URL, &dialog_saveas },
- { "Object.Link.LinkSave.LinkText", BROWSER_LINK_SAVE_TEXT, &dialog_saveas },
- { "_Object.Link.LinkDload", BROWSER_LINK_DOWNLOAD, 0 },
- { "Object.Link.LinkNew", BROWSER_LINK_NEW_WINDOW, 0 },
- { "Selection", BROWSER_SELECTION, 0 },
- { "_Selection.SelSave", BROWSER_SELECTION_SAVE, &dialog_saveas },
- { "Selection.Copy", BROWSER_SELECTION_COPY, 0 },
- { "Selection.Cut", BROWSER_SELECTION_CUT, 0 },
- { "_Selection.Paste", BROWSER_SELECTION_PASTE, 0 },
- { "Selection.Clear", BROWSER_SELECTION_CLEAR, 0 },
- { "Selection.SelectAll", BROWSER_SELECTION_ALL, 0 },
- { "Navigate", NO_ACTION, 0 },
- { "Navigate.Home", BROWSER_NAVIGATE_HOME, 0 },
- { "Navigate.Back", BROWSER_NAVIGATE_BACK, 0 },
- { "Navigate.Forward", BROWSER_NAVIGATE_FORWARD, 0 },
- { "_Navigate.UpLevel", BROWSER_NAVIGATE_UP, 0 },
- { "Navigate.Reload", BROWSER_NAVIGATE_RELOAD_ALL, 0 },
- { "Navigate.Stop", BROWSER_NAVIGATE_STOP, 0 },
- { "View", NO_ACTION, 0 },
- { "View.ScaleView", BROWSER_SCALE_VIEW, &dialog_zoom },
- { "View.Images", NO_ACTION, 0 },
- { "View.Images.ForeImg", BROWSER_IMAGES_FOREGROUND, 0 },
- { "View.Images.BackImg", BROWSER_IMAGES_BACKGROUND, 0 },
- { "View.Toolbars", NO_ACTION, 0 },
- { "View.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
- { "View.Toolbars.ToolAddress", TOOLBAR_ADDRESS_BAR, 0 },
- { "_View.Toolbars.ToolThrob", TOOLBAR_THROBBER, 0 },
- { "View.Toolbars.EditToolbar", TOOLBAR_EDIT, 0 },
- { "_View.Render", NO_ACTION, 0 },
- { "View.Render.RenderAnims", BROWSER_BUFFER_ANIMS, 0 },
- { "View.Render.RenderAll", BROWSER_BUFFER_ALL, 0 },
- { "_View.OptDefault", BROWSER_SAVE_VIEW, 0 },
- { "View.Window", NO_ACTION, 0 },
- { "View.Window.WindowSave", BROWSER_WINDOW_DEFAULT, 0 },
- { "View.Window.WindowStagr", BROWSER_WINDOW_STAGGER, 0 },
- { "_View.Window.WindowSize", BROWSER_WINDOW_COPY, 0 },
- { "View.Window.WindowReset", BROWSER_WINDOW_RESET, 0 },
- { "Utilities", NO_ACTION, 0 },
- { "Utilities.Hotlist", HOTLIST_SHOW, 0 },
- { "Utilities.Hotlist.HotlistAdd", HOTLIST_ADD_URL, 0 },
- { "Utilities.Hotlist.HotlistShow", HOTLIST_SHOW, 0 },
- { "Utilities.History", HISTORY_SHOW_GLOBAL, 0 },
- { "Utilities.History.HistLocal", HISTORY_SHOW_LOCAL, 0 },
- { "Utilities.History.HistGlobal", HISTORY_SHOW_GLOBAL, 0 },
- { "Utilities.Cookies", COOKIES_SHOW, 0 },
- { "Utilities.Cookies.ShowCookies", COOKIES_SHOW, 0 },
- { "Utilities.Cookies.DeleteCookies", COOKIES_DELETE, 0 },
- { "Help", HELP_OPEN_CONTENTS, 0 },
- { "Help.HelpContent", HELP_OPEN_CONTENTS, 0 },
- { "Help.HelpGuide", HELP_OPEN_GUIDE, 0 },
- { "_Help.HelpInfo", HELP_OPEN_INFORMATION, 0 },
- { "_Help.HelpAbout", HELP_OPEN_ABOUT, 0 },
- { "Help.HelpInter", HELP_LAUNCH_INTERACTIVE, 0 },
- {NULL, 0, 0}
- }
- };
- browser_menu = ro_gui_menu_define_menu(&browser_definition);
-
/* image quality menu */
static const struct ns_menu images_definition = {
"Display", {
@@ -276,32 +138,6 @@ void ro_gui_menu_init(void)
};
image_quality_menu = ro_gui_menu_define_menu(&images_definition);
- /* browser toolbar menu */
- static const struct ns_menu browser_toolbar_definition = {
- "Toolbar", {
- { "Toolbars", NO_ACTION, 0 },
- { "Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
- { "Toolbars.ToolAddress", TOOLBAR_ADDRESS_BAR, 0 },
- { "Toolbars.ToolThrob", TOOLBAR_THROBBER, 0 },
- { "EditToolbar", TOOLBAR_EDIT, 0 },
- {NULL, 0, 0}
- }
- };
- browser_toolbar_menu = ro_gui_menu_define_menu(
- &browser_toolbar_definition);
-
- /* tree toolbar menu */
- static const struct ns_menu tree_toolbar_definition = {
- "Toolbar", {
- { "Toolbars", NO_ACTION, 0 },
- { "Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
- { "EditToolbar", TOOLBAR_EDIT, 0 },
- {NULL, 0, 0}
- }
- };
- tree_toolbar_menu = ro_gui_menu_define_menu(&tree_toolbar_definition);
-
-
/* proxy menu */
static const struct ns_menu proxy_type_definition = {
"ProxyType", {
@@ -315,7 +151,7 @@ void ro_gui_menu_init(void)
proxy_type_menu = ro_gui_menu_define_menu(&proxy_type_definition);
/* special case menus */
- ro_gui_url_suggest_init(url_suggest_menu);
+ ro_gui_url_suggest_init();
/* Note: This table *must* be kept in sync with the LangNames file */
static const struct ns_menu lang_definition = {
@@ -381,16 +217,10 @@ void ro_gui_menu_init(void)
* \param x The x position.
* \param y The y position.
* \param w The window that the menu belongs to.
- * \param prepare true if the menu is to be prepared; otherwise
- * false (mainly for use by wimp_event module).
*/
-void ro_gui_menu_create(wimp_menu *menu, int x, int y, wimp_w w, bool prepare)
+void ro_gui_menu_create(wimp_menu *menu, int x, int y, wimp_w w)
{
- struct gui_window *g;
os_error *error;
- os_coord pos;
- int i;
- menu_action action;
struct menu_definition *definition;
/* translate menu, if necessary (this returns quickly
@@ -403,62 +233,10 @@ void ro_gui_menu_create(wimp_menu *menu, int x, int y, wimp_w w, bool prepare)
}
}
- /* read the object under the pointer for a new gui_window menu */
- if ((!current_menu) && (menu == browser_menu)) {
- hlcache_handle *h;
-
- g = ro_gui_window_lookup(w);
- h = g->bw->current_content;
-
- if (!ro_gui_window_to_window_pos(g, x, y, &pos))
- return;
- current_menu_object = NULL;
- current_menu_url = NULL;
- if (h) {
- switch (content_get_type(h)) {
- case CONTENT_HTML: {
- struct box *box;
- box = box_object_at_point(h, pos.x,
- pos.y);
- current_menu_object = box ?
- box->object : NULL;
- box = box_href_at_point(h, pos.x,
- pos.y);
- current_menu_url = box ?
- box->href : NULL;
- }
- break;
- case CONTENT_TEXTPLAIN:
- /* no object, no url */
- break;
- default:
- current_menu_object = h;
- break;
- }
- }
- }
-
/* store the menu characteristics */
current_menu = menu;
current_menu_window = w;
- current_menu_icon = -1;
-
- /* prepare the menu state */
- if (menu == url_suggest_menu) {
- if (!ro_gui_url_suggest_prepare_menu())
- return;
- } else if (menu == recent_search_menu) {
- if (!ro_gui_search_prepare_menu())
- return;
- } else if (prepare) {
- i = 0;
- do {
- action = ro_gui_menu_find_action(menu,
- &menu->entries[i]);
- if (action != NO_ACTION)
- ro_gui_menu_prepare_action(w, action, false);
- } while (!(menu->entries[i++].menu_flags & wimp_MENU_LAST));
- }
+ current_menu_icon = wimp_ICON_WINDOW;
/* create the menu */
current_menu_open = true;
@@ -467,7 +245,7 @@ void ro_gui_menu_create(wimp_menu *menu, int x, int y, wimp_w w, bool prepare)
LOG(("xwimp_create_menu: 0x%x: %s",
error->errnum, error->errmess));
warn_user("MenuError", error->errmess);
- ro_gui_menu_closed(true);
+ ro_gui_menu_closed();
}
}
@@ -507,42 +285,28 @@ void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i)
ro_gui_menu_create(menu,
state.visible.x0 + icon_state.icon.extent.x1 + 64,
state.visible.y1 + icon_state.icon.extent.y1 -
- state.yscroll, w, true);
+ state.yscroll, w);
current_menu_icon = i;
}
/**
* Clean up after a menu has been closed, or forcible close an open menu.
- *
- * \param cleanup Call any terminating functions (sub-window isn't going to be instantly re-opened)
- */
-void ro_gui_menu_closed(bool cleanup)
+ */
+void ro_gui_menu_closed(void)
{
- struct gui_window *g;
- struct browser_window *bw;
- hlcache_handle *h;
- struct toolbar *t;
os_error *error;
- bool is_cookies, is_hotlist, is_global_history;
if (current_menu) {
-
error = xwimp_create_menu(wimp_CLOSE_MENU, 0, 0);
if (error) {
LOG(("xwimp_create_menu: 0x%x: %s",
error->errnum, error->errmess));
warn_user("MenuError", error->errmess);
}
- ro_gui_menu_get_window_details(current_menu_window,
- &g, &bw, &h, &t,
- &is_cookies, &is_hotlist,
- &is_global_history);
-
- if (cleanup) {
- ro_gui_wimp_event_menus_closed(current_menu_window,
- current_menu_icon, current_menu);
- }
+
+ ro_gui_wimp_event_menus_closed(current_menu_window,
+ current_menu_icon, current_menu);
current_menu = NULL;
}
@@ -550,46 +314,43 @@ void ro_gui_menu_closed(bool cleanup)
current_menu_window = NULL;
current_menu_icon = 0;
current_menu_open = false;
- gui_form_select_control = NULL;
}
/**
- * The content has changed, reset object references
+ * Allow the current menu window to change, if the window is deleted and
+ * recreated while a menu is active on an Adjust-click.
+ *
+ * \param from The original window handle.
+ * \param to The new replacement window handle.
*/
-void ro_gui_menu_objects_moved(void)
+
+void ro_gui_menu_window_changed(wimp_w from, wimp_w to)
{
- gui_form_select_control = NULL;
- current_menu_object = NULL;
- current_menu_url = NULL;
- ro_gui_menu_prepare_action(0, BROWSER_OBJECT, false);
- if ((current_menu) && (current_menu == gui_form_select_menu))
- ro_gui_menu_closed(true);
+ if (from == current_menu_window)
+ current_menu_window = to;
}
/**
* Handle menu selection.
*/
+
void ro_gui_menu_selection(wimp_selection *selection)
{
- int i, j;
- bool needs_prepare;
+ int i; //, j;
wimp_menu_entry *menu_entry;
menu_action action;
wimp_pointer pointer;
- struct gui_window *g = NULL;
- wimp_menu *menu;
os_error *error;
int previous_menu_icon = current_menu_icon;
- char *url;
/* if we are using gui_multitask then menu selection events
* may be delivered after the menu has been closed. As such,
* we simply ignore these events. */
if (!current_menu)
- return
+ return;
assert(current_menu_window);
@@ -600,51 +361,13 @@ void ro_gui_menu_selection(wimp_selection *selection)
entries[selection->items[i]];
action = ro_gui_menu_find_action(current_menu, menu_entry);
- /* Deal with the menu action. We first pass it to Wimp_Event to
- * handle any automatic menus. If this doesn't recognise the details,
- * it is passed on to the code in menus.c.
+ /* Deal with the menu action. If this manages to re-prepare the
+ * menu for re-opening, we test for and act on Adjust clicks.
*/
- needs_prepare = false;
-
if (!ro_gui_wimp_event_menu_selection(current_menu_window,
- current_menu_icon, current_menu, selection, action)) {
-
- /* perform menu action */
- if (action != NO_ACTION)
- ro_gui_menu_handle_action(current_menu_window,
- action, false);
-
- /* perform non-automated actions */
- if (current_menu == url_suggest_menu) {
- g = ro_gui_toolbar_lookup(current_menu_window);
- if (g) {
- url = url_suggest_menu->entries[selection->items[0]].
- data.indirected_text.text;
- gui_window_set_url(g, url);
- browser_window_go(g->bw, url, 0, true);
- }
- } else if (current_menu == gui_form_select_menu) {
- g = ro_gui_window_lookup(current_menu_window);
- assert(g);
-
- if (selection->items[0] >= 0) {
- form_select_process_selection(g->bw->current_content,
- gui_form_select_control,
- selection->items[0]);
- }
- }
-
- /* allow automatic menus to have their data updated */
-// ro_gui_wimp_event_menu_selection(current_menu_window,
-// current_menu_icon, current_menu, selection);
-
- /* Menus not handled by ro_gui_wimp_event_menu_selection()
- * will need to be re-prepared before an adjust reopening.
- */
-
- needs_prepare = true;
- }
+ current_menu_icon, current_menu, selection, action))
+ return;
/* re-open the menu for Adjust clicks */
error = xwimp_get_pointer_info(&pointer);
@@ -652,43 +375,16 @@ void ro_gui_menu_selection(wimp_selection *selection)
LOG(("xwimp_get_pointer_info: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
- ro_gui_menu_closed(true);
+ ro_gui_menu_closed();
return;
}
if (pointer.buttons != wimp_CLICK_ADJUST) {
- ro_gui_menu_closed(true);
+ ro_gui_menu_closed();
return;
}
- /* re-prepare all the visible entries */
- if (needs_prepare) {
- i = 0;
- menu = current_menu;
- do {
- j = 0;
- do {
- action = ro_gui_menu_find_action(current_menu,
- &menu->entries[j]);
- if (action != NO_ACTION)
- ro_gui_menu_prepare_action(current_menu_window,
- action, false);
- } while (!(menu->entries[j++].menu_flags & wimp_MENU_LAST));
- j = selection->items[i++];
- if (j != -1) {
- menu = menu->entries[j].sub_menu;
- if ((!menu) || (menu == wimp_NO_SUB_MENU))
- break;
- }
- } while (j != -1);
- }
-
- if (current_menu == gui_form_select_menu) {
- assert(g); /* Keep scan-build happy */
- gui_create_form_select_menu(g->bw, gui_form_select_control);
- } else
- ro_gui_menu_create(current_menu, 0, 0, current_menu_window, true);
-
+ ro_gui_menu_create(current_menu, 0, 0, current_menu_window);
current_menu_icon = previous_menu_icon;
}
@@ -701,7 +397,6 @@ void ro_gui_menu_warning(wimp_message_menu_warning *warning)
int i;
menu_action action;
wimp_menu_entry *menu_entry;
- wimp_menu *sub_menu;
os_error *error;
assert(current_menu);
@@ -716,42 +411,31 @@ void ro_gui_menu_warning(wimp_message_menu_warning *warning)
entries[warning->selection.items[i]];
action = ro_gui_menu_find_action(current_menu, menu_entry);
- /* We only process the menu in the old way if the wimp_event module
- * hasn't processed it for us.
+ /* Process the warning via Wimp_Event, then register the resulting
+ * submenu with the module.
*/
- if (!ro_gui_wimp_event_submenu_warning(current_menu_window,
+ ro_gui_wimp_event_submenu_warning(current_menu_window,
current_menu_icon, current_menu, &(warning->selection),
- action)) {
- if (IS_MENU(menu_entry->sub_menu)) {
- ro_gui_wimp_event_register_submenu((wimp_w)0);
- sub_menu = menu_entry->sub_menu;
- i = 0;
- do {
- action = ro_gui_menu_find_action(current_menu,
- &sub_menu->entries[i]);
- if (action != NO_ACTION)
- ro_gui_menu_prepare_action(current_menu_window,
- action, false);
- } while (!(sub_menu->entries[i++].menu_flags &
- wimp_MENU_LAST));
- } else {
- ro_gui_wimp_event_register_submenu((wimp_w)menu_entry->sub_menu);
- action = ro_gui_menu_find_action(current_menu, menu_entry);
- if (action != NO_ACTION)
- ro_gui_menu_prepare_action(current_menu_window,
- action, true);
- }
- }
+ action);
- /* If this is a dialogue box, remove the close and back icons. */
+ if (IS_MENU(menu_entry->sub_menu)) {
+ ro_gui_wimp_event_register_submenu((wimp_w) 0);
+ } else {
+ ro_gui_wimp_event_register_submenu((wimp_w)
+ menu_entry->sub_menu);
- if (!(IS_MENU(menu_entry->sub_menu)))
- ro_gui_wimp_update_window_furniture((wimp_w)menu_entry->sub_menu,
- wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_BACK_ICON, 0);
+ /* If this is a dialogue box, remove the close and back icons.
+ */
+ ro_gui_wimp_update_window_furniture((wimp_w)
+ menu_entry->sub_menu,
+ wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_BACK_ICON,
+ 0);
+ }
/* open the sub-menu */
+
error = xwimp_create_sub_menu(menu_entry->sub_menu,
warning->pos.x, warning->pos.y);
if (error) {
@@ -761,244 +445,42 @@ void ro_gui_menu_warning(wimp_message_menu_warning *warning)
}
}
-
/**
- * Update navigate menu status and toolbar icons.
+ * Update the current menu by sending it a Menu Prepare event through wimp_event
+ * and then reopening it if the contents has changed.
*
- * /param gui the gui_window to update
+ * \param *menu The menu to refresh: if 0, the current menu will be
+ * refreshed regardless, otherwise it will be refreshed
+ * only if it matches the supplied handle.
*/
-void ro_gui_prepare_navigate(struct gui_window *gui)
-{
- ro_gui_menu_prepare_action(gui->window, HOTLIST_SHOW, false);
- ro_gui_menu_prepare_action(gui->window, BROWSER_NAVIGATE_STOP, false);
- ro_gui_menu_prepare_action(gui->window, BROWSER_NAVIGATE_RELOAD_ALL,
- false);
- ro_gui_menu_prepare_action(gui->window, BROWSER_NAVIGATE_BACK, false);
- ro_gui_menu_prepare_action(gui->window, BROWSER_NAVIGATE_FORWARD,
- false);
- ro_gui_menu_prepare_action(gui->window, BROWSER_NAVIGATE_UP, false);
- ro_gui_menu_prepare_action(gui->window, HOTLIST_SHOW, false);
- ro_gui_menu_prepare_action(gui->window, BROWSER_SAVE, false);
- ro_gui_menu_prepare_action(gui->window, BROWSER_PRINT, false);
- ro_gui_menu_prepare_action(gui->window, BROWSER_SCALE_VIEW, false);
- ro_gui_menu_prepare_action(gui->window, BROWSER_FIND_TEXT, false);
-
- if (gui->toolbar) {
- ro_gui_set_icon_shaded_state(gui->toolbar->toolbar_handle,
- ICON_TOOLBAR_SUGGEST,
- !ro_gui_url_suggest_prepare_menu());
- }
-}
-
-/**
- * Prepare the page info window for use
- *
- * \param g the gui_window to set the display icons for
- */
-void ro_gui_menu_prepare_pageinfo(struct gui_window *g)
-{
- hlcache_handle *h = g->bw->current_content;
- char icon_buf[20] = "file_xxx";
- char enc_buf[40];
- char enc_token[10] = "Encoding0";
- const char *icon = icon_buf;
- const char *title, *url, *mime;
- const char *enc = "-";
-
- assert(h);
-
- title = content_get_title(h);
- if (title == NULL)
- title = "-";
- url = content_get_url(h);
- if (url == NULL)
- url = "-";
- mime = content_get_mime_type(h);
- if (mime == NULL)
- mime = "-";
-
- sprintf(icon_buf, "file_%x", ro_content_filetype(h));
- if (!ro_gui_wimp_sprite_exists(icon_buf))
- sprintf(icon_buf, "file_xxx");
-
- if (content_get_type(h) == CONTENT_HTML) {
- if (html_get_encoding(h)) {
- enc_token[8] = '0' + html_get_encoding_source(h);
- snprintf(enc_buf, sizeof enc_buf, "%s (%s)",
- html_get_encoding(h),
- messages_get(enc_token));
- enc = enc_buf;
- } else {
- enc = messages_get("EncodingUnk");
- }
- }
-
- ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_ICON, icon, true);
- ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_TITLE, title, true);
- ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_URL, url, true);
- ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_ENC, enc, true);
- ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_TYPE, mime, true);
-}
-
-
-/**
- * Prepare the object info window for use
- *
- * \param object the object for which information is to be displayed
- * \param href corresponding href, if any
- */
-void ro_gui_menu_prepare_objectinfo(hlcache_handle *object, const char *href)
-{
- char icon_buf[20] = "file_xxx";
- const char *url, *mime;
- const char *target = "-";
-
- sprintf(icon_buf, "file_%.3x",
- ro_content_filetype(object));
- if (!ro_gui_wimp_sprite_exists(icon_buf))
- sprintf(icon_buf, "file_xxx");
-
- url = content_get_url(object);
- if (url == NULL)
- url = "-";
- mime = content_get_mime_type(object);
- if (mime == NULL)
- mime = "-";
-
- if (href)
- target = href;
-
- ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_ICON, icon_buf, true);
- ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_URL, url, true);
- ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TARGET, target, true);
- ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TYPE, mime, true);
-}
-
-
-/**
- * Display a menu of options for a form select control.
- *
- * \param bw browser window containing form control
- * \param control form control of type GADGET_SELECT
- */
-void gui_create_form_select_menu(struct browser_window *bw,
- struct form_control *control)
+void ro_gui_menu_refresh(wimp_menu *menu)
{
- unsigned int i, entries;
- char *text_convert, *temp;
- struct form_option *option;
- wimp_pointer pointer;
+ int checksum = 0;
os_error *error;
- bool reopen = true;
- utf8_convert_ret err;
- assert(control);
-
- for (entries = 0, option = control->data.select.items; option;
- option = option->next)
- entries++;
- if (entries == 0) {
- ro_gui_menu_closed(true);
+ if (!current_menu_open)
return;
- }
- if ((gui_form_select_menu) && (control != gui_form_select_control)) {
- for (i = 0; ; i++) {
- free(gui_form_select_menu->entries[i].data.
- indirected_text.text);
- if (gui_form_select_menu->entries[i].menu_flags &
- wimp_MENU_LAST)
- break;
- }
- free(gui_form_select_menu->title_data.indirected_text.text);
- free(gui_form_select_menu);
- gui_form_select_menu = 0;
- }
+ checksum = ro_gui_menu_get_checksum();
- if (!gui_form_select_menu) {
- reopen = false;
- gui_form_select_menu = malloc(wimp_SIZEOF_MENU(entries));
- if (!gui_form_select_menu) {
- warn_user("NoMemory", 0);
- ro_gui_menu_closed(true);
- return;
- }
- err = utf8_to_local_encoding(messages_get("SelectMenu"), 0,
- &text_convert);
- if (err != UTF8_CONVERT_OK) {
- /* badenc should never happen */
- assert(err != UTF8_CONVERT_BADENC);
- LOG(("utf8_to_local_encoding failed"));
- warn_user("NoMemory", 0);
- ro_gui_menu_closed(true);
- return;
- }
- gui_form_select_menu->title_data.indirected_text.text =
- text_convert;
- ro_gui_menu_init_structure(gui_form_select_menu, entries);
- }
+ if (!ro_gui_wimp_event_prepare_menu(current_menu_window,
+ current_menu_icon, current_menu))
+ return;
- for (i = 0, option = control->data.select.items; option;
- i++, option = option->next) {
- gui_form_select_menu->entries[i].menu_flags = 0;
- if (option->selected)
- gui_form_select_menu->entries[i].menu_flags =
- wimp_MENU_TICKED;
- if (!reopen) {
-
- /* convert spaces to hard spaces to stop things
- * like 'Go Home' being treated as if 'Home' is a
- * keyboard shortcut and right aligned in the menu.
- */
-
- temp = cnv_space2nbsp(option->text);
- if (!temp) {
- LOG(("cnv_space2nbsp failed"));
- warn_user("NoMemory", 0);
- ro_gui_menu_closed(true);
- return;
- }
-
- err = utf8_to_local_encoding(temp,
- 0, &text_convert);
- if (err != UTF8_CONVERT_OK) {
- /* A bad encoding should never happen,
- * so assert this */
- assert(err != UTF8_CONVERT_BADENC);
- LOG(("utf8_to_enc failed"));
- warn_user("NoMemory", 0);
- ro_gui_menu_closed(true);
- return;
- }
-
- free(temp);
-
- gui_form_select_menu->entries[i].data.indirected_text.text =
- text_convert;
- gui_form_select_menu->entries[i].data.indirected_text.size =
- strlen(gui_form_select_menu->entries[i].
- data.indirected_text.text) + 1;
+ /* \TODO -- Call the menu's event handler here. */
+
+ if (checksum != ro_gui_menu_get_checksum()) {
+ error = xwimp_create_menu(current_menu, 0, 0);
+ if (error) {
+ LOG(("xwimp_create_menu: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("MenuError", error->errmess);
}
}
+}
- gui_form_select_menu->entries[0].menu_flags |=
- wimp_MENU_TITLE_INDIRECTED;
- gui_form_select_menu->entries[i - 1].menu_flags |= wimp_MENU_LAST;
-
- 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);
- ro_gui_menu_closed(true);
- return;
- }
- gui_form_select_control = control;
- ro_gui_menu_create(gui_form_select_menu,
- pointer.pos.x, pointer.pos.y, bw->window->window, true);
-}
/**
@@ -1345,908 +827,6 @@ void ro_gui_menu_set_entry_ticked(wimp_menu *menu, menu_action action,
/**
- * Handles an action.
- *
- * \param owner the window to handle the action for
- * \param action the action to handle
- * \param windows_at_pointer whether to open any windows at the pointer location
- */
-bool ro_gui_menu_handle_action(wimp_w owner, menu_action action,
- bool windows_at_pointer)
-{
- wimp_window_state state;
- struct gui_window *g = NULL;
- struct browser_window *bw = NULL;
- hlcache_handle *h = NULL;
- struct toolbar *t = NULL;
- os_error *error;
- char url[80];
- bool is_cookies, is_hotlist, is_global_history;
-
- ro_gui_menu_get_window_details(owner, &g, &bw, &h, &t,
- &is_cookies, &is_hotlist, &is_global_history);
-
- switch (action) {
-
- /* help actions */
- case HELP_OPEN_CONTENTS:
- ro_gui_open_help_page("documentation/index");
- return true;
- case HELP_OPEN_GUIDE:
- ro_gui_open_help_page("documentation/guide");
- return true;
- case HELP_OPEN_INFORMATION:
- ro_gui_open_help_page("documentation/info");
- return true;
- case HELP_OPEN_ABOUT:
- ro_gui_open_help_page("about/index");
- return true;
- case HELP_LAUNCH_INTERACTIVE:
- if (!ro_gui_interactive_help_available()) {
- ro_gui_interactive_help_start();
- option_interactive_help = true;
- } else {
- option_interactive_help = !option_interactive_help;
- }
- return true;
-
- /* history actions */
- case HISTORY_SHOW_LOCAL:
- if ((!bw) || (!bw->history))
- return false;
- ro_gui_history_open(bw, bw->history,
- windows_at_pointer);
- return true;
- case HISTORY_SHOW_GLOBAL:
- ro_gui_global_history_open();
- return true;
-
- /* hotlist actions */
- case HOTLIST_ADD_URL:
- if (h == NULL || content_get_url(h) == NULL)
- return false;
- hotlist_add_page(content_get_url(h));
- return true;
- case HOTLIST_SHOW:
- ro_gui_hotlist_open();
- return true;
-
- /* cookies actions */
- case COOKIES_SHOW:
- ro_gui_cookies_open();
- return true;
-
- case COOKIES_DELETE:
- cookies_delete_all();
- return true;
-
- /* page actions */
- case BROWSER_PAGE_INFO:
- if (!h)
- return false;
- ro_gui_menu_prepare_action(owner, action, true);
- ro_gui_dialog_open_persistent(g->window,
- dialog_pageinfo, windows_at_pointer);
- return true;
- case BROWSER_PRINT:
- if (!h)
- return false;
- ro_gui_menu_prepare_action(owner, action, true);
- ro_gui_dialog_open_persistent(g->window,
- dialog_print, windows_at_pointer);
- return true;
- case BROWSER_NEW_WINDOW:
- if (!h)
- return false;
- browser_window_create(content_get_url(h), bw, 0, false,
- false);
- return true;
- case BROWSER_VIEW_SOURCE:
- if (!h)
- return false;
- ro_gui_view_source(h);
- return true;
-
- /* object actions */
- case BROWSER_OBJECT_INFO:
- if (!current_menu_object)
- return false;
- ro_gui_menu_prepare_action(owner, action, true);
- ro_gui_dialog_open_persistent(g->window,
- dialog_objinfo, windows_at_pointer);
- return true;
- case BROWSER_OBJECT_RELOAD:
- if (!current_menu_object)
- return false;
- content_invalidate_reuse_data(current_menu_object);
- browser_window_reload(bw, false);
- return true;
-
- /* link actions */
- case BROWSER_LINK_SAVE_URI:
- case BROWSER_LINK_SAVE_URL:
- case BROWSER_LINK_SAVE_TEXT:
- if (!current_menu_url)
- return false;
- ro_gui_menu_prepare_action(owner, action, true);
- ro_gui_dialog_open_persistent(owner, dialog_saveas,
- windows_at_pointer);
- break;
- case BROWSER_LINK_DOWNLOAD:
- if (!current_menu_url)
- return false;
- browser_window_download(bw, current_menu_url,
- content_get_url(h));
- break;
- case BROWSER_LINK_NEW_WINDOW:
- if (!current_menu_url)
- return false;
- browser_window_create(current_menu_url, bw,
- content_get_url(h), true, false);
- break;
-
- /* save actions */
- case BROWSER_OBJECT_SAVE:
- case BROWSER_OBJECT_EXPORT_SPRITE:
- case BROWSER_OBJECT_EXPORT_DRAW:
- h = current_menu_object;
- /* Fall through */
- case BROWSER_SAVE:
- case BROWSER_SAVE_COMPLETE:
- case BROWSER_EXPORT_DRAW:
- case BROWSER_EXPORT_PDF:
- case BROWSER_EXPORT_TEXT:
- case BROWSER_SAVE_URL_URI:
- case BROWSER_SAVE_URL_URL:
- case BROWSER_SAVE_URL_TEXT:
- if (!h)
- return false;
- /* Fall through */
- ro_gui_menu_prepare_action(owner, action, true);
- ro_gui_dialog_open_persistent(owner, dialog_saveas,
- windows_at_pointer);
- return true;
-
- /* selection actions */
- case BROWSER_SELECTION_SAVE:
- ro_gui_menu_prepare_action(owner, action, true);
- ro_gui_dialog_open_persistent(owner, dialog_saveas,
- windows_at_pointer);
- return true;
- case BROWSER_SELECTION_COPY:
- browser_window_key_press(bw, KEY_COPY_SELECTION);
- break;
- case BROWSER_SELECTION_CUT:
- browser_window_key_press(bw, KEY_CUT_SELECTION);
- return true;
- case BROWSER_SELECTION_PASTE:
- browser_window_key_press(bw, KEY_PASTE);
- return true;
- case BROWSER_SELECTION_ALL:
- browser_window_key_press(bw, KEY_SELECT_ALL);
- break;
- case BROWSER_SELECTION_CLEAR:
- browser_window_key_press(bw, KEY_CLEAR_SELECTION);
- break;
-
- /* navigation actions */
- case BROWSER_NAVIGATE_HOME:
- if (!bw)
- return false;
- if ((option_homepage_url) &&
- (option_homepage_url[0])) {
- browser_window_go(g->bw,
- option_homepage_url, 0, true);
- } else {
- snprintf(url, sizeof url,
- "file:///<NetSurf$Dir>/Docs/welcome/index_%s",
- option_language);
- browser_window_go(g->bw, url, 0, true);
- }
- return true;
- case BROWSER_NAVIGATE_BACK:
- if ((!bw) || (!bw->history))
- return false;
- history_back(bw, bw->history);
- return true;
- case BROWSER_NAVIGATE_FORWARD:
- if ((!bw) || (!bw->history))
- return false;
- history_forward(bw, bw->history);
- return true;
- case BROWSER_NAVIGATE_UP:
- if ((!bw) || (!h))
- return false;
- return ro_gui_window_navigate_up(bw->window,
- content_get_url(h));
- case BROWSER_NAVIGATE_RELOAD:
- case BROWSER_NAVIGATE_RELOAD_ALL:
- if (!bw)
- return false;
- browser_window_reload(bw,
- (action == BROWSER_NAVIGATE_RELOAD_ALL));
- return true;
- case BROWSER_NAVIGATE_STOP:
- if (!bw)
- return false;
- browser_window_stop(bw);
- return true;
- case BROWSER_NAVIGATE_URL:
- ro_gui_menu_prepare_action(owner, action, true);
- ro_gui_dialog_open_persistent(NULL, dialog_openurl,
- windows_at_pointer);
- return true;
-
- /* browser window/display actions */
- case BROWSER_SCALE_VIEW:
- if (!h)
- return false;
- ro_gui_menu_prepare_action(owner, action, true);
- ro_gui_dialog_open_persistent(g->window, dialog_zoom,
- windows_at_pointer);
- return true;
- case BROWSER_FIND_TEXT:
- if (!h || (content_get_type(h) != CONTENT_TEXTPLAIN &&
- content_get_type(h) != CONTENT_HTML))
- return false;
- ro_gui_menu_prepare_action(owner, action, true);
- ro_gui_dialog_open_persistent(g->window,
- dialog_search, windows_at_pointer);
- return true;
- case BROWSER_IMAGES_BACKGROUND:
- if (!g)
- return false;
- g->option.background_images =
- !g->option.background_images;
- gui_window_redraw_window(g);
- return true;
- case BROWSER_BUFFER_ANIMS:
- if (!g)
- return false;
- g->option.buffer_animations =
- !g->option.buffer_animations;
- break;
- case BROWSER_BUFFER_ALL:
- if (!g)
- return false;
- g->option.buffer_everything =
- !g->option.buffer_everything;
- break;
- case BROWSER_SAVE_VIEW:
- if (!bw)
- return false;
- ro_gui_window_default_options(bw);
- ro_gui_save_options();
- return true;
- case BROWSER_WINDOW_DEFAULT:
- if (!g)
- return false;
- ro_gui_screen_size(&option_window_screen_width,
- &option_window_screen_height);
- state.w = current_menu_window;
- 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);
- }
- option_window_x = state.visible.x0;
- option_window_y = state.visible.y0;
- option_window_width =
- state.visible.x1 - state.visible.x0;
- option_window_height =
- state.visible.y1 - state.visible.y0;
- ro_gui_save_options();
- return true;
- case BROWSER_WINDOW_STAGGER:
- option_window_stagger = !option_window_stagger;
- ro_gui_save_options();
- return true;
- case BROWSER_WINDOW_COPY:
- option_window_size_clone = !option_window_size_clone;
- ro_gui_save_options();
- return true;
- case BROWSER_WINDOW_RESET:
- option_window_screen_width = 0;
- option_window_screen_height = 0;
- ro_gui_save_options();
- return true;
-
- /* toolbar actions */
- case TOOLBAR_BUTTONS:
- assert(t);
- t->display_buttons = !t->display_buttons;
- ro_gui_theme_refresh_toolbar(t);
- return true;
- case TOOLBAR_ADDRESS_BAR:
- assert(t);
- t->display_url = !t->display_url;
- ro_gui_theme_refresh_toolbar(t);
- if (t->display_url)
- ro_gui_set_caret_first(t->toolbar_handle);
- return true;
- case TOOLBAR_THROBBER:
- assert(t);
- t->display_throbber = !t->display_throbber;
- ro_gui_theme_refresh_toolbar(t);
- return true;
- case TOOLBAR_EDIT:
- assert(t);
- ro_gui_theme_toggle_edit(t);
- return true;
-
- /* misc actions */
- case APPLICATION_QUIT:
- if (ro_gui_prequit()) {
- LOG(("QUIT in response to user request"));
- netsurf_quit = true;
- }
- return true;
- case CHOICES_SHOW:
- ro_gui_configure_show();
- return true;
-
- /* unknown action */
- default:
- return false;
- }
- return false;
-}
-
-
-/**
- * Prepares an action for use.
- *
- * \param owner the window to prepare the action for
- * \param action the action to prepare
- * \param windows whether to update sub-windows
- */
-void ro_gui_menu_prepare_action(wimp_w owner, menu_action action,
- bool windows)
-{
- struct gui_window *g;
- struct browser_window *bw;
- hlcache_handle *h;
- struct toolbar *t;
- bool result = false;
- int checksum = 0;
- os_error *error;
- char *parent;
- url_func_result res;
- bool compare;
- bool is_cookies, is_hotlist, is_global_history;
-
- ro_gui_menu_get_window_details(owner, &g, &bw, &h, &t,
- &is_cookies, &is_hotlist, &is_global_history);
- if (current_menu_open)
- checksum = ro_gui_menu_get_checksum();
- if (!h) {
- current_menu_object = NULL;
- current_menu_url = NULL;
- }
-
- switch (action) {
-
- /* help actions */
- case HELP_LAUNCH_INTERACTIVE:
- result = ro_gui_interactive_help_available()
- && option_interactive_help;
- ro_gui_menu_set_entry_ticked(current_menu,
- action, result);
- ro_gui_save_options();
- break;
-
- /* history actions */
- case HISTORY_SHOW_LOCAL:
- ro_gui_menu_set_entry_shaded(current_menu, action,
- (!bw || (!bw->history) ||
- !(h || history_back_available(bw->history) ||
- history_forward_available(bw->history))));
- break;
-
- /* hotlist actions */
- case HOTLIST_ADD_URL:
- ro_gui_menu_set_entry_shaded(current_menu, action,
- h == NULL);
- break;
-
- /* page actions */
- case BROWSER_PAGE:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !h ||
- (content_get_type(h) != CONTENT_HTML &&
- content_get_type(h) != CONTENT_TEXTPLAIN));
- break;
- case BROWSER_PAGE_INFO:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !h);
- if ((windows) && (h))
- ro_gui_menu_prepare_pageinfo(g);
- break;
- case BROWSER_PRINT:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !h);
- if ((t) && (t->type == THEME_BROWSER_TOOLBAR))
- ro_gui_set_icon_shaded_state(
- t->toolbar_handle,
- ICON_TOOLBAR_PRINT, !h);
- if ((windows) && (h))
- ro_gui_print_prepare(g);
- if ((t) && (!t->editor) &&
- (t->type == THEME_BROWSER_TOOLBAR))
- ro_gui_set_icon_shaded_state(
- t->toolbar_handle,
- ICON_TOOLBAR_PRINT, !h);
- break;
- case BROWSER_NEW_WINDOW:
- case BROWSER_VIEW_SOURCE:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !h);
- break;
-
- /* object actions */
- case BROWSER_OBJECT:
- ro_gui_menu_set_entry_shaded(current_menu, action,
- !current_menu_object &&
- !current_menu_url);
- break;
-
- case BROWSER_OBJECT_LINK:
- ro_gui_menu_set_entry_shaded(current_menu, action,
- !current_menu_url);
- break;
-
- case BROWSER_OBJECT_INFO:
- if (windows && current_menu_object)
- ro_gui_menu_prepare_objectinfo(
- current_menu_object,
- current_menu_url);
- /* Fall through */
- case BROWSER_OBJECT_RELOAD:
- case BROWSER_OBJECT_OBJECT:
- ro_gui_menu_set_entry_shaded(current_menu, action,
- !current_menu_object);
- break;
-
- case BROWSER_OBJECT_PRINT:
- /* not yet implemented */
- ro_gui_menu_set_entry_shaded(current_menu, action,
- true);
- break;
-
- /* save actions (browser, hotlist, history) */
- case BROWSER_OBJECT_SAVE:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !current_menu_object);
- if (windows && current_menu_object)
- ro_gui_save_prepare(GUI_SAVE_OBJECT_ORIG,
- current_menu_object,
- NULL, NULL, NULL);
- break;
- case BROWSER_OBJECT_EXPORT:
- case BROWSER_OBJECT_EXPORT_SPRITE:
- case BROWSER_OBJECT_EXPORT_DRAW: {
- bool exp_sprite = false;
- bool exp_draw = false;
-
- if (current_menu_object)
- h = current_menu_object;
-
- if (h) {
- switch (content_get_type(h)) {
-/* \todo - this classification should prob be done in content_() */
- /* bitmap types (Sprite export possible) */
-#ifdef WITH_JPEG
- case CONTENT_JPEG:
-#endif
-#ifdef WITH_MNG
- case CONTENT_JNG:
- case CONTENT_MNG:
-#endif
-#ifdef WITH_GIF
- case CONTENT_GIF:
-#endif
-#ifdef WITH_BMP
- case CONTENT_BMP:
- case CONTENT_ICO:
-#endif
-#if defined(WITH_MNG) || defined(WITH_PNG)
- case CONTENT_PNG:
-#endif
-#ifdef WITH_SPRITE
- case CONTENT_SPRITE:
-#endif
- exp_sprite = true;
- break;
-
- /* vector types (Draw export possible) */
-#if defined(WITH_NS_SVG) || defined(WITH_RSVG)
- case CONTENT_SVG:
-#endif
-#ifdef WITH_DRAW
- case CONTENT_DRAW:
-#endif
- exp_draw = true;
- break;
-
- default: break;
- }
- }
-
- switch (action) {
- case BROWSER_OBJECT_EXPORT_SPRITE:
- if (!exp_sprite)
- h = NULL;
- break;
- case BROWSER_OBJECT_EXPORT_DRAW:
- if (!exp_draw)
- h = NULL;
- break;
- default:
- if (!exp_sprite && !exp_draw)
- h = NULL;
- break;
- }
-
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !h);
- if ((h) && (windows))
- ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE, h, NULL, NULL, NULL);
- }
- break;
- case BROWSER_LINK_SAVE_URI:
- case BROWSER_LINK_SAVE_URL:
- case BROWSER_LINK_SAVE_TEXT:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !current_menu_url);
- if (windows && current_menu_url) {
- gui_save_type save_type;
- switch (action) {
- case BROWSER_LINK_SAVE_URI:
- save_type = GUI_SAVE_LINK_URI;
- break;
- case BROWSER_LINK_SAVE_URL:
- save_type = GUI_SAVE_LINK_URL;
- break;
- default:
- save_type = GUI_SAVE_LINK_TEXT;
- break;
- }
- ro_gui_save_prepare(save_type, NULL, NULL,
- current_menu_url, NULL);
- }
- break;
-
- case BROWSER_SELECTION:
- /* make menu available if there's anything that /could/
- * be selected */
- ro_gui_menu_set_entry_shaded(current_menu, action,
- !h || (content_get_type(h) != CONTENT_HTML &&
- content_get_type(h) != CONTENT_TEXTPLAIN));
- break;
- case BROWSER_SELECTION_SAVE:
- if (h && (!bw->sel || !selection_defined(bw->sel)))
- h = NULL;
- ro_gui_menu_set_entry_shaded(current_menu, action, !h);
- if ((h) && (windows))
- ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL, bw->sel, NULL, NULL);
- break;
- case BROWSER_SELECTION_COPY:
- ro_gui_menu_set_entry_shaded(current_menu, action,
- !(h && bw->sel && selection_defined(bw->sel)));
- break;
- case BROWSER_SELECTION_CUT:
- ro_gui_menu_set_entry_shaded(current_menu, action,
- !(h && bw->sel && selection_defined(bw->sel)
- && !selection_read_only(bw->sel)));
- break;
- case BROWSER_SELECTION_PASTE:
- ro_gui_menu_set_entry_shaded(current_menu, action,
- !(h && bw->paste_callback));
- break;
- case BROWSER_SAVE:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !h);
- if ((h) && (windows))
- ro_gui_save_prepare(GUI_SAVE_SOURCE, h, NULL, NULL, NULL);
- if ((t) && (!t->editor) &&
- (t->type == THEME_BROWSER_TOOLBAR))
- ro_gui_set_icon_shaded_state(
- t->toolbar_handle,
- ICON_TOOLBAR_SAVE, !h);
- break;
- case BROWSER_SAVE_COMPLETE:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !h);
- if ((h) && (windows))
- ro_gui_save_prepare(GUI_SAVE_COMPLETE, h, NULL, NULL, NULL);
- break;
- case BROWSER_EXPORT_DRAW:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !h);
- if ((h) && (windows))
- ro_gui_save_prepare(GUI_SAVE_DRAW, h, NULL, NULL, NULL);
- break;
- case BROWSER_EXPORT_PDF:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !h);
- if ((h) && (windows))
- ro_gui_save_prepare(GUI_SAVE_PDF, h, NULL, NULL, NULL);
- break;
- case BROWSER_EXPORT_TEXT:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !h);
- if ((h) && (windows))
- ro_gui_save_prepare(GUI_SAVE_TEXT, h, NULL, NULL, NULL);
- break;
- case BROWSER_OBJECT_SAVE_URL_URI:
- if (h && content_get_type(h) == CONTENT_HTML)
- h = current_menu_object;
- /* Fall through */
- case BROWSER_SAVE_URL_URI:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !h);
- if ((h) && (windows))
- ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL,
- NULL,
- content_get_url(h),
- content_get_title(h));
- break;
- case BROWSER_OBJECT_SAVE_URL_URL:
- if (h && content_get_type(h) == CONTENT_HTML)
- h = current_menu_object;
- /* Fall through */
- case BROWSER_SAVE_URL_URL:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !h);
- if ((h) && (windows))
- ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL,
- NULL,
- content_get_url(h),
- content_get_title(h));
- break;
- case BROWSER_OBJECT_SAVE_URL_TEXT:
- h = current_menu_object;
- /* Fall through */
- case BROWSER_SAVE_URL_TEXT:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !h);
- if ((h) && (windows))
- ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL,
- NULL,
- content_get_url(h),
- content_get_title(h));
- break;
-
- /* navigation actions */
- case BROWSER_NAVIGATE_BACK:
- result = browser_window_back_available(bw);
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !result);
- if ((t) && (!t->editor) &&
- (t->type == THEME_BROWSER_TOOLBAR))
- ro_gui_set_icon_shaded_state(
- t->toolbar_handle,
- ICON_TOOLBAR_BACK, !result);
- break;
- case BROWSER_NAVIGATE_FORWARD:
- result = browser_window_forward_available(bw);
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !result);
- if ((t) && (!t->editor) &&
- (t->type == THEME_BROWSER_TOOLBAR))
- ro_gui_set_icon_shaded_state(
- t->toolbar_handle,
- ICON_TOOLBAR_FORWARD, !result);
- break;
- case BROWSER_NAVIGATE_UP:
- result = (bw && h);
- if (result) {
- res = url_parent(content_get_url(h), &parent);
- if (res == URL_FUNC_OK) {
- res = url_compare(content_get_url(h),
- parent, false,
- &compare);
- if (res == URL_FUNC_OK)
- result = !compare;
- free(parent);
- } else {
- result = false;
- }
- }
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !result);
- if ((t) && (!t->editor) &&
- (t->type == THEME_BROWSER_TOOLBAR))
- ro_gui_set_icon_shaded_state(
- t->toolbar_handle,
- ICON_TOOLBAR_UP, !result);
- break;
- case BROWSER_NAVIGATE_RELOAD:
- case BROWSER_NAVIGATE_RELOAD_ALL:
- result = browser_window_reload_available(bw);
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !result);
- if ((t) && (!t->editor) &&
- (t->type == THEME_BROWSER_TOOLBAR))
- ro_gui_set_icon_shaded_state(
- t->toolbar_handle,
- ICON_TOOLBAR_RELOAD, !result);
- break;
- case BROWSER_NAVIGATE_STOP:
- result = browser_window_stop_available(bw);
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !result);
- if ((t) && (!t->editor) &&
- (t->type == THEME_BROWSER_TOOLBAR))
- ro_gui_set_icon_shaded_state(
- t->toolbar_handle,
- ICON_TOOLBAR_STOP, !result);
- break;
- case BROWSER_NAVIGATE_URL:
- if (windows)
- ro_gui_dialog_prepare_open_url();
- break;
-
- /* display actions */
- case BROWSER_SCALE_VIEW:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !h);
- if ((h) && (windows))
- ro_gui_dialog_prepare_zoom(g);
- if ((t) && (!t->editor) &&
- (t->type == THEME_BROWSER_TOOLBAR))
- ro_gui_set_icon_shaded_state(
- t->toolbar_handle,
- ICON_TOOLBAR_SCALE, !h);
- break;
- case BROWSER_FIND_TEXT:
- result = !h || (content_get_type(h) != CONTENT_HTML &&
- content_get_type(h) != CONTENT_TEXTPLAIN);
- ro_gui_menu_set_entry_shaded(current_menu,
- action, result);
- if ((!result) && (windows)) {
- ro_gui_search_prepare(g->bw);
- }
- if ((t) && (!t->editor) &&
- (t->type == THEME_BROWSER_TOOLBAR))
- ro_gui_set_icon_shaded_state(
- t->toolbar_handle,
- ICON_TOOLBAR_SEARCH, result);
- break;
- case BROWSER_IMAGES_FOREGROUND:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, true);
- ro_gui_menu_set_entry_ticked(current_menu,
- action, true);
- break;
- case BROWSER_IMAGES_BACKGROUND:
- if (g)
- ro_gui_menu_set_entry_ticked(current_menu,
- action, g->option.background_images);
- break;
- case BROWSER_BUFFER_ANIMS:
- if (g) {
- ro_gui_menu_set_entry_shaded(current_menu,
- action, g->option.buffer_everything);
- ro_gui_menu_set_entry_ticked(current_menu,
- action,
- g->option.buffer_animations ||
- g->option.buffer_everything);
- }
- break;
- case BROWSER_BUFFER_ALL:
- if (g)
- ro_gui_menu_set_entry_ticked(current_menu,
- action, g->option.buffer_everything);
- break;
- case BROWSER_WINDOW_STAGGER:
- ro_gui_menu_set_entry_shaded(current_menu, action,
- option_window_screen_width == 0);
- ro_gui_menu_set_entry_ticked(current_menu, action,
- ((option_window_screen_width == 0) ||
- option_window_stagger));
- break;
- case BROWSER_WINDOW_COPY:
- ro_gui_menu_set_entry_ticked(current_menu, action,
- option_window_size_clone);
- break;
- case BROWSER_WINDOW_RESET:
- ro_gui_menu_set_entry_shaded(current_menu, action,
- option_window_screen_width == 0);
- break;
-
- /* tree actions */
- case TREE_SELECTION:
- break;
-
- /* toolbar actions */
- case TOOLBAR_BUTTONS:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, (!t || (t->editor)));
- ro_gui_menu_set_entry_ticked(current_menu,
- action, (t &&
- ((t->display_buttons) || (t->editor))));
- break;
- case TOOLBAR_ADDRESS_BAR:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !t);
- ro_gui_menu_set_entry_ticked(current_menu, action,
- (t && t->display_url));
- break;
- case TOOLBAR_THROBBER:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !t);
- ro_gui_menu_set_entry_ticked(current_menu, action,
- (t && t->display_throbber));
- break;
- case TOOLBAR_EDIT:
- ro_gui_menu_set_entry_shaded(current_menu,
- action, !t);
- ro_gui_menu_set_entry_ticked(current_menu, action,
- (t && t->editor));
- break;
-
- /* unknown action */
- default:
- return;
- }
-
- /* update open menus */
- if ((current_menu_open) &&
- (checksum != ro_gui_menu_get_checksum())) {
- error = xwimp_create_menu(current_menu, 0, 0);
- if (error) {
- LOG(("xwimp_create_menu: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("MenuError", error->errmess);
- }
- }
-}
-
-
-/**
- * Gets various details relating to a window
- *
- * \param w the window to complete information for
- */
-void ro_gui_menu_get_window_details(wimp_w w, struct gui_window **g,
- struct browser_window **bw, hlcache_handle **h,
- struct toolbar **toolbar,
- bool *is_cookies, bool *is_hotlist, bool *is_global_history)
-{
- *is_cookies = false;
- *is_hotlist = false;
- *is_global_history = false;
-
- *g = ro_gui_window_lookup(w);
-
- if (*g) {
- *bw = (*g)->bw;
- *toolbar = (*g)->toolbar;
- if (*bw)
- *h = (*bw)->current_content;
- } else {
- *bw = NULL;
- *h = NULL;
- if (ro_gui_hotlist_check_window(w)) {
- *is_hotlist = true;
-// *toolbar = treeview_window->toolbar;
- } else if (ro_gui_global_history_check_window(w)) {
- *is_global_history = true;
-// *toolbar = treeview_window->toolbar;
- } else if (ro_gui_cookies_check_window(w)) {
- *is_cookies = true;
-// *toolbar = treeview_window->toolbar;
- } else {
- *toolbar = NULL;
- }
- }
-}
-
-
-/**
* Calculates a simple checksum for the current menu state
*/
int ro_gui_menu_get_checksum(void)
@@ -2364,3 +944,4 @@ bool ro_gui_menu_translate(struct menu_definition *menu)
return true;
}
+
diff --git a/riscos/menus.h b/riscos/menus.h
index 197aee9d1..ef768e96d 100644
--- a/riscos/menus.h
+++ b/riscos/menus.h
@@ -23,13 +23,9 @@
#include "oslib/wimp.h"
#include "riscos/gui.h"
-extern wimp_menu *iconbar_menu, *browser_menu, *hotlist_menu, *cookies_menu,
- *global_history_menu, *image_quality_menu,
- *browser_toolbar_menu, *tree_toolbar_menu, *proxy_type_menu;
-extern wimp_menu *languages_menu, *url_suggest_menu;
+extern wimp_menu *image_quality_menu, *proxy_type_menu, *languages_menu;
extern wimp_menu *current_menu;
-extern int iconbar_menu_height;
typedef enum {
@@ -170,21 +166,16 @@ struct ns_menu {
void ro_gui_menu_init(void);
-void ro_gui_menu_create(wimp_menu* menu, int x, int y, wimp_w w, bool prepare);
-bool ro_gui_menu_handle_action(wimp_w owner, menu_action action,
- bool windows_at_pointer);
-void ro_gui_menu_prepare_action(wimp_w owner, menu_action action,
- bool windows);
-void ro_gui_menu_closed(bool cleanup);
-void ro_gui_menu_objects_moved(void);
+void ro_gui_menu_create(wimp_menu* menu, int x, int y, wimp_w w);
+void ro_gui_menu_closed(void);
void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i);
+void ro_gui_menu_window_changed(wimp_w from, wimp_w to);
void ro_gui_menu_selection(wimp_selection* selection);
void ro_gui_menu_warning(wimp_message_menu_warning *warning);
+void ro_gui_menu_refresh(wimp_menu *menu);
void ro_gui_menu_init_structure(wimp_menu *menu, int entries);
-void ro_gui_prepare_navigate(struct gui_window *gui);
const char *ro_gui_menu_find_menu_entry_key(wimp_menu *menu,
const char *translated);
-
wimp_menu *ro_gui_menu_define_menu(const struct ns_menu *menu);
void ro_gui_menu_set_entry_shaded(wimp_menu *menu, menu_action action,
bool shaded);
diff --git a/riscos/plugin.c b/riscos/plugin.c
index 340eaaf3e..19fd2b806 100644
--- a/riscos/plugin.c
+++ b/riscos/plugin.c
@@ -63,7 +63,7 @@
#include "riscos/gui.h"
#include "riscos/options.h"
#include "riscos/plugin.h"
-#include "riscos/theme.h"
+#include "riscos/toolbar.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/url.h"
@@ -362,8 +362,7 @@ void plugin_open(struct content *c, struct browser_window *bw,
pmo.bbox.x0 = 10;
/* avoid toolbar */
- pmo.bbox.y1 = -10 - (bw->window->toolbar ?
- bw->window->toolbar->height : 0);
+ pmo.bbox.y1 = -10 - ro_toolbar_height(bw->window->toolbar);
pmo.bbox.x1 = (state.visible.x1 - state.visible.x0) - 10;
pmo.bbox.y0 = (state.visible.y0 - state.visible.y1) - 10;
}
@@ -501,8 +500,8 @@ void plugin_reformat(struct content *c, int width, int height)
/* standalone */
x = 10 / 2;
/* avoid toolbar */
- y = (10 + (c->data.plugin.bw->window->toolbar ?
- c->data.plugin.bw->window->toolbar->height : 0)) / 2;
+ y = (10 + ro_toolbar_height(
+ c->data.plugin.bw->window->toolbar0)) / 2;
}
pmr.size = 52;
diff --git a/riscos/print.c b/riscos/print.c
index 1a66e7e12..807b12eeb 100644
--- a/riscos/print.c
+++ b/riscos/print.c
@@ -532,7 +532,7 @@ void ro_print_cleanup(void)
print_text_black = false;
print_prev_message = 0;
print_max_sheets = -1;
- ro_gui_menu_closed(true);
+ ro_gui_menu_closed();
ro_gui_dialog_close(dialog_print);
}
diff --git a/riscos/search.c b/riscos/search.c
index 502a2cb02..ec98b969c 100644
--- a/riscos/search.c
+++ b/riscos/search.c
@@ -66,6 +66,9 @@ wimp_menu *recent_search_menu = (wimp_menu *)&menu_recent;
static void ro_gui_search_end(wimp_w w);
static bool ro_gui_search_next(wimp_w w);
+static bool ro_gui_search_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer);
+static bool ro_gui_search_prepare_menu(void);
static bool ro_gui_search_click(wimp_pointer *pointer);
static bool ro_gui_search_keypress(wimp_key *key);
static search_flags_t ro_gui_search_update_flags(void);
@@ -90,6 +93,8 @@ void ro_gui_search_init(void)
ro_gui_search_keypress);
ro_gui_wimp_event_register_close_window(dialog_search,
ro_gui_search_end);
+ ro_gui_wimp_event_register_menu_prepare(dialog_search,
+ ro_gui_search_menu_prepare);
ro_gui_wimp_event_register_menu_gright(dialog_search,
ICON_SEARCH_TEXT, ICON_SEARCH_MENU,
recent_search_menu);
@@ -117,7 +122,7 @@ void ro_gui_search_init(void)
bool ro_gui_search_next(wimp_w w)
{
search_data.search_insert = true;
- search_flags_t flags = SEARCH_FLAG_FORWARDS |
+ search_flags_t flags = SEARCH_FLAG_FORWARDS |
ro_gui_search_update_flags();
if (search_verify_new(search_data.search_window,
&ro_gui_search_callbacks, NULL))
@@ -127,13 +132,39 @@ bool ro_gui_search_next(wimp_w w)
return false;
}
+
+/**
+ * Callback to prepare menus in the Search dialog. At present, this
+ * only has to handle the previous search pop-up.
+ *
+ * \param w The window handle owning the menu.
+ * \param i The icon handle owning the menu.
+ * \param *menu The menu to be prepared.
+ * \param *pointer The associated mouse click event block, or NULL
+ * on an Adjust-click re-opening.
+ * \return true if the event was handled; false if not.
+ */
+
+bool ro_gui_search_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer)
+{
+ if (menu != recent_search_menu || i != ICON_SEARCH_MENU)
+ return false;
+
+ if (pointer != NULL)
+ return ro_gui_search_prepare_menu();
+
+ return true;
+}
+
+
bool ro_gui_search_click(wimp_pointer *pointer)
{
search_flags_t flags;
switch (pointer->i) {
case ICON_SEARCH_FIND_PREV:
search_data.search_insert = true;
- flags = ~SEARCH_FLAG_FORWARDS &
+ flags = ~SEARCH_FLAG_FORWARDS &
ro_gui_search_update_flags();
if (search_verify_new(search_data.search_window,
&ro_gui_search_callbacks, NULL))
@@ -144,7 +175,7 @@ bool ro_gui_search_click(wimp_pointer *pointer)
ICON_SEARCH_TEXT));
return true;
case ICON_SEARCH_CASE_SENSITIVE:
- flags = SEARCH_FLAG_FORWARDS |
+ flags = SEARCH_FLAG_FORWARDS |
ro_gui_search_update_flags();
if (search_verify_new(search_data.search_window,
&ro_gui_search_callbacks, NULL))
@@ -157,7 +188,7 @@ bool ro_gui_search_click(wimp_pointer *pointer)
case ICON_SEARCH_SHOW_ALL:
if (search_data.search_window->search_context != NULL)
search_show_all(ro_gui_get_icon_selected_state(
- pointer->w, pointer->i),
+ pointer->w, pointer->i),
search_data.search_window->
search_context);
return true;
@@ -309,19 +340,19 @@ bool ro_gui_search_keypress(wimp_key *key)
ICON_SEARCH_CASE_SENSITIVE);
ro_gui_set_icon_selected_state(dialog_search,
ICON_SEARCH_CASE_SENSITIVE, !state);
- flags = SEARCH_FLAG_FORWARDS |
+ flags = SEARCH_FLAG_FORWARDS |
ro_gui_search_update_flags();
if (search_verify_new(search_data.search_window,
&ro_gui_search_callbacks, NULL))
search_step(search_data.search_window->
search_context, flags,
ro_gui_get_icon_string(
- dialog_search,
+ dialog_search,
ICON_SEARCH_TEXT));
return true;
case IS_WIMP_KEY | wimp_KEY_UP:
search_data.search_insert = true;
- flags = ~SEARCH_FLAG_FORWARDS &
+ flags = ~SEARCH_FLAG_FORWARDS &
ro_gui_search_update_flags();
if (search_verify_new(search_data.search_window,
&ro_gui_search_callbacks, NULL))
@@ -333,7 +364,7 @@ bool ro_gui_search_keypress(wimp_key *key)
return true;
case IS_WIMP_KEY | wimp_KEY_DOWN:
search_data.search_insert = true;
- flags = SEARCH_FLAG_FORWARDS |
+ flags = SEARCH_FLAG_FORWARDS |
ro_gui_search_update_flags();
if (search_verify_new(search_data.search_window,
&ro_gui_search_callbacks, NULL))
@@ -353,7 +384,7 @@ bool ro_gui_search_keypress(wimp_key *key)
search_data.
search_window->
search_context);
- ro_gui_search_set_forward_state(true,
+ ro_gui_search_set_forward_state(true,
search_data.search_window);
ro_gui_search_set_back_state(true,
search_data.search_window);
@@ -362,15 +393,15 @@ bool ro_gui_search_keypress(wimp_key *key)
if (key->c == 8 || /* backspace */
key->c == 21 || /* ctrl u */
(key->c >= 0x20 && key->c <= 0x7f)) {
- flags = SEARCH_FLAG_FORWARDS |
+ flags = SEARCH_FLAG_FORWARDS |
ro_gui_search_update_flags();
- if (search_data.search_window->search_context
+ if (search_data.search_window->search_context
!= NULL)
search_destroy_context(
search_data.
search_window->
search_context);
- ro_gui_search_set_forward_state(true,
+ ro_gui_search_set_forward_state(true,
search_data.search_window);
ro_gui_search_set_back_state(true,
search_data.search_window);
@@ -378,7 +409,7 @@ bool ro_gui_search_keypress(wimp_key *key)
&ro_gui_search_callbacks,
NULL))
search_step(search_data.search_window->
- search_context, flags,
+ search_context, flags,
ro_gui_get_icon_string(
dialog_search,
ICON_SEARCH_TEXT));
@@ -438,7 +469,7 @@ void ro_gui_search_set_hourglass(bool active, void *p)
void ro_gui_search_set_forward_state(bool active, void *p)
{
- ro_gui_set_icon_shaded_state(dialog_search, ICON_SEARCH_FIND_NEXT,
+ ro_gui_set_icon_shaded_state(dialog_search, ICON_SEARCH_FIND_NEXT,
!active);
}
diff --git a/riscos/sslcert.c b/riscos/sslcert.c
index f2af924a0..f4e4f48b1 100644
--- a/riscos/sslcert.c
+++ b/riscos/sslcert.c
@@ -149,8 +149,8 @@ void gui_cert_verify(const char *url,
/* Create the SSL data and build a tree from it. */
- sslcert_window->tv = ro_treeview_create(sslcert_window->pane, NULL,
- sslcert_get_tree_flags());
+ sslcert_window->tv = ro_treeview_create(sslcert_window->pane,
+ NULL, NULL, sslcert_get_tree_flags());
if (sslcert_window->tv == NULL) {
LOG(("Failed to allocate treeview"));
free(sslcert_window);
diff --git a/riscos/textselection.c b/riscos/textselection.c
index 07a87e50b..1f3809f50 100644
--- a/riscos/textselection.c
+++ b/riscos/textselection.c
@@ -30,6 +30,7 @@
#include "desktop/selection.h"
#include "desktop/textinput.h"
#include "riscos/gui.h"
+#include "riscos/menus.h"
#include "riscos/message.h"
#include "riscos/save.h"
#include "riscos/textselection.h"
@@ -260,6 +261,8 @@ bool gui_empty_clipboard(void)
void gui_clear_selection(struct gui_window *g)
{
+ /* Refresh any open menu, in case it's the browser window menu. */
+ ro_gui_menu_refresh(0);
}
@@ -566,7 +569,7 @@ void ro_gui_selection_dragging(wimp_message *message)
bw = g->bw;
h = bw->current_content;
- if (h && content_get_type(h) == CONTENT_HTML &&
+ if (h && content_get_type(h) == CONTENT_HTML &&
html_get_box_tree(h)) {
struct box *box = html_get_box_tree(h);
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;
-}
diff --git a/riscos/theme.h b/riscos/theme.h
index eb96d2c6b..4a4ba1cb2 100644
--- a/riscos/theme.h
+++ b/riscos/theme.h
@@ -17,60 +17,32 @@
*/
/** \file
- * Window themes and toolbars (interface).
+ * Window themes(interface).
*/
#include <stdbool.h>
+#include "oslib/osspriteop.h"
#ifndef _NETSURF_RISCOS_THEME_H_
#define _NETSURF_RISCOS_THEME_H_
-/* icon numbers for browser toolbars */
-#define ICON_TOOLBAR_BACK 0
-#define ICON_TOOLBAR_FORWARD 1
-#define ICON_TOOLBAR_STOP 2
-#define ICON_TOOLBAR_RELOAD 3
-#define ICON_TOOLBAR_HOME 4
-#define ICON_TOOLBAR_HISTORY 5
-#define ICON_TOOLBAR_SAVE 6
-#define ICON_TOOLBAR_PRINT 7
-#define ICON_TOOLBAR_BOOKMARK 8
-#define ICON_TOOLBAR_SCALE 9
-#define ICON_TOOLBAR_SEARCH 10
-#define ICON_TOOLBAR_UP 11
-#define ICON_TOOLBAR_LAST 12
-#define ICON_TOOLBAR_SURROUND 12 // Must be after highest toolbar icon
-#define ICON_TOOLBAR_FAVICON 13
-#define ICON_TOOLBAR_URL 14
-#define ICON_TOOLBAR_SUGGEST 15
-#define ICON_TOOLBAR_THROBBER 16
+/** Theme styles, collecting groups of attributes for different locations. */
-/* icon numbers for hotlist/history toolbars */
-#define ICON_TOOLBAR_DELETE 0
-#define ICON_TOOLBAR_EXPAND 1
-#define ICON_TOOLBAR_OPEN 2
-#define ICON_TOOLBAR_COOKIES_LAST 4
-#define ICON_TOOLBAR_LAUNCH 3
-#define ICON_TOOLBAR_HISTORY_LAST 4
-#define ICON_TOOLBAR_CREATE 4 // must be after last history icon
-#define ICON_TOOLBAR_HOTLIST_LAST 5
+typedef enum {
+ THEME_STYLE_NONE = 0,
+ THEME_STYLE_BROWSER_TOOLBAR,
+ THEME_STYLE_HOTLIST_TOOLBAR,
+ THEME_STYLE_COOKIES_TOOLBAR,
+ THEME_STYLE_GLOBAL_HISTORY_TOOLBAR,
+ THEME_STYLE_STATUS_BAR
+} theme_style;
-/* editing toolbar separator number */
-#define ICON_TOOLBAR_SEPARATOR_BROWSER 11
-#define ICON_TOOLBAR_SEPARATOR_HOTLIST 5
-#define ICON_TOOLBAR_SEPARATOR_HISTORY 4
-#define ICON_TOOLBAR_SEPARATOR_COOKIES 3
+/** Theme elements, which belong to styles. */
typedef enum {
- THEME_BROWSER_TOOLBAR,
- THEME_HOTLIST_TOOLBAR,
- THEME_HISTORY_TOOLBAR,
- THEME_COOKIES_TOOLBAR,
- THEME_BROWSER_EDIT_TOOLBAR,
- THEME_HOTLIST_EDIT_TOOLBAR,
- THEME_HISTORY_EDIT_TOOLBAR,
- THEME_COOKIES_EDIT_TOOLBAR
-} toolbar_type;
+ THEME_ELEMENT_FOREGROUND,
+ THEME_ELEMENT_BACKGROUND
+} theme_element;
struct theme_file_header {
unsigned int magic_value;
@@ -89,18 +61,6 @@ struct theme_file_header {
unsigned int decompressed_sprite_size;
};
-struct toolbar_icon {
- int icon_number; /**< wimp icon number */
- bool display; /**< whether to display the icon */
- int x; /**< icon x position (valid only when displayed) */
- int y; /**< icon y position (valid only when displayed) */
- int width; /**< icon width */
- int height; /**< icon height */
- char name[12]; /**< icon name */
- char validation[40]; /**< validation string */
- struct toolbar_icon *next; /**< next toolbar icon, or NULL for no more */
-};
-
struct theme {
osspriteop_area *sprite_area; /**< sprite area for theme */
int throbber_width; /**< width of the throbber */
@@ -109,26 +69,6 @@ struct theme {
int users; /**< number of users for the theme */
};
-struct toolbar {
- bool display_buttons; /**< display standard buttons */
- bool display_url; /**< display URL bar (if applicable) */
- bool display_throbber; /**< display throbber (if applicable) */
- int toolbar_current; /**< the size of the toolbar window in OS units */
- int height; /**< vertical extent of the toolbar (read only) */
- int max_height; /**< allowed vertical extent (read only) */
- int old_height; /**< height on last test (read only) */
- wimp_w toolbar_handle; /**< toolbar window handle */
- wimp_w parent_handle; /**< parent window handle (read only) */
- bool reformat_buttons; /**< buttons need reformatting */
- char *url_buffer; /**< buffer for status text (read only) */
- char *throbber_buffer; /**< buffer for status text (read only) */
- struct toolbar_icon *icon; /**< first toolbar icon (read only) */
- struct toolbar_icon *suggest; /**< suggestion toolbar icon (read only) */
- struct theme_descriptor *descriptor; /**< theme descriptor (read only) */
- toolbar_type type; /**< toolbar type (read only) */
- struct toolbar *editor; /**< toolbar editor */
-};
-
struct theme_descriptor {
char *leafname; /**< theme leafname */
char *filename; /**< theme filename */
@@ -151,33 +91,19 @@ void ro_gui_theme_initialise(void);
void ro_gui_theme_finalise(void);
struct theme_descriptor *ro_gui_theme_find(const char *leafname);
struct theme_descriptor *ro_gui_theme_get_available(void);
+struct theme_descriptor *ro_gui_theme_get_current(void);
+osspriteop_area *ro_gui_theme_get_sprites(struct theme_descriptor *descriptor);
+int ro_gui_theme_get_style_element(struct theme_descriptor *descriptor,
+ theme_style style, theme_element element);
+bool ro_gui_theme_get_throbber_data(struct theme_descriptor *descriptor,
+ int *frames, int *width, int *height,
+ bool *right, bool *redraw);
+
bool ro_gui_theme_read_file_header(struct theme_descriptor *descriptor,
struct theme_file_header *file_header);
bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list);
bool ro_gui_theme_apply(struct theme_descriptor *descriptor);
void ro_gui_theme_close(struct theme_descriptor *descriptor, bool list);
-
-struct toolbar *ro_gui_theme_create_toolbar(struct theme_descriptor *descriptor, toolbar_type type);
-bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct toolbar *toolbar);
-bool ro_gui_theme_attach_toolbar(struct toolbar *toolbar, wimp_w parent);
-bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width);
-void ro_gui_theme_destroy_toolbar(struct toolbar *toolbar);
-void ro_gui_theme_refresh_toolbar(struct toolbar *toolbar);
-
-void ro_gui_theme_toggle_edit(struct toolbar *toolbar);
-void ro_gui_theme_toolbar_editor_sync(struct toolbar *toolbar);
-void ro_gui_theme_toolbar_editor_click(struct toolbar *toolbar, wimp_pointer *pointer);
-void ro_gui_theme_toolbar_editor_drag_end(wimp_dragged *drag);
-
-int ro_gui_theme_height_change(struct toolbar *toolbar);
-
-struct toolbar_icon *ro_gui_theme_toolbar_get_icon(struct toolbar *toolbar, int x, int y);
-
-#define ro_gui_theme_toolbar_height(toolbar) (toolbar->height + \
- (toolbar->editor ? toolbar->editor->height : 0) > toolbar->max_height ? \
- toolbar->max_height : toolbar->height + \
- (toolbar->editor ? toolbar->editor->height : 0))
-#define ro_gui_theme_toolbar_full_height(toolbar) (toolbar->height + \
- (toolbar->editor ? toolbar->editor->height : 0))
#endif
+
diff --git a/riscos/toolbar.c b/riscos/toolbar.c
new file mode 100644
index 000000000..374650d46
--- /dev/null
+++ b/riscos/toolbar.c
@@ -0,0 +1,1770 @@
+/*
+ * Copyright 2004, 2005 Richard Wilson <info@tinct.net>
+ * Copyright 2010, 2011 Stephen Fryatt <stevef@netsurf-browser.org>
+ *
+ * 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
+ * Window toolbars (implementation).
+ */
+
+#include <alloca.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include "oslib/dragasprite.h"
+#include "oslib/os.h"
+#include "oslib/osgbpb.h"
+#include "oslib/osfile.h"
+#include "oslib/osfind.h"
+#include "oslib/osspriteop.h"
+#include "oslib/wimpspriteop.h"
+#include "oslib/squash.h"
+#include "oslib/wimp.h"
+#include "oslib/wimpextend.h"
+#include "oslib/wimpspriteop.h"
+#include "content/content.h"
+#include "desktop/gui.h"
+#include "desktop/plotters.h"
+#include "riscos/cookies.h"
+#include "riscos/dialog.h"
+#include "riscos/global_history.h"
+#include "riscos/gui.h"
+#include "riscos/gui/button_bar.h"
+#include "riscos/gui/throbber.h"
+#include "riscos/gui/url_bar.h"
+#include "riscos/hotlist.h"
+#include "riscos/menus.h"
+#include "riscos/options.h"
+#include "riscos/save.h"
+#include "riscos/theme.h"
+#include "riscos/toolbar.h"
+#include "riscos/treeview.h"
+#include "riscos/url_complete.h"
+#include "riscos/wimp.h"
+#include "riscos/wimp_event.h"
+#include "riscos/wimputils.h"
+#include "riscos/window.h"
+#include "utils/log.h"
+#include "utils/utils.h"
+
+
+#define TOOLBAR_WIDGET_GUTTER 8
+
+/* Toolbar rows used to index into the arrays of row-specific data.
+ */
+
+#define TOOLBAR_ROW_TOP 0
+#define TOOLBAR_ROW_DIV1 1
+#define TOOLBAR_ROW_EDIT 2
+#define TOOLBAR_MAX_ROWS 3
+
+/* The toolbar data structure.
+ */
+
+struct toolbar {
+ /** Bar details. */
+ struct theme_descriptor *theme;
+ theme_style style;
+ toolbar_flags flags;
+
+ int current_width, current_height;
+ int full_width, full_height;
+ int clip_width, clip_height;
+
+ /** Toolbar and parent window handles. */
+ wimp_w toolbar_handle;
+ wimp_w parent_handle;
+
+ /** Row locations and sizes. */
+ int row_y0[TOOLBAR_MAX_ROWS];
+ int row_y1[TOOLBAR_MAX_ROWS];
+
+ /** Details for the button bar. */
+ struct button_bar *buttons;
+ bool buttons_display;
+ os_coord buttons_size;
+
+ /** Details for the URL bar. */
+ struct url_bar *url;
+ bool url_display;
+ os_coord url_size;
+
+ /** Details for the throbber. */
+ struct throbber *throbber;
+ bool throbber_display;
+ bool throbber_right;
+ os_coord throbber_size;
+
+ /** Client callback data. */
+ const struct toolbar_callbacks *callbacks;
+ void *client_data;
+
+ /** Details for the toolbar editor. */
+ wimp_i editor_div1;
+ struct button_bar *editor;
+ os_coord editor_size;
+
+ bool editing;
+
+ /** Interactive help data. */
+
+ const char *help_prefix;
+
+ /** The next bar in the toolbar list. */
+ struct toolbar *next;
+};
+
+
+/* Global variables for the toolbar module.
+ */
+
+/** The list of defined toolbars. */
+static struct toolbar *ro_toolbar_bars = NULL;
+
+/** The Toolber Menu */
+wimp_menu *toolbar_menu;
+
+
+/* A basic window definition for the toolbar and status bar.
+ */
+
+static wimp_window ro_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,
+ wimp_BUTTON_CLICK_DRAG << wimp_ICON_BUTTON_TYPE_SHIFT,
+ wimpspriteop_AREA,
+ 1,
+ 1,
+ {""},
+ 0,
+ { }
+};
+
+static char ro_toolbar_null_string[] = "";
+static char ro_toolbar_line_validation[] = "R2";
+
+/*
+ * Private function prototypes.
+ */
+
+static void ro_toolbar_update_current_widgets(struct toolbar *toolbar);
+static void ro_toolbar_refresh_widget_dimensions(struct toolbar *toolbar);
+static void ro_toolbar_reformat_widgets(struct toolbar *toolbar);
+
+static void ro_toolbar_redraw(wimp_draw *redraw);
+static bool ro_toolbar_click(wimp_pointer *pointer);
+static bool ro_toolbar_keypress(wimp_key *key);
+static bool ro_toolbar_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer);
+static void ro_toolbar_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action);
+static bool ro_toolbar_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action);
+static const char *ro_toolbar_get_help_suffix(wimp_w w, wimp_i i, os_coord *pos,
+ wimp_mouse_state buttons);
+
+static void ro_toolbar_update_buttons(struct toolbar *toolbar);
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_init(void)
+{
+ /* browser toolbar menu */
+ static const struct ns_menu toolbar_definition = {
+ "Toolbar", {
+ { "Toolbars", NO_ACTION, 0 },
+ { "Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
+ { "Toolbars.ToolAddress", TOOLBAR_ADDRESS_BAR, 0 },
+ { "Toolbars.ToolThrob", TOOLBAR_THROBBER, 0 },
+ { "EditToolbar", TOOLBAR_EDIT, 0 },
+ {NULL, 0, 0}
+ }
+ };
+ toolbar_menu = ro_gui_menu_define_menu(
+ &toolbar_definition);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+struct toolbar *ro_toolbar_create(struct theme_descriptor *descriptor,
+ wimp_w parent, theme_style style, toolbar_flags bar_flags,
+ const struct toolbar_callbacks *callbacks, void *client_data,
+ const char *help)
+{
+ struct toolbar *toolbar;
+
+ /* Allocate memory for the bar and link it into the list of bars. */
+
+ toolbar = calloc(sizeof(struct toolbar), 1);
+ if (toolbar == NULL) {
+ LOG(("No memory for malloc()"));
+ warn_user("NoMemory", 0);
+ return NULL;
+ }
+
+ toolbar->next = ro_toolbar_bars;
+ ro_toolbar_bars = toolbar;
+
+ /* Store the supplied settings. */
+
+ toolbar->flags = bar_flags;
+ toolbar->theme = descriptor;
+ toolbar->style = style;
+ toolbar->parent_handle = parent;
+ toolbar->callbacks = callbacks;
+ toolbar->client_data = client_data;
+
+ /* Set up the internal widgets: initially, there are none. */
+
+ toolbar->buttons = NULL;
+ toolbar->buttons_display = false;
+
+ toolbar->url = NULL;
+ toolbar->url_display = false;
+
+ toolbar->throbber = NULL;
+ toolbar->throbber_display = false;
+
+ /* Set up the bar editor. */
+
+ toolbar->editor = NULL;
+ toolbar->editor_div1 = -1;
+
+ toolbar->editing = false;
+
+ toolbar->help_prefix = help;
+
+ return toolbar;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+bool ro_toolbar_add_buttons(struct toolbar *toolbar,
+ const struct button_bar_buttons buttons[], char *button_order)
+{
+ if (toolbar == NULL)
+ return false;
+
+ if (toolbar->buttons != NULL)
+ return false;
+
+ toolbar->buttons = ro_gui_button_bar_create(toolbar->theme, buttons);
+ if (toolbar->buttons != NULL) {
+ toolbar->buttons_display = true;
+ ro_gui_button_bar_arrange_buttons(toolbar->buttons,
+ button_order);
+ }
+
+ toolbar->editor = ro_gui_button_bar_create(toolbar->theme, buttons);
+ if (toolbar->editor != NULL)
+ ro_gui_button_bar_hide(toolbar->editor, !toolbar->editing);
+
+ if (toolbar->buttons != NULL && toolbar->editor != NULL)
+ if (!ro_gui_button_bar_link_editor(toolbar->buttons,
+ toolbar->editor,
+ (void (*)(void *))
+ ro_toolbar_update_current_widgets,
+ toolbar))
+ return false;
+
+ return (toolbar->buttons == NULL || toolbar->editor == NULL) ?
+ false : true;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+bool ro_toolbar_add_throbber(struct toolbar *toolbar)
+{
+ if (toolbar == NULL)
+ return false;
+
+ if (toolbar->throbber != NULL)
+ return false;
+
+ toolbar->throbber = ro_gui_throbber_create(toolbar->theme);
+
+ if (toolbar->throbber != NULL)
+ toolbar->throbber_display = true;
+
+ return (toolbar->throbber == NULL) ? false : true;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+bool ro_toolbar_add_url(struct toolbar *toolbar)
+{
+ if (toolbar == NULL)
+ return false;
+
+ if (toolbar->url != NULL)
+ return false;
+
+ toolbar->url = ro_gui_url_bar_create(toolbar->theme);
+
+ if (toolbar->url != NULL)
+ toolbar->url_display = true;
+
+ return (toolbar->url == NULL) ? false : true;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+bool ro_toolbar_rebuild(struct toolbar *toolbar)
+{
+ os_error *error;
+ wimp_icon_create icon;
+ wimp_w old_window = NULL;
+
+ if (toolbar == NULL)
+ return false;
+
+ /* Start to set up the toolbar window. */
+
+ ro_toolbar_window.sprite_area =
+ ro_gui_theme_get_sprites(toolbar->theme);
+ ro_toolbar_window.work_bg =
+ ro_gui_theme_get_style_element(toolbar->theme,
+ toolbar->style, THEME_ELEMENT_BACKGROUND);
+
+ /* Delete any existing toolbar window... */
+
+ if (toolbar->toolbar_handle != NULL) {
+ old_window = toolbar->toolbar_handle;
+ error = xwimp_delete_window(toolbar->toolbar_handle);
+ if (error)
+ LOG(("xwimp_delete_window: 0x%x: %s",
+ error->errnum, error->errmess));
+ toolbar->toolbar_handle = NULL;
+ }
+
+ /* ...and create a new window. */
+
+ error = xwimp_create_window(&ro_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;
+ }
+
+ /* Set up the toolbar's event handlers. Only set the user activity-
+ * related callbacks if the bar isn't for display purposes. If the
+ * toolbar is being recreated, simply transfer the handlers across
+ * from the old, now-deleted window.
+ */
+
+ if (old_window == NULL) {
+ ro_gui_wimp_event_register_redraw_window(
+ toolbar->toolbar_handle, ro_toolbar_redraw);
+ ro_gui_wimp_event_set_user_data(toolbar->toolbar_handle,
+ toolbar);
+
+ if (!(toolbar->flags & TOOLBAR_FLAGS_DISPLAY)) {
+ ro_gui_wimp_event_register_mouse_click(
+ toolbar->toolbar_handle,
+ ro_toolbar_click);
+ ro_gui_wimp_event_register_keypress(
+ toolbar->toolbar_handle,
+ ro_toolbar_keypress);
+ ro_gui_wimp_event_register_menu_prepare(
+ toolbar->toolbar_handle,
+ ro_toolbar_menu_prepare);
+ ro_gui_wimp_event_register_menu_warning(
+ toolbar->toolbar_handle,
+ ro_toolbar_menu_warning);
+ ro_gui_wimp_event_register_menu_selection(
+ toolbar->toolbar_handle,
+ ro_toolbar_menu_select);
+ ro_gui_wimp_event_register_menu(toolbar->toolbar_handle,
+ toolbar_menu, true, false);
+ ro_gui_wimp_event_register_help_suffix(
+ toolbar->toolbar_handle,
+ ro_toolbar_get_help_suffix);
+ }
+ } else {
+ ro_gui_wimp_event_transfer(old_window, toolbar->toolbar_handle);
+ }
+
+ /* The help prefix changes from edit to non-edit more. */
+
+ ro_gui_wimp_event_set_help_prefix(toolbar->toolbar_handle,
+ (toolbar->editing) ?
+ "HelpEditToolbar" : toolbar->help_prefix);
+
+ /* Place the widgets into the new bar, using the new theme.
+ *
+ * \TODO -- If any widgets fail to rebuild, then we currently just
+ * carry on without them. Not sure if the whole bar
+ * rebuild should fail here?
+ */
+
+ if (toolbar->throbber != NULL) {
+ if (!ro_gui_throbber_rebuild(toolbar->throbber, toolbar->theme,
+ toolbar->style, toolbar->toolbar_handle,
+ toolbar->editing)) {
+ ro_gui_throbber_destroy(toolbar->throbber);
+ toolbar->throbber = NULL;
+ }
+
+ ro_gui_theme_get_throbber_data(toolbar->theme, NULL, NULL, NULL,
+ &toolbar->throbber_right, NULL);
+ }
+
+ if (toolbar->buttons != NULL) {
+ if (!ro_gui_button_bar_rebuild(toolbar->buttons, toolbar->theme,
+ toolbar->style, toolbar->toolbar_handle,
+ toolbar->editing)) {
+ ro_gui_button_bar_destroy(toolbar->buttons);
+ toolbar->buttons = NULL;
+ }
+ }
+
+ if (toolbar->editor != NULL) {
+ if (!ro_gui_button_bar_rebuild(toolbar->editor, toolbar->theme,
+ toolbar->style, toolbar->toolbar_handle,
+ toolbar->editing)) {
+ ro_gui_button_bar_destroy(toolbar->editor);
+ toolbar->editor = NULL;
+ }
+ }
+
+ if (toolbar->url != NULL) {
+ if (!ro_gui_url_bar_rebuild(toolbar->url, toolbar->theme,
+ toolbar->style, toolbar->toolbar_handle,
+ toolbar->flags & TOOLBAR_FLAGS_DISPLAY,
+ toolbar->editing)) {
+ ro_gui_url_bar_destroy(toolbar->url);
+ toolbar->url = NULL;
+ }
+ }
+
+ /* If this is an editor, add in a divider icon and the editor
+ * button bar.
+ */
+
+ if (toolbar->editing) {
+ icon.w = toolbar->toolbar_handle;
+ icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED |
+ wimp_ICON_VCENTRED | wimp_ICON_BORDER |
+ (wimp_COLOUR_BLACK <<
+ wimp_ICON_FG_COLOUR_SHIFT) |
+ (wimp_COLOUR_VERY_LIGHT_GREY <<
+ wimp_ICON_BG_COLOUR_SHIFT);
+ icon.icon.extent.x0 = 0;
+ icon.icon.extent.x1 = 0;
+ icon.icon.extent.y1 = 0;
+ icon.icon.extent.y0 = 0;
+ icon.icon.data.indirected_text.text = ro_toolbar_null_string;
+ icon.icon.data.indirected_text.validation =
+ ro_toolbar_line_validation;
+ icon.icon.data.indirected_text.size = 1;
+ error = xwimp_create_icon(&icon, &toolbar->editor_div1);
+ if (error) {
+ LOG(("xwimp_create_icon: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ toolbar->editor_div1 = -1;
+ }
+ }
+
+ /* Establish the required dimensions to fit the widgets, then
+ * reflow the bar contents.
+ */
+
+ ro_toolbar_refresh_widget_dimensions(toolbar);
+
+ ro_toolbar_process(toolbar, -1, true);
+
+ if (toolbar->parent_handle != NULL)
+ ro_toolbar_attach(toolbar, toolbar->parent_handle);
+
+ ro_toolbar_update_buttons(toolbar);
+
+ return true;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+bool ro_toolbar_attach(struct toolbar *toolbar, wimp_w parent)
+{
+ wimp_outline outline;
+ wimp_window_state state;
+ os_error *error;
+
+ if (toolbar == NULL || toolbar->toolbar_handle == NULL)
+ return false;
+
+ toolbar->parent_handle = parent;
+
+ /* Only try to attach the toolbar if there's any of it visible to
+ * matter.
+ */
+
+ if (toolbar->current_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 + 2 -
+ toolbar->current_height;
+ state.xscroll = 0;
+ state.yscroll = 0;
+ 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;
+ }
+
+ 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;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+bool ro_toolbar_process(struct toolbar *toolbar, int width, bool reformat)
+{
+ os_error *error;
+ wimp_outline outline;
+ wimp_window_state state;
+ int old_height, old_width;
+ int xeig, yeig;
+ os_coord pixel = {1, 1};
+
+ if (!toolbar)
+ return false;
+
+ old_height = toolbar->current_height;
+ old_width = toolbar->current_width;
+
+ /* calculate 1px in OS units */
+
+ ro_convert_pixels_to_os_units(&pixel, (os_mode)-1);
+ xeig = pixel.x;
+ yeig = pixel.y;
+
+ /* Measure the parent window width if the caller has asked us to
+ * calculate the clip width ourselves. Otherwise, if a clip width
+ * has been specified, set the clip to that.
+ */
+
+ if ((toolbar->parent_handle != NULL) && (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;
+ }
+
+ toolbar->clip_width = outline.outline.x1 -
+ outline.outline.x0 - 2;
+ toolbar->current_width = toolbar->clip_width;
+ } else if (width != -1) {
+ toolbar->clip_width = width;
+ toolbar->current_width = toolbar->clip_width;
+ }
+
+ /* Find the parent visible height to clip our toolbar height to
+ */
+
+ if (toolbar->parent_handle != NULL) {
+ 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;
+ }
+
+ toolbar->clip_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 (toolbar->clip_height >= toolbar->full_height)
+ toolbar->current_height = toolbar->full_height;
+ else
+ toolbar->current_height = toolbar->clip_height;
+
+ /* Update our position
+ */
+ if (old_height != toolbar->current_height)
+ ro_toolbar_attach(toolbar, toolbar->parent_handle);
+ } else {
+ toolbar->clip_height = toolbar->full_height;
+ toolbar->current_height = toolbar->full_height;
+ }
+
+ /* Reflow the widgets into the toolbar if the dimensions have
+ * changed or we have been asked to anyway. */
+
+ if (toolbar->current_width != old_width || reformat)
+ ro_toolbar_reformat_widgets(toolbar);
+
+ return true;
+}
+
+
+/**
+ * Update the widgets currently on view in a toolbar. This can be used
+ * generally, but is primarily offered to widgets as a way for them
+ * to force an update.
+ *
+ * \param *toolbar The toolbar to update.
+ */
+
+void ro_toolbar_update_current_widgets(struct toolbar *toolbar)
+{
+ int old_height;
+
+ if (toolbar == NULL)
+ return;
+
+ old_height = toolbar->full_height;
+
+ ro_toolbar_refresh_widget_dimensions(toolbar);
+ ro_toolbar_reformat_widgets(toolbar);
+
+ /* If the toolbar height has changed, we need to tell the client. */
+
+ if (toolbar->full_height != old_height)
+ ro_toolbar_refresh(toolbar);
+}
+
+
+/**
+ * Get the minimum dimenstions required by the toolbar widgets after
+ * these have changed. The minimum dimensions are assumed not to change
+ * unless we change theme (ie. we rebuild the bar) or we knowingly
+ * alter a widget (eg. we add or remove button-bar buttons).
+ *
+ *
+ * \param *toolbar The toolbar to refresh.
+ */
+
+void ro_toolbar_refresh_widget_dimensions(struct toolbar *toolbar)
+{
+ int width, height;
+ int row_width, row_height;
+
+ if (toolbar == NULL)
+ return;
+
+ /* Process the toolbar editor and any associated divider rows.
+ */
+
+ if (toolbar->editor != NULL && toolbar->editing) {
+ width = 0;
+ height = 0;
+ ro_gui_button_bar_get_dims(toolbar->editor, &width, &height);
+
+ toolbar->editor_size.x = width;
+ toolbar->editor_size.y = height;
+
+ toolbar->row_y0[TOOLBAR_ROW_EDIT] = TOOLBAR_WIDGET_GUTTER;
+ toolbar->row_y1[TOOLBAR_ROW_EDIT] = TOOLBAR_WIDGET_GUTTER
+ + height;
+
+ toolbar->row_y0[TOOLBAR_ROW_DIV1] = TOOLBAR_WIDGET_GUTTER +
+ toolbar->row_y1[TOOLBAR_ROW_EDIT];
+ toolbar->row_y1[TOOLBAR_ROW_DIV1] = 8 +
+ toolbar->row_y0[TOOLBAR_ROW_DIV1];
+ } else {
+ toolbar->editor_size.x = 0;
+ toolbar->editor_size.y = 0;
+
+ toolbar->row_y0[TOOLBAR_ROW_EDIT] = 0;
+ toolbar->row_y1[TOOLBAR_ROW_EDIT] = 0;
+ toolbar->row_y0[TOOLBAR_ROW_DIV1] = 0;
+ toolbar->row_y1[TOOLBAR_ROW_DIV1] = 0;
+ }
+
+ /* Process the top row icons. */
+
+ row_width = 0;
+ row_height = 0;
+
+ /* If the editor is active, any button bar if forced into view. */
+
+ if (toolbar->buttons != NULL &&
+ (toolbar->buttons_display || toolbar->editing)) {
+ width = 0;
+ height = 0;
+ ro_gui_button_bar_get_dims(toolbar->buttons, &width, &height);
+
+ row_width += width;
+ toolbar->buttons_size.x = width;
+ toolbar->buttons_size.y = height;
+
+ if (height > row_height)
+ row_height = height;
+ } else {
+ toolbar->buttons_size.x = 0;
+ toolbar->buttons_size.y = 0;
+ }
+
+ if (toolbar->url != NULL && toolbar->url_display) {
+ width = 0;
+ height = 0;
+ ro_gui_url_bar_get_dims(toolbar->url, &width, &height);
+
+ if (row_width > 0)
+ row_width += TOOLBAR_WIDGET_GUTTER;
+ row_width += width;
+
+ toolbar->url_size.x = width;
+ toolbar->url_size.y = height;
+
+ if (height > row_height)
+ row_height = height;
+ } else {
+ toolbar->url_size.x = 0;
+ toolbar->url_size.y = 0;
+ }
+
+ if (toolbar->throbber != NULL && toolbar->throbber_display) {
+ width = 0;
+ height = 0;
+ ro_gui_throbber_get_dims(toolbar->throbber, &width, &height);
+
+ if (row_width > 0)
+ row_width += TOOLBAR_WIDGET_GUTTER;
+ row_width += width;
+
+ toolbar->throbber_size.x = width;
+ toolbar->throbber_size.y = height;
+
+ if (height > row_height)
+ row_height = height;
+ } else {
+ toolbar->throbber_size.x = 0;
+ toolbar->throbber_size.y = 0;
+ }
+
+ if (row_height > 0) {
+ toolbar->row_y0[TOOLBAR_ROW_TOP] = TOOLBAR_WIDGET_GUTTER +
+ toolbar->row_y1[TOOLBAR_ROW_DIV1];
+ toolbar->row_y1[TOOLBAR_ROW_TOP] = row_height +
+ toolbar->row_y0[TOOLBAR_ROW_TOP];
+ } else {
+ toolbar->row_y0[TOOLBAR_ROW_TOP] = 0;
+ toolbar->row_y1[TOOLBAR_ROW_TOP] = 0;
+ }
+
+ /* Establish the full dimensions of the bar.
+ *
+ * \TODO -- This currently assumes an "all or nothing" approach to
+ * the editor bar, and will need reworking once we have to
+ * worry about tab bars.
+ */
+
+ if (toolbar->row_y1[TOOLBAR_ROW_TOP] > 0) {
+ toolbar->full_height = toolbar->row_y1[TOOLBAR_ROW_TOP] +
+ TOOLBAR_WIDGET_GUTTER;
+ } else {
+ toolbar->full_height = 0;
+ }
+ toolbar->full_width = 2 * TOOLBAR_WIDGET_GUTTER +
+ (row_width > toolbar->editor_size.x) ?
+ row_width : toolbar->editor_size.x;
+}
+
+
+/**
+ * Reformat (reflow) the widgets into the toolbar, based on the toolbar size
+ * and the previously calculated widget dimensions.
+ *
+ * \param *toolbar The toolbar to reformat.
+ */
+
+void ro_toolbar_reformat_widgets(struct toolbar *toolbar)
+{
+ int left_margin, right_margin;
+
+ left_margin = TOOLBAR_WIDGET_GUTTER;
+ right_margin = toolbar->clip_width - TOOLBAR_WIDGET_GUTTER;
+
+ /* Flow the toolbar editor row, which will be a fixed with and
+ * may alter the right margin.
+ */
+
+ if (toolbar->editor != NULL && toolbar->editing) {
+ if (right_margin < left_margin + toolbar->editor_size.x)
+ right_margin = left_margin + toolbar->editor_size.x;
+
+ ro_gui_button_bar_set_extent(toolbar->editor,
+ left_margin,
+ toolbar->row_y0[TOOLBAR_ROW_EDIT],
+ left_margin + toolbar->editor_size.x,
+ toolbar->row_y1[TOOLBAR_ROW_EDIT]);
+
+ if (toolbar->editor_div1 != -1)
+ xwimp_resize_icon(toolbar->toolbar_handle,
+ toolbar->editor_div1, -8,
+ toolbar->row_y0[TOOLBAR_ROW_DIV1],
+ toolbar->clip_width + 8,
+ toolbar->row_y1[TOOLBAR_ROW_DIV1]);
+ }
+
+ /* Flow the top row. */
+
+ if (toolbar->throbber != NULL && toolbar->throbber_display) {
+ if (toolbar->throbber_right) {
+ right_margin -= (toolbar->throbber_size.x +
+ TOOLBAR_WIDGET_GUTTER);
+ } else {
+ ro_gui_throbber_set_extent(toolbar->throbber,
+ left_margin,
+ toolbar->row_y0[TOOLBAR_ROW_TOP],
+ left_margin + toolbar->throbber_size.x,
+ toolbar->row_y1[TOOLBAR_ROW_TOP]);
+ left_margin += (toolbar->throbber_size.x +
+ TOOLBAR_WIDGET_GUTTER);
+ }
+ }
+
+ if (toolbar->buttons != NULL &&
+ (toolbar->buttons_display || toolbar->editing)) {
+ if (right_margin < left_margin + toolbar->buttons_size.x)
+ right_margin = left_margin + toolbar->buttons_size.x;
+
+ ro_gui_button_bar_set_extent(toolbar->buttons,
+ left_margin,
+ toolbar->row_y0[TOOLBAR_ROW_TOP],
+ left_margin + toolbar->buttons_size.x,
+ toolbar->row_y1[TOOLBAR_ROW_TOP]);
+ left_margin += (toolbar->buttons_size.x +
+ TOOLBAR_WIDGET_GUTTER);
+ }
+
+ if (toolbar->url != NULL && toolbar->url_display) {
+ if (right_margin < left_margin + toolbar->url_size.x)
+ right_margin = left_margin + toolbar->url_size.x;
+
+ ro_gui_url_bar_set_extent(toolbar->url,
+ left_margin,
+ toolbar->row_y0[TOOLBAR_ROW_TOP],
+ right_margin,
+ toolbar->row_y1[TOOLBAR_ROW_TOP]);
+
+ left_margin = right_margin + TOOLBAR_WIDGET_GUTTER;
+ }
+
+ if (toolbar->throbber != NULL && toolbar->throbber_display &&
+ toolbar->throbber_right) {
+ left_margin = right_margin + TOOLBAR_WIDGET_GUTTER;
+ ro_gui_throbber_set_extent(toolbar->throbber,
+ left_margin,
+ toolbar->row_y0[TOOLBAR_ROW_TOP],
+ left_margin + toolbar->throbber_size.x,
+ toolbar->row_y1[TOOLBAR_ROW_TOP]);
+ }
+
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_destroy(struct toolbar *toolbar)
+{
+ struct toolbar *bar;
+
+ if (toolbar == NULL)
+ return;
+
+ LOG(("Destroying toolbar 0x%x", (unsigned int) toolbar));
+
+ /* Destroy the widgets. */
+
+ if (toolbar->buttons != NULL)
+ ro_gui_button_bar_destroy(toolbar->buttons);
+
+ if (toolbar->editor != NULL)
+ ro_gui_button_bar_destroy(toolbar->editor);
+
+ if (toolbar->url != NULL)
+ ro_gui_url_bar_destroy(toolbar->url);
+
+ if (toolbar->throbber != NULL)
+ ro_gui_throbber_destroy(toolbar->throbber);
+
+ /* Delete the toolbar window. */
+
+ if (toolbar->toolbar_handle != NULL) {
+ xwimp_delete_window(toolbar->toolbar_handle);
+ ro_gui_wimp_event_finalise(toolbar->toolbar_handle);
+ }
+
+ /* Remove the bar from the list and free the memory.
+ */
+
+ if (ro_toolbar_bars == toolbar) {
+ ro_toolbar_bars = toolbar->next;
+ } else {
+ for (bar = ro_toolbar_bars; bar != NULL && bar->next != toolbar;
+ bar = bar->next);
+
+ if (bar->next == toolbar)
+ bar->next = toolbar->next;
+ }
+
+ free(toolbar);
+
+}
+
+
+/**
+ * Handle redraw request events for a toolbar workarea.
+ *
+ * \param *redraw The redraw block for the event.
+ */
+
+void ro_toolbar_redraw(wimp_draw *redraw)
+{
+ struct toolbar *toolbar;
+ osbool more;
+ os_error *error;
+
+ toolbar = (struct toolbar *)ro_gui_wimp_event_get_user_data(redraw->w);
+
+ assert(toolbar != NULL);
+
+ plot = ro_plotters;
+ ro_plot_set_scale(1.0);
+
+ 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) {
+ ro_plot_origin_x = redraw->box.x0 - redraw->xscroll;
+ ro_plot_origin_y = redraw->box.y1 - redraw->yscroll;
+
+ if (toolbar->buttons != NULL && toolbar->buttons_display)
+ ro_gui_button_bar_redraw(toolbar->buttons, redraw);
+
+ if (toolbar->editor != NULL && toolbar->editing)
+ ro_gui_button_bar_redraw(toolbar->editor, redraw);
+
+ if (toolbar->url != NULL && toolbar->url_display)
+ ro_gui_url_bar_redraw(toolbar->url, redraw);
+
+ 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;
+ }
+ }
+}
+
+
+/**
+ * Process clicks on a toolbar, passing details on to clients where necessary.
+ *
+ * \param *pointer The wimp mouse click event.
+ * \return True if the event was handled; else false.
+ */
+
+bool ro_toolbar_click(wimp_pointer *pointer)
+{
+ struct toolbar *toolbar;
+ union toolbar_action action;
+ wimp_window_state state;
+ os_error *error;
+
+ toolbar = (struct toolbar *)
+ ro_gui_wimp_event_get_user_data(pointer->w);
+
+ if (toolbar == NULL)
+ return false;
+
+ assert(pointer->w == toolbar->toolbar_handle);
+
+ state.w = toolbar->toolbar_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;
+ }
+
+ /* If the click wasn't in the URL Bar's text field, then it will
+ * need to close any URL Complete window that is open.
+ *
+ * \TODO -- This should really move into the URL Bar module, as
+ * URL Complete is really an extension to that.
+ */
+
+ if (toolbar->url != NULL && toolbar->url_display &&
+ !ro_gui_url_bar_test_for_text_field_click(toolbar->url,
+ pointer))
+ ro_gui_url_complete_close();
+
+ /* Pass the click around the toolbar widgets. */
+
+ if (toolbar->buttons != NULL &&
+ (toolbar->buttons_display || toolbar->editing) &&
+ ro_gui_button_bar_click(toolbar->buttons, pointer,
+ &state, &action.button)) {
+ if (action.button != TOOLBAR_BUTTON_NONE &&
+ !toolbar->editing &&
+ toolbar->callbacks != NULL &&
+ toolbar->callbacks->user_action != NULL)
+ toolbar->callbacks->user_action(toolbar->client_data,
+ TOOLBAR_ACTION_BUTTON, action);
+ return true;
+ }
+
+ if (toolbar->url != NULL && toolbar->url_display &&
+ ro_gui_url_bar_click(toolbar->url, pointer,
+ &state, &action.url)) {
+ if (action.url != TOOLBAR_URL_NONE &&
+ !toolbar->editing &&
+ toolbar->callbacks != NULL &&
+ toolbar->callbacks->user_action != NULL)
+ toolbar->callbacks->user_action(toolbar->client_data,
+ TOOLBAR_ACTION_URL, action);
+ return true;
+ }
+
+ if (toolbar->editor != NULL && toolbar->editing &&
+ ro_gui_button_bar_click(toolbar->editor, pointer,
+ &state, &action.button)) {
+ return true;
+ }
+
+ /* Nothing else has handled this, so try passing it to the
+ * URL Complete module.
+ *
+ * \TODO -- This should really move into the URL Bar module, as
+ * URL Complete is really an extension to that.
+ */
+
+ if (toolbar->url != NULL && toolbar->url_display &&
+ ro_gui_url_bar_test_for_text_field_click(toolbar->url,
+ pointer)) {
+ ro_gui_url_complete_start(toolbar);
+ return true;
+ }
+
+ return false;
+}
+
+
+/**
+ * Process keypresses in a toolbar, passing details on to clients where
+ * necessary.
+ *
+ * \param *key The wimp key press event.
+ * \return True if the event was handled; else false.
+ */
+
+bool ro_toolbar_keypress(wimp_key *key)
+{
+ struct toolbar *toolbar;
+
+ toolbar = (struct toolbar *) ro_gui_wimp_event_get_user_data(key->w);
+
+ if (toolbar == NULL)
+ return false;
+
+ /* If the caret is in the URL bar, ask the URL Complete module if it
+ * wants to handle the keypress.
+ *
+ * \TODO -- This should really move into the URL Bar module, as
+ * URL Complete is really an extension to that.
+ */
+
+ if (toolbar->url != NULL && toolbar->url_display &&
+ ro_gui_url_bar_test_for_text_field_keypress(
+ toolbar->url, key) &&
+ ro_gui_url_complete_keypress(toolbar, key->c))
+ return true;
+
+ /* Otherwsie, pass the keypress on to the client. */
+
+ if (toolbar->callbacks->user_action != NULL)
+ toolbar->callbacks->key_press(toolbar->client_data, key);
+
+ return true;
+}
+
+
+/**
+ * Prepare the toolbar menu for (re-)opening
+ *
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param *menu The menu about to be opened.
+ * \param *pointer Pointer to the relevant wimp event block, or
+ * NULL for an Adjust click.
+ * \return true if the event was handled; else false.
+ */
+
+bool ro_toolbar_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer)
+{
+ struct toolbar *toolbar;
+
+ toolbar = (struct toolbar *) ro_gui_wimp_event_get_user_data(w);
+
+ if (toolbar == NULL)
+ return false;
+
+ /* Pass the event on to potentially interested widgets. */
+
+ if (toolbar->url != NULL && ro_gui_url_bar_menu_prepare(toolbar->url,
+ i, menu, pointer))
+ return true;
+
+ /* Try to process the event as a toolbar menu. */
+
+ if (menu != toolbar_menu)
+ return false;
+
+ /* Shade menu entries according to the state of the window and object
+ * under the pointer.
+ */
+
+ /* Toolbar (Sub)Menu */
+
+ ro_gui_menu_set_entry_shaded(menu, TOOLBAR_EDIT,
+ ro_toolbar_menu_edit_shade(toolbar));
+ ro_gui_menu_set_entry_ticked(menu, TOOLBAR_EDIT,
+ ro_toolbar_menu_edit_tick(toolbar));
+
+ ro_gui_menu_set_entry_shaded(menu, TOOLBAR_BUTTONS,
+ ro_toolbar_menu_option_shade(toolbar) ||
+ toolbar->buttons == NULL);
+ ro_gui_menu_set_entry_ticked(menu, TOOLBAR_BUTTONS,
+ ro_toolbar_menu_buttons_tick(toolbar) &&
+ toolbar->buttons != NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, TOOLBAR_ADDRESS_BAR,
+ ro_toolbar_menu_edit_shade(toolbar) ||
+ toolbar->url == NULL);
+ ro_gui_menu_set_entry_ticked(menu, TOOLBAR_ADDRESS_BAR,
+ ro_toolbar_menu_url_tick(toolbar) &&
+ toolbar->url != NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, TOOLBAR_THROBBER,
+ ro_toolbar_menu_edit_shade(toolbar) ||
+ toolbar->throbber == NULL);
+ ro_gui_menu_set_entry_ticked(menu, TOOLBAR_THROBBER,
+ ro_toolbar_menu_throbber_tick(toolbar) &&
+ toolbar->throbber != NULL);
+
+ return true;
+}
+
+
+/**
+ * Handle submenu warnings for the toolbar menu
+ *
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param *menu The menu to which the warning applies.
+ * \param *selection The wimp menu selection data.
+ * \param action The selected menu action.
+ */
+
+void ro_toolbar_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action)
+{
+ /* Do nothing */
+}
+
+
+/**
+ * Handle selections from the toolbar menu
+ *
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param *menu The menu from which the selection was made.
+ * \param *selection The wimp menu selection data.
+ * \param action The selected menu action.
+ * \return true if action accepted; else false.
+ */
+
+bool ro_toolbar_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action)
+{
+ struct toolbar *toolbar;
+
+ toolbar = (struct toolbar *) ro_gui_wimp_event_get_user_data(w);
+
+ if (toolbar == NULL)
+ return false;
+
+ /* Pass the event on to potentially interested widgets. */
+
+ if (toolbar->url != NULL && ro_gui_url_bar_menu_select(toolbar->url,
+ i, menu, selection, action))
+ return true;
+
+ /* Try to process the event as a toolbar menu. */
+
+ if (menu != toolbar_menu)
+ return false;
+
+ switch (action) {
+ case TOOLBAR_BUTTONS:
+ ro_toolbar_set_display_buttons(toolbar,
+ !ro_toolbar_get_display_buttons(toolbar));
+ break;
+ case TOOLBAR_ADDRESS_BAR:
+ ro_toolbar_set_display_url(toolbar,
+ !ro_toolbar_get_display_url(toolbar));
+ if (ro_toolbar_get_display_url(toolbar))
+ ro_toolbar_take_caret(toolbar);
+ break;
+ case TOOLBAR_THROBBER:
+ ro_toolbar_set_display_throbber(toolbar,
+ !ro_toolbar_get_display_throbber(toolbar));
+ break;
+ case TOOLBAR_EDIT:
+ ro_toolbar_toggle_edit(toolbar);
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ * Translate the contents of a message_HELP_REQUEST into a suffix for a
+ * NetSurf message token. The help system will then add this to whatever
+ * prefix the current toolbar has registered with WimpEvent.
+ *
+ * \param w The window handle under the mouse.
+ * \param i The icon handle under the mouse.
+ * \param *pos The mouse position.
+ * \param buttons The mouse button state.
+ * \return The required help token suffix.
+ */
+
+const char *ro_toolbar_get_help_suffix(wimp_w w, wimp_i i, os_coord *pos,
+ wimp_mouse_state buttons)
+{
+ struct toolbar *toolbar;
+ wimp_window_state state;
+ os_error *error;
+ const char *suffix;
+
+ toolbar = (struct toolbar *) ro_gui_wimp_event_get_user_data(w);
+
+ if (toolbar == NULL || toolbar->toolbar_handle != w)
+ return NULL;
+
+ state.w = toolbar->toolbar_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 NULL;
+ }
+
+ /* Pass the help request around the toolbar widgets. */
+
+ if (toolbar->throbber != NULL && toolbar->throbber_display &&
+ ro_gui_throbber_help_suffix(toolbar->throbber, i,
+ pos, &state, buttons, &suffix))
+ return suffix;
+
+ if (toolbar->url != NULL && toolbar->url_display &&
+ ro_gui_url_bar_help_suffix(toolbar->url, i,
+ pos, &state, buttons, &suffix))
+ return suffix;
+
+ if (toolbar->buttons != NULL && toolbar->buttons_display &&
+ ro_gui_button_bar_help_suffix(toolbar->buttons, i,
+ pos, &state, buttons, &suffix))
+ return suffix;
+
+ return "";
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_update_client_data(struct toolbar *toolbar, void *client_data)
+{
+ if (toolbar != NULL)
+ toolbar->client_data = client_data;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_update_all_buttons(void)
+{
+ struct toolbar *bar;
+
+ bar = ro_toolbar_bars;
+ while (bar != NULL) {
+ ro_toolbar_update_buttons(bar);
+
+ bar = bar->next;
+ }
+}
+
+
+/**
+ * Update the state of a toolbar's buttons.
+ *
+ * \param toolbar the toolbar to update
+ */
+
+void ro_toolbar_update_buttons(struct toolbar *toolbar)
+{
+ assert(toolbar != NULL);
+
+ if (toolbar->callbacks != NULL &&
+ toolbar->callbacks->update_buttons != NULL)
+ toolbar->callbacks->update_buttons(toolbar->client_data);
+}
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_refresh(struct toolbar *toolbar)
+{
+ assert(toolbar != NULL);
+
+ ro_toolbar_process(toolbar, -1, true);
+ if (toolbar->callbacks != NULL &&
+ toolbar->callbacks->change_size != NULL)
+ toolbar->callbacks->change_size(toolbar->client_data);
+
+ if (toolbar->toolbar_handle != NULL)
+ xwimp_force_redraw(toolbar->toolbar_handle, 0, 0,
+ toolbar->current_width,
+ toolbar->current_height);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_theme_update(void)
+{
+ struct toolbar *bar, *next;
+ bool ok;
+
+ bar = ro_toolbar_bars;
+ while (bar != NULL) {
+ /* Take the next bar address now, as *bar may become invalid
+ * during the update process (if an update fails and
+ * ro_toolbar_destroy() is called) and we don't want to lose
+ * the link to the rest of the chain.
+ */
+
+ next = bar->next;
+
+ /* Only process the bar if the theme is set to the default.
+ * Otherwise, it's up to the owner to do whatever they need
+ * to do for themselves.
+ */
+
+ if (bar->theme == NULL) {
+ ok = ro_toolbar_rebuild(bar);
+
+ if (!ok)
+ ro_toolbar_destroy(bar);
+ } else {
+ ok = true;
+ }
+
+ if (bar->callbacks != NULL &&
+ bar->callbacks->theme_update != NULL)
+ bar->callbacks->theme_update(bar->client_data, ok);
+
+ bar = next;
+ }
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+struct toolbar *ro_toolbar_parent_window_lookup(wimp_w w)
+{
+ struct toolbar *toolbar;
+
+ toolbar = ro_toolbar_bars;
+ while (toolbar != NULL && toolbar->parent_handle != w)
+ toolbar = toolbar->next;
+
+ return toolbar;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+struct toolbar *ro_toolbar_window_lookup(wimp_w w)
+{
+ struct toolbar *toolbar;
+
+ toolbar = ro_toolbar_bars;
+ while (toolbar != NULL && toolbar->toolbar_handle != w)
+ toolbar = toolbar->next;
+
+ return toolbar;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+wimp_w ro_toolbar_get_parent_window(struct toolbar *toolbar)
+{
+ return (toolbar != NULL) ? toolbar->parent_handle : 0;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+wimp_w ro_toolbar_get_window(struct toolbar *toolbar)
+{
+ return (toolbar != NULL) ? toolbar->toolbar_handle : 0;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+int ro_toolbar_height(struct toolbar *toolbar)
+{
+ return (toolbar == NULL) ? 0 : toolbar->current_height;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+int ro_toolbar_full_height(struct toolbar *toolbar)
+{
+ return (toolbar == NULL) ? 0 : toolbar->full_height;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_start_throbbing(struct toolbar *toolbar)
+{
+ if (toolbar != NULL && toolbar->throbber != NULL)
+ ro_gui_throbber_animate(toolbar->throbber);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_stop_throbbing(struct toolbar *toolbar)
+{
+ if (toolbar != NULL && toolbar->throbber != NULL)
+ ro_gui_throbber_stop(toolbar->throbber);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_throb(struct toolbar *toolbar)
+{
+ if (toolbar != NULL && toolbar->throbber != NULL)
+ ro_gui_throbber_animate(toolbar->throbber);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+bool ro_toolbar_set_button_order(struct toolbar *toolbar, char order[])
+{
+ if (toolbar == NULL || toolbar->buttons == NULL)
+ return false;
+
+ if (!ro_gui_button_bar_arrange_buttons(toolbar->buttons, order))
+ return false;
+
+ ro_toolbar_refresh_widget_dimensions(toolbar);
+
+ return ro_toolbar_process(toolbar, -1, true);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_set_button_shaded_state(struct toolbar *toolbar,
+ button_bar_action action, bool shaded)
+{
+ if (toolbar == NULL && toolbar->buttons == NULL)
+ return;
+
+ ro_gui_button_bar_shade_button(toolbar->buttons, action, shaded);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+bool ro_toolbar_take_caret(struct toolbar *toolbar)
+{
+ if (toolbar == NULL || toolbar->url == NULL || !toolbar->url_display)
+ return false;
+
+ return ro_gui_url_bar_take_caret(toolbar->url);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_set_url(struct toolbar *toolbar, const char *url,
+ bool is_utf8, bool set_caret)
+{
+ if (toolbar != NULL && toolbar->url != NULL)
+ ro_gui_url_bar_set_url(toolbar->url, url, is_utf8, set_caret);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+const char *ro_toolbar_get_url(struct toolbar *toolbar)
+{
+ if (toolbar == NULL || toolbar->url == NULL)
+ return NULL;
+
+ return ro_gui_url_bar_get_url(toolbar->url);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+bool ro_toolbar_get_url_field_extent(struct toolbar *toolbar, os_box *extent)
+{
+ if (toolbar == NULL || toolbar->url == NULL)
+ return false;
+
+ if (extent == NULL)
+ return true;
+
+ return ro_gui_url_bar_get_url_extent(toolbar->url, extent);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_set_site_favicon(struct toolbar *toolbar,
+ struct hlcache_handle *h)
+{
+ if (toolbar == NULL || toolbar->url == NULL)
+ return;
+
+ ro_gui_url_bar_set_site_favicon(toolbar->url, h);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_set_content_favicon(struct toolbar *toolbar,
+ struct hlcache_handle *h)
+{
+ if (toolbar == NULL || toolbar->url == NULL)
+ return;
+
+ ro_gui_url_bar_set_content_favicon(toolbar->url, h);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_update_urlsuggest(struct toolbar *toolbar)
+{
+ if (toolbar != NULL && toolbar->url != NULL)
+ return;
+
+ ro_gui_url_bar_update_urlsuggest(toolbar->url);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_set_display_buttons(struct toolbar *toolbar, bool display)
+{
+ if (toolbar == NULL || toolbar->buttons == NULL)
+ return;
+
+ toolbar->buttons_display = display;
+ ro_gui_button_bar_hide(toolbar->buttons, !display);
+ ro_toolbar_refresh_widget_dimensions(toolbar);
+ ro_toolbar_refresh(toolbar);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_set_display_url(struct toolbar *toolbar, bool display)
+{
+ if (toolbar == NULL || toolbar->url == NULL)
+ return;
+
+ toolbar->url_display = display;
+ ro_gui_url_bar_hide(toolbar->url, !display);
+ ro_toolbar_refresh_widget_dimensions(toolbar);
+ ro_toolbar_refresh(toolbar);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+void ro_toolbar_set_display_throbber(struct toolbar *toolbar, bool display)
+{
+ if (toolbar == NULL || toolbar->throbber == NULL)
+ return;
+
+ toolbar->throbber_display = display;
+ ro_gui_throbber_hide(toolbar->throbber, !display);
+ ro_toolbar_refresh_widget_dimensions(toolbar);
+ ro_toolbar_refresh(toolbar);
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+bool ro_toolbar_get_display_buttons(struct toolbar *toolbar)
+{
+ return (toolbar == NULL || toolbar->buttons == NULL) ?
+ false : toolbar->buttons_display;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+bool ro_toolbar_get_display_url(struct toolbar *toolbar)
+{
+ return (toolbar == NULL || toolbar->url == NULL) ?
+ false : toolbar->url_display;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+bool ro_toolbar_get_display_throbber(struct toolbar *toolbar)
+{
+ return (toolbar == NULL || toolbar->throbber == NULL) ?
+ false : toolbar->throbber_display;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+bool ro_toolbar_get_editing(struct toolbar *toolbar)
+{
+ return (toolbar == NULL || !toolbar->editing) ? false : true;
+}
+
+
+/* This is an exported interface documented in toolbar.h */
+
+bool ro_toolbar_toggle_edit(struct toolbar *toolbar)
+{
+ char *new_buttons;
+
+ if (toolbar == NULL || toolbar->editor == NULL)
+ return false;
+
+ toolbar->editing = !toolbar->editing;
+
+ ro_gui_button_bar_hide(toolbar->editor, !toolbar->editing);
+ ro_gui_button_bar_hide(toolbar->buttons,
+ !toolbar->buttons_display && !toolbar->editing);
+
+ if (!ro_toolbar_rebuild(toolbar)) {
+ ro_toolbar_destroy(toolbar);
+ return false;
+ }
+
+ ro_toolbar_refresh(toolbar);
+
+ /* If there's a callback registered and an edit has finished,
+ * tell out client what the new button state is.
+ */
+
+ if (!toolbar->editing && toolbar->buttons != NULL &&
+ toolbar->callbacks != NULL &&
+ toolbar->callbacks->save_buttons != NULL) {
+ new_buttons = ro_gui_button_bar_get_config(toolbar->buttons);
+ toolbar->callbacks->save_buttons(toolbar->client_data,
+ new_buttons);
+ }
+
+ return true;
+}
+
diff --git a/riscos/toolbar.h b/riscos/toolbar.h
new file mode 100644
index 000000000..c2e22cf39
--- /dev/null
+++ b/riscos/toolbar.h
@@ -0,0 +1,525 @@
+/*
+ * Copyright 2005 Richard Wilson <info@tinct.net>
+ * Copyright 2010, 2011 Stephen Fryatt <stevef@netsurf-browser.org>
+ *
+ * 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
+ * Window toolbars (interface).
+ */
+
+#include <stdbool.h>
+#include "riscos/theme.h"
+#include "riscos/gui/button_bar.h"
+#include "riscos/gui/throbber.h"
+#include "riscos/gui/url_bar.h"
+
+#ifndef _NETSURF_RISCOS_TOOLBAR_H_
+#define _NETSURF_RISCOS_TOOLBAR_H_
+
+typedef enum {
+ TOOLBAR_FLAGS_NONE = 0x00,
+ TOOLBAR_FLAGS_DISPLAY = 0x01,
+ TOOLBAR_FLAGS_EDIT = 0x02,
+} toolbar_flags;
+
+/**
+ * Widget action types that the toolbar can pass on to clients.
+ */
+
+typedef enum {
+ TOOLBAR_ACTION_NONE = 0,
+ TOOLBAR_ACTION_BUTTON,
+ TOOLBAR_ACTION_URL
+} toolbar_action_type;
+
+/**
+ * Union to hold the different widget action data that can be passed
+ * from widget via toolbar to client.
+ */
+
+union toolbar_action {
+ button_bar_action button;
+ url_bar_action url;
+};
+
+struct toolbar;
+
+struct toolbar_callbacks {
+ /** Call on theme update */
+ void (*theme_update)(void *, bool);
+
+ /** Call on bar size change */
+ void (*change_size)(void *);
+
+ /** Call to update button states */
+ void (*update_buttons)(void *);
+
+ /** Call to handle user actions */
+ void (*user_action)(void *, toolbar_action_type, union toolbar_action);
+
+ /** Call to handle keypresses. */
+ void (*key_press)(void *, wimp_key *);
+
+ /** Call on change to button order. */
+ void (*save_buttons)(void *, char *);
+};
+
+
+#define ro_toolbar_menu_option_shade(toolbar) \
+ (((toolbar) == NULL) || ro_toolbar_get_editing(toolbar))
+
+#define ro_toolbar_menu_buttons_tick(toolbar) \
+ (ro_toolbar_get_display_buttons(toolbar) || \
+ ro_toolbar_get_editing(toolbar))
+
+#define ro_toolbar_menu_url_tick(toolbar) \
+ (ro_toolbar_get_display_url(toolbar))
+
+#define ro_toolbar_menu_throbber_tick(toolbar) \
+ (ro_toolbar_get_display_throbber(toolbar))
+
+#define ro_toolbar_menu_edit_shade(toolbar) ((toolbar) == NULL)
+
+#define ro_toolbar_menu_edit_tick(toolbar) (ro_toolbar_get_editing(toolbar))
+
+
+/* The new toolbar API */
+
+
+/**
+ * Initialise the RISC OS toolbar widget.
+ */
+
+void ro_toolbar_init(void);
+
+
+/**
+ * Create a new toolbar, ready to have widgets added and to be attached to
+ * a window. If a parent window is supplied, then the toolbar module will
+ * handle the window attachments; if NULL, it is up to the client to sort this
+ * out for itself.
+ *
+ * \param *descriptor The theme to apply, or NULL for the default.
+ * \param parent The window to attach the toolbar to, or NULL.
+ * \param style The theme style to apply.
+ * \param bar_flags Toolbar flags for the new bar.
+ * \param *callbacks A client callback block, or NULL for none.
+ * \param *client_data A data pointer to pass to callbacks, or NULL.
+ * \param *help The Help token prefix for interactive help.
+ * \return The handle of the new bar, or NULL on failure.
+ */
+
+struct toolbar *ro_toolbar_create(struct theme_descriptor *descriptor,
+ wimp_w parent, theme_style style, toolbar_flags bar_flags,
+ const struct toolbar_callbacks *callbacks, void *client_data,
+ const char *help);
+
+
+/**
+ * Add a button bar to a toolbar, and configure the buttons.
+ *
+ * \param *toolbar The toolbar to take the button bar.
+ * \param buttons[] The button definitions.
+ * \param *button_order The initial button order to use.
+ * \return true if the action completed; else false.
+ */
+
+bool ro_toolbar_add_buttons(struct toolbar *toolbar,
+ const struct button_bar_buttons buttons[], char *button_order);
+
+
+/**
+ * Add a throbber to a toolbar.
+ *
+ * \param *toolbar The toolbar to take the throbber.
+ * \return true if the action completed; else false.
+ */
+
+bool ro_toolbar_add_throbber(struct toolbar *toolbar);
+
+
+/**
+ * Add a URL bar to a toolbar.
+ *
+ * \param *toolbar The toolbar to take the URL bar.
+ * \return true if the action completed; else false.
+ */
+
+bool ro_toolbar_add_url(struct toolbar *toolbar);
+
+
+/**
+ * (Re-)build a toolbar to use the specified (or current) theme. If false
+ * is returned, the toolbar may not be complete and should be deleted.
+ *
+ * \param *toolbar The toolbar to rebuild.
+ * \return true if the action was successful; else false.
+ */
+
+bool ro_toolbar_rebuild(struct toolbar *toolbar);
+
+
+/**
+ * Attach or re-attach a toolbar to its parent window.
+ *
+ * \param *toolbar The toolbar to attach.
+ * \param parent The window to attach the toolbar to.
+ * \return true if the operation succeeded; else false.
+ */
+
+bool ro_toolbar_attach(struct toolbar *toolbar, wimp_w parent);
+
+
+/**
+ * Process a toolbar, updating its contents for a size or content change.
+ *
+ * \param *toolbar The toolbar to update.
+ * \param width The width to reformat to, or -1 to use parent.
+ * \param reformat true to force a widget reflow; else false.
+ * \return true if the operation succeeded; else false.
+ */
+
+bool ro_toolbar_process(struct toolbar *toolbar, int width, bool reformat);
+
+
+/**
+ * Destroy a toolbar after use.
+ *
+ * \param *toolbar The toolbar to destroy.
+ */
+
+void ro_toolbar_destroy(struct toolbar *toolbar);
+
+
+/**
+ * Change the client data associated with a toolbar's callbacks.
+ *
+ * \param *toolbar the toolbar whose data is to be updated.
+ * \param *client_data the new client data, or NULL for none.
+ */
+
+void ro_toolbar_update_client_data(struct toolbar *toolbar, void *client_data);
+
+
+/**
+ * Force the update of all toolbars buttons to reflect the current state.
+ */
+
+void ro_toolbar_update_all_buttons(void);
+
+
+/**
+ * Refresh a toolbar after it has been updated
+ *
+ * \param toolbar the toolbar to update
+ */
+
+void ro_toolbar_refresh(struct toolbar *toolbar);
+
+
+/**
+ * Force the update of all toolbars to reflect the application of a new theme.
+ */
+
+void ro_toolbar_theme_update(void);
+
+
+/**
+ * Find the toolbar associated with a given RO window handle.
+ *
+ * \param w the window handle to look up.
+ * \return the toolbar handle, or NULL if a match wasn't found.
+ */
+
+struct toolbar *ro_toolbar_parent_window_lookup(wimp_w w);
+
+
+/**
+ * Find the toolbar using a given RO window handle for its pane.
+ *
+ * \param w the window (pane) handle to look up.
+ * \return the toolbar handle, or NULL if a match wasn't found.
+ */
+
+struct toolbar *ro_toolbar_window_lookup(wimp_w w);
+
+
+/**
+ * Return the RO window handle of the parent window for a toolbar.
+ *
+ * \param *toolbar the toolbar to look up.
+ * \return the RO window handle of the parent.
+ */
+
+wimp_w ro_toolbar_get_parent_window(struct toolbar *toolbar);
+
+
+/**
+ * Return the RO window handle of a toolbar.
+ *
+ * \param *toolbar the toolbar to look up.
+ * \return the RO window handle of the bar.
+ */
+
+wimp_w ro_toolbar_get_window(struct toolbar *toolbar);
+
+
+/**
+ * Return the current height of a toolbar, allowing for available window
+ * space.
+ *
+ * \param *toolbar The toolbar of interest.
+ * \return The current toolbar height in OS units.
+ */
+
+int ro_toolbar_height(struct toolbar *toolbar);
+
+
+/**
+ * Return the full height that a toolbar could grow to, if space is available.
+ *
+ * \param *toolbar The toolbar of interest.
+ * \return The full toolbar height in OS units.
+ */
+
+int ro_toolbar_full_height(struct toolbar *toolbar);
+
+
+/**
+ * Starts a toolbar throbber, if there is one active.
+ *
+ * \param *toolbar the toolbar to start throbbing.
+ */
+
+void ro_toolbar_start_throbbing(struct toolbar *toolbar);
+
+
+/**
+ * Stops a toolbar throbber, if there is one active.
+ *
+ * \param *toolbar the toolbar to stop throbbing.
+ */
+
+void ro_toolbar_stop_throbbing(struct toolbar *toolbar);
+
+
+/**
+ * Animate a toolbar throbber, if there is one active.
+ *
+ * \param *toolbar the toolbar to throb.
+ */
+
+void ro_toolbar_throb(struct toolbar *toolbar);
+
+/**
+ * Change the arrangement of buttons and spacers on a button bar within a
+ * toolbar.
+ *
+ * \param *toolbar The toolbar to change.
+ * \param order[] The new button configuration.
+ * \return true of the order was updated; else false.
+ */
+
+bool ro_toolbar_set_button_order(struct toolbar *toolbar, char order[]);
+
+
+/**
+ * Set the shaded state of a toolbar button.
+ *
+ * \param *toolbar the toolbar to update.
+ * \param action the button action to update.
+ * \param shaded true if the button should be shaded; else false.
+ */
+
+void ro_toolbar_set_button_shaded_state(struct toolbar *toolbar,
+ button_bar_action action, bool shaded);
+
+/**
+ * Give a toolbar input focus, placing the caret into the URL bar if one is
+ * present. Currently a toolbar can only accept focus if it has a URL bar.
+ *
+ * \param *toolbar The toolbar to take the caret.
+ * \return true if the caret was taken; else false.
+ */
+
+bool ro_toolbar_take_caret(struct toolbar *toolbar);
+
+
+/**
+ * Set the content of a toolbar's URL field.
+ *
+ * \param *toolbar the toolbar to update.
+ * \param *url the new url to insert.
+ * \param is_utf8 true if the string is in utf8 encoding; false
+ * if it is in local encoding.
+ * \param set_caret true if the caret should be placed in the field;
+ * else false.
+ */
+
+void ro_toolbar_set_url(struct toolbar *toolbar, const char *url,
+ bool is_utf8, bool set_caret);
+
+
+/**
+ * Return a pointer to the URL contained in a browser toolbar. If the toolbar
+ * doesn't have a URL field, then NULL is returned instead.
+ *
+ * \param *toolbar The toolbar to look up the URL from.
+ * \return pointer to the URL, or NULL.
+ */
+
+const char *ro_toolbar_get_url(struct toolbar *toolbar);
+
+
+/**
+ * Return the current work area coordinates of the URL and favicon field's
+ * bounding box.
+ *
+ * \param *toolbar The toolbar to look up.
+ * \param *extent Return the coordinates.
+ * \return true if successful; else false.
+ */
+
+bool ro_toolbar_get_url_field_extent(struct toolbar *toolbar, os_box *extent);
+
+
+/**
+ * Update the favicon in a browser window toolbar to the supplied content, or
+ * revert to using filetype-based icons.
+ *
+ * \param *toolbar The toolbar to refresh.
+ * \param *h The new favicon to use, or NULL for none.
+ */
+
+void ro_toolbar_set_site_favicon(struct toolbar *toolbar,
+ struct hlcache_handle *h);
+
+
+/**
+ * Update the favicon in a browser window toolbar to reflect the RISC OS
+ * filetype of the supplied content. If the toolbar currently has a
+ * site favicon set, then this call will be ignored.
+ *
+ * \param *toolbar The toolbar to refresh.
+ * \param *h The page content to reflect.
+ */
+
+void ro_toolbar_set_content_favicon(struct toolbar *toolbar,
+ struct hlcache_handle *h);
+
+
+/**
+ * Update the state of the URL suggestion pop-up menu icon on a toolbar.
+ *
+ * \param *toolbar The toolbar to update.
+ */
+
+void ro_toolbar_update_urlsuggest(struct toolbar *toolbar);
+
+
+/**
+ * Set the display button bar state for a toolbar.
+ *
+ * \param *toolbar the toolbar to update.
+ * \param display true to display the button bar; else false.
+ */
+
+void ro_toolbar_set_display_buttons(struct toolbar *toolbar, bool display);
+
+
+/**
+ * Set the display URL bar state for a toolbar.
+ *
+ * \param *toolbar the toolbar to update.
+ * \param display true to display the URL bar; else false.
+ */
+
+void ro_toolbar_set_display_url(struct toolbar *toolbar, bool display);
+
+
+/**
+ * Set the display throbber state for a toolbar.
+ *
+ * \param *toolbar the toolbar to update.
+ * \param display true to display the throbber; else false.
+ */
+
+void ro_toolbar_set_display_throbber(struct toolbar *toolbar, bool display);
+
+
+/**
+ * Return true or false depending on whether the given toolbar is set to
+ * display the button bar.
+ *
+ * \param *toolbar the toolbar of interest.
+ * \return true if the toolbar exists and the button bar is
+ * shown; else false.
+ */
+
+bool ro_toolbar_get_display_buttons(struct toolbar *toolbar);
+
+
+/**
+ * Return true or false depending on whether the given toolbar is set to
+ * display the URL bar.
+ *
+ * \param *toolbar the toolbar of interest.
+ * \return true if the toolbar exists and the URL bar is
+ * shown; else false.
+ */
+
+bool ro_toolbar_get_display_url(struct toolbar *toolbar);
+
+
+/**
+ * Return true or false depending on whether the given toolbar is set to
+ * display the throbber.
+ *
+ * \param *toolbar the toolbar of interest.
+ * \return true if the toolbar exists and the throbber is
+ * shown; else false.
+ */
+
+bool ro_toolbar_get_display_throbber(struct toolbar *toolbar);
+
+
+/**
+ * Return true or false depending on whether the given toolbar is currently
+ * being edited.
+ *
+ * \param *toolbar the toolbar of interest.
+ * \return true if the toolbar exists and is beng edited;
+ * else false.
+ */
+
+bool ro_toolbar_get_editing(struct toolbar *toolbar);
+
+
+/**
+ * Toggle toolbar edit mode on the given toolbar. Only a button bar can be
+ * edited, so edit mode can only be toggled if there's an editor button
+ * bar defined.
+ *
+ * \param *toolbar The toolbar to be toggled.
+ * \return true if the action was successful; false if
+ * the action failed and the toolbar was destroyed.
+ */
+
+bool ro_toolbar_toggle_edit(struct toolbar *toolbar);
+
+#endif
+
diff --git a/riscos/treeview.c b/riscos/treeview.c
index afd636519..78bf9f0b4 100644
--- a/riscos/treeview.c
+++ b/riscos/treeview.c
@@ -46,7 +46,7 @@
#include "riscos/gui.h"
#include "riscos/image.h"
#include "riscos/menus.h"
-#include "riscos/theme.h"
+#include "riscos/toolbar.h"
#include "riscos/tinct.h"
#include "riscos/textarea.h"
#include "riscos/treeview.h"
@@ -87,6 +87,7 @@ struct ro_treeview
int y; /*< Y coordinate of drag start */
} drag_start;
tree_drag_type drag; /*< The current drag type for the tree */
+ struct ro_treeview_callbacks *callbacks; /*< Callback handlers */
};
static void ro_treeview_redraw_request(int x, int y, int width, int height,
@@ -109,6 +110,13 @@ static bool ro_treeview_keypress(wimp_key *key);
static void ro_treeview_set_window_extent(ro_treeview *tv,
int width, int height);
+static void ro_treeview_update_theme(void *data, bool ok);
+static void ro_treeview_update_toolbar(void *data);
+static void ro_treeview_button_update(void *data);
+static void ro_treeview_save_toolbar_buttons(void *data, char *config);
+static void ro_treeview_button_click(void *data,
+ toolbar_action_type action_type, union toolbar_action action);
+
static const struct treeview_table ro_tree_callbacks = {
ro_treeview_redraw_request,
ro_treeview_resized,
@@ -116,18 +124,29 @@ static const struct treeview_table ro_tree_callbacks = {
ro_treeview_get_window_dimensions
};
+static const struct toolbar_callbacks ro_treeview_toolbar_callbacks = {
+ ro_treeview_update_theme,
+ ro_treeview_update_toolbar,
+ ro_treeview_button_update,
+ ro_treeview_button_click,
+ NULL, /* No toolbar keypress handler */
+ ro_treeview_save_toolbar_buttons
+};
+
+
/**
* Create a RISC OS GUI implementation of a treeview tree.
*
* \param window The window to create the tree in.
* \param *toolbar A toolbar to attach to the window.
+ * \param *callbacks Callbacks to service the treeview.
* \param flags The treeview flags.
*
* \return The RISC OS treeview pointer.
*/
ro_treeview *ro_treeview_create(wimp_w window, struct toolbar *toolbar,
- unsigned int flags)
+ struct ro_treeview_callbacks *callbacks, unsigned int flags)
{
ro_treeview *tv;
@@ -166,6 +185,10 @@ ro_treeview *ro_treeview_create(wimp_w window, struct toolbar *toolbar,
tv->drag = TREE_NO_DRAG;
+ /* Record the callback info. */
+
+ tv->callbacks = callbacks;
+
/* Register wimp events to handle the supplied window. */
ro_gui_wimp_event_register_redraw_window(tv->w, ro_treeview_redraw);
@@ -194,6 +217,18 @@ void ro_treeview_destroy(ro_treeview *tv)
}
/**
+ * Return a pointer to a toolbar callbacks structure with the handlers to be
+ * used by any treeview window toolbars.
+ *
+ * \return A pointer to the callback structure.
+ */
+
+const struct toolbar_callbacks *ro_treeview_get_toolbar_callbacks(void)
+{
+ return &ro_treeview_toolbar_callbacks;
+}
+
+/**
* Change the redraw origin of a treeview tree in RISC OS graphics units.
*
* \param *tv The ro_treeview object to update.
@@ -702,7 +737,7 @@ static void ro_treeview_open(wimp_open *open)
}
if (tv->tb)
- ro_gui_theme_process_toolbar(tv->tb, -1);
+ ro_toolbar_process(tv->tb, -1, false);
}
@@ -786,10 +821,16 @@ static bool ro_treeview_mouse_click(wimp_pointer *pointer)
if (tv->drag == TREE_SELECT_DRAG ||
tv->drag == TREE_MOVE_DRAG)
ro_treeview_drag_start(tv, pointer, &state);
+
+
+ if (tv->callbacks != NULL &&
+ tv->callbacks->toolbar_button_update != NULL)
+ tv->callbacks->toolbar_button_update();
}
/* We assume that the owning module will have attached a window menu
- * to our parent window. If it hasn't, this call will quietly fail.
+ * to our parent window with the auto flag unset (so that we can fudge
+ * the selection above). If it hasn't, this call will quietly fail.
*/
if (pointer->buttons == wimp_CLICK_MENU)
@@ -860,6 +901,10 @@ void ro_treeview_mouse_at(wimp_pointer *pointer)
tv->drag_start.y, xpos, ypos);
tv->drag = TREE_NO_DRAG;
}
+
+ if (tv->callbacks != NULL &&
+ tv->callbacks->toolbar_button_update != NULL)
+ tv->callbacks->toolbar_button_update();
}
@@ -884,7 +929,7 @@ static void ro_treeview_drag_start(ro_treeview *tv, wimp_pointer *pointer,
drag.bbox.y0 = state->visible.y0;
drag.bbox.x1 = state->visible.x1;
drag.bbox.y1 = state->visible.y1 -
- ro_gui_theme_toolbar_height(tv->tb);
+ ro_toolbar_height(tv->tb);
switch (tv->drag) {
case TREE_SELECT_DRAG:
@@ -922,7 +967,7 @@ static void ro_treeview_drag_start(ro_treeview *tv, wimp_pointer *pointer,
auto_scroll.pause_zone_sizes.y0 = 80;
auto_scroll.pause_zone_sizes.x1 = 80;
auto_scroll.pause_zone_sizes.y1 = 80 +
- ro_gui_theme_toolbar_height(tv->tb);
+ ro_toolbar_height(tv->tb);
auto_scroll.pause_duration = 0;
auto_scroll.state_change = (void *) 1;
@@ -1038,8 +1083,14 @@ static bool ro_treeview_keypress(wimp_key *key)
}
if (!(c & IS_WIMP_KEY)) {
- if (tree_keypress(tv->tree, c))
+ if (tree_keypress(tv->tree, c)) {
+ if (tv->callbacks &&
+ tv->callbacks->toolbar_button_update
+ != NULL)
+ tv->callbacks->toolbar_button_update();
+
return true;
+ }
}
return false;
@@ -1049,23 +1100,20 @@ static bool ro_treeview_keypress(wimp_key *key)
/**
* Update a treeview to use a new theme.
*
- * \param *tv Pointer to the treeview to update.
+ * \param *data Pointer to the treeview to update.
+ * \param ok true if the bar still exists; else false.
*/
-void ro_treeview_update_theme(ro_treeview *tv)
+void ro_treeview_update_theme(void *data, bool ok)
{
- if (tv != NULL && tv->tb != NULL){
- /* \todo -- Check for toolbar editing here. */
+ ro_treeview *tv = (ro_treeview *) data;
- if (!ro_gui_theme_update_toolbar(NULL, tv->tb)) {
- ro_gui_theme_destroy_toolbar(tv->tb);
+ if (tv != NULL && tv->tb != NULL){
+ if (ok) {
+ ro_treeview_update_toolbar(tv);
+ } else {
tv->tb = NULL;
}
-
- /* \todo -- Check for toolbar editing here. */
-
- ro_gui_theme_attach_toolbar(tv->tb, tv->w);
- ro_treeview_update_toolbar(tv);
}
}
@@ -1073,33 +1121,86 @@ void ro_treeview_update_theme(ro_treeview *tv)
/**
* Change the size of a treeview's toolbar and redraw the window.
*
- * \param *tv The treeview to update.
+ * \param *data The treeview to update.
*/
-void ro_treeview_update_toolbar(ro_treeview *tv)
+void ro_treeview_update_toolbar(void *data)
{
+ ro_treeview *tv = (ro_treeview *) data;
+
+ if (tv != NULL && tv->tb != NULL) {
ro_treeview_set_origin(tv, 0,
- -(ro_gui_theme_toolbar_height(tv->tb)));
+ -(ro_toolbar_height(tv->tb)));
xwimp_force_redraw(tv->w, 0, tv->extent.y, tv->extent.x, 0);
+ }
+}
+
+
+/**
+ * Update the toolbar icons in a treeview window's toolbar. As we're just
+ * an intermediate widget, we pass the details on down the chain.
+ *
+ * \param *data The treeview owning the toolbar.
+ */
+void ro_treeview_button_update(void *data)
+{
+ ro_treeview *tv = (ro_treeview *) data;
+
+ if (tv == NULL || tv->callbacks == NULL)
+ return;
+
+ if (tv->callbacks->toolbar_button_update != NULL)
+ tv->callbacks->toolbar_button_update();
+}
+
+
+/**
+ * Save a new button configuration from a treeview window's toolbar. As
+ * we're just an intermediate widget, we pass the details on.
+ *
+ * \param *data The treeview owning the toolbar.
+ * \param *config The new button config string.
+ */
+
+void ro_treeview_save_toolbar_buttons(void *data, char *config)
+{
+ ro_treeview *tv = (ro_treeview *) data;
+
+ if (tv == NULL || tv->callbacks == NULL)
+ return;
+
+ if (tv->callbacks->toolbar_button_save != NULL)
+ tv->callbacks->toolbar_button_save(config);
+}
+
+
+/**
+ * Process clicks on buttons in a treeview window's toolbar. As we're just
+ * an intermediate widget, we just pass the details on down the chain.
+ *
+ * \param *data The treeview owning the click.
+ * \param action_type The action type to be handled.
+ * \param action The action to handle.
+ */
+
+void ro_treeview_button_click(void *data,
+ toolbar_action_type action_type, union toolbar_action action)
+{
+ ro_treeview *tv = (ro_treeview *) data;
+
+ if (tv == NULL || tv->callbacks == NULL ||
+ action_type != TOOLBAR_ACTION_BUTTON)
+ return;
+
+ if (tv->callbacks->toolbar_button_click != NULL)
+ tv->callbacks->toolbar_button_click(action.button);
+
+ if (tv->callbacks->toolbar_button_update != NULL)
+ tv->callbacks->toolbar_button_update();
}
-#if 0
- if ((tree) && (tree->toolbar)) {
- if (tree->toolbar->editor)
- if (!ro_gui_theme_update_toolbar(NULL, tree->toolbar->editor))
- tree->toolbar->editor = NULL;
- if (!ro_gui_theme_update_toolbar(NULL, tree->toolbar)) {
- ro_gui_theme_destroy_toolbar(tree->toolbar);
- tree->toolbar = NULL;
- }
- ro_gui_theme_toolbar_editor_sync(tree->toolbar);
- ro_gui_theme_attach_toolbar(tree->toolbar, (wimp_w)tree->handle);
- tree_resized(tree);
- xwimp_force_redraw((wimp_w)tree->handle, 0, -16384, 16384, 16384);
- }
-#endif
/**
* Return a token identifying the interactive help message for a given cursor
diff --git a/riscos/treeview.h b/riscos/treeview.h
index 7f4da9074..54919522b 100644
--- a/riscos/treeview.h
+++ b/riscos/treeview.h
@@ -29,6 +29,7 @@
#include <oslib/wimp.h>
#include "desktop/tree.h"
+#include "riscos/toolbar.h"
/* defined in front end code */
extern const char tree_directory_icon_name[];
@@ -36,13 +37,16 @@ extern const char tree_content_icon_name[];
typedef struct ro_treeview ro_treeview;
-struct ro_treeview_table {
- void (*open_menu)(wimp_pointer *pointer);
+struct ro_treeview_callbacks {
+ void (*toolbar_button_click)(button_bar_action action);
+ void (*toolbar_button_update)(void);
+ void (*toolbar_button_save)(char *);
};
ro_treeview *ro_treeview_create(wimp_w window, struct toolbar *toolbar,
- unsigned int flags);
+ struct ro_treeview_callbacks *callbacks, unsigned int flags);
void ro_treeview_destroy(ro_treeview *tv);
+const struct toolbar_callbacks *ro_treeview_get_toolbar_callbacks(void);
struct tree *ro_treeview_get_tree(ro_treeview *tv);
wimp_w ro_treeview_get_window(ro_treeview *tv);
@@ -51,8 +55,6 @@ bool ro_treeview_has_selection(ro_treeview *tv);
void ro_treeview_set_origin(ro_treeview *tv, int x, int y);
void ro_treeview_mouse_at(wimp_pointer *pointer);
void ro_treeview_drag_end(wimp_dragged *drag);
-void ro_treeview_update_theme(ro_treeview *tv);
-void ro_treeview_update_toolbar(ro_treeview *tv);
int ro_treeview_get_help(help_full_message_request *message_data);
#endif
diff --git a/riscos/uri.c b/riscos/uri.c
index 44cac853b..0a2dcbbd1 100644
--- a/riscos/uri.c
+++ b/riscos/uri.c
@@ -27,7 +27,6 @@
#include "utils/config.h"
#include "content/fetch.h"
#include "desktop/browser.h"
-#include "riscos/theme.h"
#include "desktop/gui.h"
#include "riscos/gui.h"
#include "riscos/uri.h"
diff --git a/riscos/url_complete.c b/riscos/url_complete.c
index 9649c5604..98820b7a3 100644
--- a/riscos/url_complete.c
+++ b/riscos/url_complete.c
@@ -31,7 +31,7 @@
#include "riscos/global_history.h"
#include "riscos/gui.h"
#include "riscos/options.h"
-#include "riscos/theme.h"
+#include "riscos/toolbar.h"
#include "riscos/url_complete.h"
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
@@ -62,59 +62,59 @@ static int mouse_y;
static bool url_complete_callback(const char *url,
const struct url_data *data);
-/**
- * Should be called when the caret is placed into a URL completion icon.
- *
- * \param g the gui_window to initialise URL completion for
- */
-void ro_gui_url_complete_start(struct gui_window *g)
+
+/* This is an exported interface documented in url_complete.h */
+
+void ro_gui_url_complete_start(struct toolbar *toolbar)
{
- const char *url;
+ const char *url;
+ wimp_w parent;
+
+ assert(toolbar != NULL);
+ parent = ro_toolbar_get_parent_window(toolbar);
- if ((!g->toolbar) || (!g->toolbar->display_url) ||
- (g->window == url_complete_parent))
+ if (!ro_toolbar_get_display_url(toolbar) ||
+ (parent == url_complete_parent))
return;
- ro_gui_url_complete_close(NULL, 0);
- url = ro_gui_get_icon_string(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL);
+ ro_gui_url_complete_close();
+ url = ro_toolbar_get_url(toolbar);
url_complete_matched_string = strdup(url);
if (url_complete_matched_string)
- url_complete_parent = g->window;
+ url_complete_parent = parent;
}
-/**
- * Handles a keypress for URL completion
- *
- * \param g the gui_window to update
- * \param key the key pressed (as UTF32 code or wimp key + bit31 set)
- * \return true to indicate keypress handled, false otherwise
- */
-bool ro_gui_url_complete_keypress(struct gui_window *g, uint32_t key)
+/* This is an exported interface documented in url_complete.h */
+
+bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key)
{
- wimp_window_state state;
- char *match_url;
- const char *url;
- int i, lines;
- int old_selection;
- int height;
- os_error *error;
- bool currently_open;
+ wimp_w parent;
+ wimp_window_state state;
+ char *match_url;
+ const char *url;
+ int i, lines;
+ int old_selection;
+ int height;
+ os_error *error;
+ bool currently_open;
+
+ assert(toolbar != NULL);
+ parent = ro_toolbar_get_parent_window(toolbar);
/* we must have a toolbar/url bar */
- if ((!g->toolbar) || (!g->toolbar->display_url) ||
+ if (!ro_toolbar_get_display_url(toolbar) ||
(!option_url_suggestion)) {
- ro_gui_url_complete_close(NULL, 0);
+ ro_gui_url_complete_close();
return false;
}
/* if we are currently active elsewhere, remove the previous window */
- currently_open = ((g->window == url_complete_parent) &&
+ currently_open = ((parent == url_complete_parent) &&
(url_complete_matches_available > 0));
- if (g->window != url_complete_parent)
- ro_gui_url_complete_close(NULL, 0);
+ if (parent != url_complete_parent)
+ ro_gui_url_complete_close();
/* forcibly open on down keys */
if ((!currently_open) && (url_complete_matched_string)) {
@@ -129,12 +129,11 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, uint32_t key)
/* get the text to match */
- url_complete_parent = g->window;
- url = ro_gui_get_icon_string(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL);
- match_url = strdup(url);
- if (!match_url) {
- ro_gui_url_complete_close(NULL, 0);
+ url_complete_parent = parent;
+ url = ro_toolbar_get_url(toolbar);
+ match_url = (url != NULL) ? strdup(url) : NULL;
+ if (match_url == NULL) {
+ ro_gui_url_complete_close();
return false;
}
@@ -181,7 +180,7 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, uint32_t key)
if (!url_complete_matches) {
url_complete_matches = malloc(64 * sizeof(char *));
if (!url_complete_matches) {
- ro_gui_url_complete_close(NULL, 0);
+ ro_gui_url_complete_close();
return false;
}
url_complete_matches_allocated = 64;
@@ -195,12 +194,12 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, uint32_t key)
urldb_iterate_partial(match_url, url_complete_callback);
if ((url_complete_memory_exhausted) ||
(url_complete_matches_available == 0)) {
- ro_gui_url_complete_close(NULL, 0);
+ ro_gui_url_complete_close();
return false;
}
/* update the window */
- state.w = g->window;
+ state.w = parent;
error = xwimp_get_window_state(&state);
if (error) {
LOG(("xwimp_get_window_state: 0x%x: %s",
@@ -209,7 +208,7 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, uint32_t key)
return false;
}
url_complete_matches_reset = true;
- ro_gui_url_complete_resize(g, PTR_WIMP_OPEN(&state));
+ ro_gui_url_complete_resize(toolbar, PTR_WIMP_OPEN(&state));
url_complete_matches_reset = false;
/* redraw the relevant bits of the window */
@@ -300,14 +299,13 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, uint32_t key)
}
if (url_complete_matches_selection == -1) {
- ro_gui_set_icon_string(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL,
- url_complete_original_url, true);
+ ro_toolbar_set_url(toolbar,
+ url_complete_original_url, true, false);
} else {
- ro_gui_set_icon_string(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL,
+ ro_toolbar_set_url(toolbar,
url_complete_matches[
- url_complete_matches_selection], true);
+ url_complete_matches_selection],
+ true, false);
free(url_complete_matched_string);
url_complete_matched_string = strdup(url_complete_matches[
url_complete_matches_selection]);
@@ -343,6 +341,7 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, uint32_t key)
return true;
}
+
/**
* Callback function for urldb_iterate_partial
*
@@ -350,6 +349,7 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, uint32_t key)
* \param data Data associated with URL
* \return true to continue iteration, false otherwise
*/
+
bool url_complete_callback(const char *url, const struct url_data *data)
{
const char **array_extend;
@@ -379,21 +379,18 @@ bool url_complete_callback(const char *url, const struct url_data *data)
return true;
}
-/**
- * Move and resize the url completion window to match the toolbar.
- *
- * \param g the gui_window to update
- * \param open the wimp_open request (updated on exit)
- */
-void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open)
+
+/* This is an exported interface documented in url_complete.h */
+
+void ro_gui_url_complete_resize(struct toolbar *toolbar, wimp_open *open)
{
- os_box extent = { 0, 0, 0, 0 };
- wimp_icon_state url_state;
- wimp_window_state toolbar_state;
- wimp_window_state state;
- os_error *error;
- int lines;
- int scroll_v = 0;
+ os_box extent = { 0, 0, 0, 0 };
+ os_box url_extent;
+ wimp_window_state toolbar_state;
+ wimp_window_state state;
+ os_error *error;
+ int lines;
+ int scroll_v = 0;
/* only react to our window */
if (open->w != url_complete_parent)
@@ -401,10 +398,10 @@ void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open)
/* if there is no toolbar, or there is no URL bar shown,
* or there are no URL matches, close it */
- if ((!g->toolbar) || (!g->toolbar->display_url) ||
+ if (!ro_toolbar_get_display_url(toolbar) ||
(!url_complete_matches) ||
(url_complete_matches_available == 0)) {
- ro_gui_url_complete_close(NULL, 0);
+ ro_gui_url_complete_close();
return;
}
@@ -422,7 +419,7 @@ void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open)
state.yscroll = 0;
/* move the window to the correct position */
- toolbar_state.w = g->toolbar->toolbar_handle;
+ toolbar_state.w = ro_toolbar_get_window(toolbar);
error = xwimp_get_window_state(&toolbar_state);
if (error) {
LOG(("xwimp_get_window_state: 0x%x: %s",
@@ -431,13 +428,8 @@ void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open)
return;
}
- url_state.w = g->toolbar->toolbar_handle;
- url_state.i = ICON_TOOLBAR_SURROUND;
- error = xwimp_get_icon_state(&url_state);
- if (error) {
- LOG(("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
+ if (!ro_toolbar_get_url_field_extent(toolbar, &url_extent)) {
+ LOG(("Failed to read URL field extent."));
return;
}
@@ -460,10 +452,9 @@ void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open)
scroll_v = ro_get_vscroll_width(NULL) - 2;
state.flags |= wimp_WINDOW_VSCROLL;
}
- state.visible.x0 = open->visible.x0 + 2 + url_state.icon.extent.x0;
- state.visible.x1 = open->visible.x0 - 2 +
- url_state.icon.extent.x1 - scroll_v;
- state.visible.y1 = open->visible.y1 - url_state.icon.extent.y1 + 2;
+ state.visible.x0 = open->visible.x0 + 2 + url_extent.x0;
+ state.visible.x1 = open->visible.x0 - 2 + url_extent.x1 - scroll_v;
+ state.visible.y1 = open->visible.y1 - url_extent.y1 + 2;
state.visible.y0 = state.visible.y1 - (lines * 44);
if (state.visible.x1 + scroll_v > toolbar_state.visible.x1)
state.visible.x1 = toolbar_state.visible.x1 - scroll_v;
@@ -488,23 +479,21 @@ void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open)
}
-/**
- * Try to close the current url completion window
- *
- * \param g the gui_window the user clicked on (or NULL to forcibly close)
- * \param i the icon the user clicked on to prompt the close
- * \return whether the window was closed
- */
-bool ro_gui_url_complete_close(struct gui_window *g, wimp_i i)
+/* This is an exported interface documented in url_complete.h */
+
+bool ro_gui_url_complete_close(void)
{
- os_error *error;
- bool currently_open;
+ os_error *error;
+ bool currently_open;
- if ((g && (i == ICON_TOOLBAR_URL) &&
- (g->window == url_complete_parent)))
- return false;
+ /* There used to be a check here to see if the icon clicked was the
+ * URL text field in the toolbar. Since this only applied to clicks
+ * originating from the toolbar module following the restructuring,
+ * and this check was better done within the toolbar, it has been
+ * removed from this function and the associated parameters removed.
+ */
- currently_open = ((url_complete_parent) &&
+ currently_open = ((url_complete_parent != NULL) &&
(url_complete_matches_available > 0));
free(url_complete_matches);
@@ -530,11 +519,8 @@ bool ro_gui_url_complete_close(struct gui_window *g, wimp_i i)
}
-/**
- * Redraws a section of the URL completion window
- *
- * \param redraw the area to redraw
- */
+/* This is an exported interface documented in url_complete.h */
+
void ro_gui_url_complete_redraw(wimp_draw *redraw)
{
osbool more;
@@ -633,11 +619,8 @@ void ro_gui_url_complete_redraw(wimp_draw *redraw)
}
-/**
- * Handle mouse movement over the URL completion window.
- *
- * \param pointer the pointer state
- */
+/* This is an exported interface documented in url_complete.h */
+
void ro_gui_url_complete_mouse_at(wimp_pointer *pointer)
{
wimp_mouse_state current;
@@ -649,12 +632,8 @@ void ro_gui_url_complete_mouse_at(wimp_pointer *pointer)
}
-/**
- * Handle mouse clicks in the URL completion window.
- *
- * \param pointer the pointer state
- * \return whether the click was handled
- */
+/* This is an exported interface documented in url_complete.h */
+
bool ro_gui_url_complete_click(wimp_pointer *pointer)
{
wimp_window_state state;
@@ -685,9 +664,7 @@ bool ro_gui_url_complete_click(wimp_pointer *pointer)
g = ro_gui_window_lookup(url_complete_parent);
if (!g)
return false;
- url = ro_gui_get_icon_string(
- g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL);
+ url = ro_toolbar_get_url(g->toolbar);
free(url_complete_original_url);
url_complete_original_url = strdup(url);
if (!url_complete_original_url)
@@ -722,10 +699,10 @@ bool ro_gui_url_complete_click(wimp_pointer *pointer)
/* Select sets the text and launches */
if (pointer->buttons == wimp_CLICK_SELECT) {
- ro_gui_set_icon_string(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL,
+ ro_toolbar_set_url(g->toolbar,
url_complete_matches[
- url_complete_matches_selection], true);
+ url_complete_matches_selection],
+ true, false);
/** \todo The interaction of components here is hideous */
/* Do NOT make any attempt to use any of the global url
@@ -740,15 +717,16 @@ bool ro_gui_url_complete_click(wimp_pointer *pointer)
url_complete_matches[
url_complete_matches_selection],
0, true);
- ro_gui_url_complete_close(NULL, 0);
+ ro_gui_url_complete_close();
/* Adjust just sets the text */
} else if (pointer->buttons == wimp_CLICK_ADJUST) {
- ro_gui_set_icon_string(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL,
+ ro_toolbar_set_url(g->toolbar,
url_complete_matches[
- url_complete_matches_selection], true);
- ro_gui_url_complete_keypress(g, 0);
+ url_complete_matches_selection],
+ true, false);
+ ro_gui_url_complete_keypress(g->toolbar, 0);
}
return true;
}
+
diff --git a/riscos/url_complete.h b/riscos/url_complete.h
index 299135791..12f640086 100644
--- a/riscos/url_complete.h
+++ b/riscos/url_complete.h
@@ -29,12 +29,72 @@
struct gui_window;
-void ro_gui_url_complete_start(struct gui_window *g);
-bool ro_gui_url_complete_keypress(struct gui_window *g, uint32_t key);
-void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open);
-bool ro_gui_url_complete_close(struct gui_window *g, wimp_i i);
+/**
+ * Should be called when the caret is placed into a URL completion icon.
+ *
+ * \param *toolbar The toolbar to initialise URL completion for.
+ */
+
+void ro_gui_url_complete_start(struct toolbar *toolbar);
+
+
+/**
+ * Handles a keypress for URL completion
+ *
+ * \param *toolbar The toolbar to be updated.
+ * \param key the key pressed (as UTF32 code or
+ * wimp key + bit31 set)
+ * \return true to indicate keypress handled; else false.
+ */
+
+bool ro_gui_url_complete_keypress(struct toolbar *toolbar, uint32_t key);
+
+
+/**
+ * Move and resize the url completion window to match the toolbar.
+ *
+ * \param *toolbar The toolbar to update
+ * \param *open the wimp_open request (updated on exit)
+ */
+
+void ro_gui_url_complete_resize(struct toolbar *toolbar, wimp_open *open);
+
+
+/**
+ * Try to close the current url completion window
+ *
+ * \return whether the window was closed
+ */
+
+bool ro_gui_url_complete_close(void);
+
+
+/**
+ * Redraws a section of the URL completion window
+ *
+ * \param redraw the area to redraw
+ */
+
void ro_gui_url_complete_redraw(wimp_draw *redraw);
+
+
+/**
+ * Handle mouse movement over the URL completion window.
+ *
+ * \param pointer the pointer state
+ */
+
void ro_gui_url_complete_mouse_at(wimp_pointer *pointer);
+
+
+/**
+ * Handle mouse clicks in the URL completion window.
+ *
+ * \param pointer the pointer state
+ * \return whether the click was handled
+ */
+
bool ro_gui_url_complete_click(wimp_pointer *pointer);
#endif
+
diff --git a/riscos/url_suggest.c b/riscos/url_suggest.c
index 82ca5520c..be766e1bd 100644
--- a/riscos/url_suggest.c
+++ b/riscos/url_suggest.c
@@ -34,28 +34,29 @@ struct url_suggest_item {
struct url_suggest_item *next; /*< The next URL in the list. */
};
-static bool url_suggest_callback(const char *url, const struct url_data *data);
+static bool ro_gui_url_suggest_callback(const char *url,
+ const struct url_data *data);
-static wimp_menu *suggest_menu;
static int suggest_entries;
static time_t suggest_time;
static struct url_suggest_item *suggest_list;
+static wimp_MENU(URL_SUGGEST_MAX_URLS) url_suggest_menu_block;
+wimp_menu *ro_gui_url_suggest_menu = (wimp_menu *) &url_suggest_menu_block;
+
+
/**
- * Initialise the URL suggestion menu. A menu block which must be set to
- * contain URL_SUGGEST_MAX_URLS entries is passed in.
+ * Initialise the URL suggestion menu. This MUST be called before anything
+ * tries to use the URL menu.
*
- * /param *menu The menu to use as the suggestion menu.
* /return true if initialisation was OK; else false.
*/
-bool ro_gui_url_suggest_init(wimp_menu *menu)
+bool ro_gui_url_suggest_init(void)
{
- suggest_menu = menu;
-
- suggest_menu->title_data.indirected_text.text =
+ ro_gui_url_suggest_menu->title_data.indirected_text.text =
(char *) messages_get("URLSuggest");
- ro_gui_menu_init_structure((wimp_menu *) suggest_menu,
+ ro_gui_menu_init_structure((wimp_menu *) ro_gui_url_suggest_menu,
URL_SUGGEST_MAX_URLS);
suggest_entries = 0;
@@ -65,6 +66,21 @@ bool ro_gui_url_suggest_init(wimp_menu *menu)
/**
+ * Check if there is a URL suggestion menu available for use.
+ *
+ * \TODO -- Ideally this should be able to decide if there's a menu
+ * available without actually having to build it all.
+ *
+ * /return true if the menu has entries; else false.
+ */
+
+bool ro_gui_url_suggest_get_menu_available(void)
+{
+ return ro_gui_url_suggest_prepare_menu();
+}
+
+
+/**
* Builds the URL suggestion menu. This is called by ro_gui_menu_create() when
* it is asked to display the url_suggest_menu.
*
@@ -82,7 +98,7 @@ bool ro_gui_url_suggest_prepare_menu(void)
suggest_list = NULL;
suggest_time = time(NULL);
- urldb_iterate_entries(url_suggest_callback);
+ urldb_iterate_entries(ro_gui_url_suggest_callback);
/* If any menu entries were found, put them into the menu. The list
* is in reverse order, last to first, so the menu is filled backwards.
@@ -100,10 +116,12 @@ bool ro_gui_url_suggest_prepare_menu(void)
while (list != NULL && i > 0) {
i--;
- suggest_menu->entries[i].menu_flags = 0;
- suggest_menu->entries[i].data.indirected_text.text =
+ ro_gui_url_suggest_menu->entries[i].menu_flags = 0;
+ ro_gui_url_suggest_menu->
+ entries[i].data.indirected_text.text =
(char *) list->url;
- suggest_menu->entries[i].data.indirected_text.size =
+ ro_gui_url_suggest_menu->
+ entries[i].data.indirected_text.size =
strlen(list->url) + 1;
next = list->next;
@@ -113,9 +131,10 @@ bool ro_gui_url_suggest_prepare_menu(void)
assert(i == 0);
- suggest_menu->entries[0].menu_flags |=
+ ro_gui_url_suggest_menu->entries[0].menu_flags |=
wimp_MENU_TITLE_INDIRECTED;
- suggest_menu->entries[suggest_entries - 1].menu_flags |=
+ ro_gui_url_suggest_menu->
+ entries[suggest_entries - 1].menu_flags |=
wimp_MENU_LAST;
return true;
@@ -133,7 +152,7 @@ bool ro_gui_url_suggest_prepare_menu(void)
* \return true to continue iteration, false otherwise
*/
-bool url_suggest_callback(const char *url, const struct url_data *data)
+bool ro_gui_url_suggest_callback(const char *url, const struct url_data *data)
{
int count;
unsigned int weight;
@@ -193,3 +212,21 @@ bool url_suggest_callback(const char *url, const struct url_data *data)
return true;
}
+
+/**
+ * Process a selection from the URL Suggest menu.
+ *
+ * \param *selection The menu selection.
+ * \return Pointer to the URL that was selected, or NULL for none.
+ */
+
+const char *ro_gui_url_suggest_get_selection(wimp_selection *selection)
+{
+ const char *url = NULL;
+
+ if (selection->items[0] >= 0)
+ url = ro_gui_url_suggest_menu->entries[selection->items[0]].
+ data.indirected_text.text;
+
+ return url;
+}
diff --git a/riscos/url_suggest.h b/riscos/url_suggest.h
index d13b7d89a..738cb9bf7 100644
--- a/riscos/url_suggest.h
+++ b/riscos/url_suggest.h
@@ -27,8 +27,12 @@
#define URL_SUGGEST_MAX_URLS 16
-bool ro_gui_url_suggest_init(wimp_menu *menu);
+extern wimp_menu *ro_gui_url_suggest_menu;
+
+bool ro_gui_url_suggest_init(void);
+bool ro_gui_url_suggest_get_menu_available(void);
bool ro_gui_url_suggest_prepare_menu(void);
+const char *ro_gui_url_suggest_get_selection(wimp_selection *selection);
#endif
diff --git a/riscos/wimp.c b/riscos/wimp.c
index 71443afb4..6043b6791 100644
--- a/riscos/wimp.c
+++ b/riscos/wimp.c
@@ -36,7 +36,6 @@
#include "desktop/gui.h"
#include "riscos/gui.h"
#include "riscos/oslib_pre7.h"
-#include "riscos/theme.h"
#include "riscos/wimp.h"
#include "utils/log.h"
#include "utils/utf8.h"
@@ -546,6 +545,71 @@ bool ro_gui_get_icon_shaded_state(wimp_w w, wimp_i i)
/**
+ * Set the deleted state of an icon.
+ *
+ * \param w window handle
+ * \param i icon handle
+ * \param state shaded state
+ */
+void ro_gui_set_icon_deleted_state(wimp_w w, wimp_i i, bool state)
+{
+ wimp_caret caret;
+ os_error *error;
+
+ /* update the state */
+ if (ro_gui_get_icon_deleted_state(w, i) == state)
+ return;
+ error = xwimp_set_icon_state(w, i,
+ (state ? wimp_ICON_DELETED : 0), wimp_ICON_DELETED);
+ if (error) {
+ LOG(("xwimp_get_icon_state: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+ if (!state)
+ return;
+
+ /* ensure the caret is not in a shaded icon */
+ error = xwimp_get_caret_position(&caret);
+ if (error) {
+ LOG(("xwimp_get_caret_position: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return;
+ }
+ if ((caret.w != w) || (caret.i != i))
+ return;
+ /* move the caret to the first avaiable writable */
+ if (ro_gui_set_caret_first(w))
+ return;
+ /* lose the caret */
+ error = xwimp_set_caret_position((wimp_w)-1, (wimp_i)-1, -1, -1, -1, -1);
+ if (error) {
+ LOG(("xwimp_set_caret_position: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return;
+ }
+}
+
+
+/**
+ * Gets the deleted state of an icon.
+ *
+ * \param w window handle
+ * \param i icon handle
+ */
+bool ro_gui_get_icon_deleted_state(wimp_w w, wimp_i i)
+{
+ wimp_icon_state ic;
+ ic.w = w;
+ ic.i = i;
+ xwimp_get_icon_state(&ic);
+ return (ic.icon.flags & wimp_ICON_DELETED) != 0;
+}
+
+
+/**
* Set the button type of an icon.
*
* \param w window handle
@@ -841,6 +905,52 @@ os_error *ro_gui_wimp_get_sprite(const char *name, osspriteop_header **sprite)
/**
+ * Get the dimensions of a sprite
+ *
+ * \param *area The sprite area to use.
+ * \param *sprite Pointer to the sprite name.
+ * \param *width Return the sprite width.
+ * \param *height Return the sprite height.
+ * \return true if successful; else false.
+ */
+
+bool ro_gui_wimp_get_sprite_dimensions(osspriteop_area *area, char *sprite,
+ int *width, int *height)
+{
+ os_error *error = NULL;
+ os_mode mode;
+ os_coord dimensions;
+
+ dimensions.x = 0;
+ dimensions.y = 0;
+
+ if (area != (osspriteop_area *) -1)
+ error = xosspriteop_read_sprite_info(osspriteop_USER_AREA,
+ area, (osspriteop_id) sprite,
+ &dimensions.x, &dimensions.y, 0, &mode);
+
+ if (error != NULL || area == (osspriteop_area *) -1)
+ error = xwimpspriteop_read_sprite_info(sprite,
+ &dimensions.x, &dimensions.y, 0, &mode);
+
+ if (error == NULL) {
+ ro_convert_pixels_to_os_units(&dimensions, mode);
+ if (width != NULL)
+ *width = dimensions.x;
+ if (height != NULL)
+ *height = dimensions.y;
+ } else 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 false;
+ }
+
+ return true;
+}
+
+
+/**
* Performs simple user redraw for a window.
*
* \param user_fill whether to fill the redraw area
diff --git a/riscos/wimp.h b/riscos/wimp.h
index a1672ae67..cd30fc7e5 100644
--- a/riscos/wimp.h
+++ b/riscos/wimp.h
@@ -54,6 +54,8 @@ void ro_gui_set_icon_selected_state(wimp_w w, wimp_i i, bool state);
bool ro_gui_get_icon_selected_state(wimp_w w, wimp_i i);
void ro_gui_set_icon_shaded_state(wimp_w w, wimp_i i, bool state);
bool ro_gui_get_icon_shaded_state(wimp_w w, wimp_i i);
+void ro_gui_set_icon_deleted_state(wimp_w w, wimp_i i, bool state);
+bool ro_gui_get_icon_deleted_state(wimp_w w, wimp_i i);
void ro_gui_set_icon_button_type(wimp_w w, wimp_i i, int type);
void ro_gui_set_icon_sprite(wimp_w w, wimp_i i, osspriteop_area *area,
const char *name);
@@ -64,7 +66,8 @@ void ro_gui_open_window_centre(wimp_w parent, wimp_w child);
osspriteop_area *ro_gui_load_sprite_file(const char *pathname);
bool ro_gui_wimp_sprite_exists(const char *sprite);
os_error *ro_gui_wimp_get_sprite(const char *name, osspriteop_header **sprite);
-
+bool ro_gui_wimp_get_sprite_dimensions(osspriteop_area *area, char *sprite,
+ int *width, int *height);
wimp_w ro_gui_set_window_background_colour(wimp_w window, wimp_colour background);
void ro_gui_set_icon_colours(wimp_w window, wimp_i icon,
diff --git a/riscos/wimp_event.c b/riscos/wimp_event.c
index 43011a0e6..384a5258e 100644
--- a/riscos/wimp_event.c
+++ b/riscos/wimp_event.c
@@ -1,6 +1,6 @@
/*
* Copyright 2005 Richard Wilson <info@tinct.net>
- * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
+ * Copyright 2010, 2011 Stephen Fryatt <stevef@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -95,16 +95,19 @@ struct event_window {
void (*open_window)(wimp_open *open);
void (*close_window)(wimp_w w);
void (*redraw_window)(wimp_draw *redraw);
- void (*menu_selection)(wimp_w w, wimp_i i);
+ bool (*menu_prepare)(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_pointer *p);
+ bool (*menu_selection)(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_selection *s, menu_action a);
+ void (*menu_warning)(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_selection *s, menu_action a);
+ void (*menu_close)(wimp_w w, wimp_i i, wimp_menu *m);
wimp_menu *window_menu;
bool window_menu_auto;
- void (*window_menu_prepare)(wimp_w w, wimp_menu *m);
- bool (*window_menu_selection)(wimp_w w, wimp_menu *m,
- wimp_selection *s, menu_action action);
- void (*window_menu_close)(wimp_w w, wimp_menu *m);
- void (*window_menu_warning)(wimp_w w, wimp_menu *m,
- wimp_selection *s, menu_action action);
+ bool window_menu_iconbar;
const char *help_prefix;
+ const char *(*get_help_suffix)(wimp_w w, wimp_i i, os_coord *pos,
+ wimp_mouse_state buttons);
void *user_data;
struct icon_event *first;
struct event_window *next;
@@ -117,7 +120,7 @@ static struct event_window *ro_gui_wimp_event_get_window(wimp_w w);
static struct event_window *ro_gui_wimp_event_find_window(wimp_w w);
static struct icon_event *ro_gui_wimp_event_get_event(wimp_w w, wimp_i i,
event_type type);
-static void ro_gui_wimp_event_prepare_menu(wimp_w w, struct icon_event *event);
+static void ro_gui_wimp_event_prepare_gright_menu(wimp_w w, struct icon_event *event);
static struct event_window *ro_gui_wimp_event_remove_window(wimp_w w);
static struct event_window *ro_gui_wimp_event_windows[WIN_HASH_SIZE];
@@ -243,6 +246,40 @@ bool ro_gui_wimp_event_validate(wimp_w w)
return true;
}
+/**
+ * Transfer event data from one window to another. This can be used as an
+ * alternative to ro_gui_wimp_event_finalise() and re-registering, if
+ * events need to continue across a change of window handle.
+ *
+ * All aspects of the registered events MUST remain the same in the new
+ * window!
+ *
+ * \param from The current window, which is to be deleted.
+ * \param to The window to which the events should transfer.
+ * \return true on success; false for an unknown window.
+ */
+
+bool ro_gui_wimp_event_transfer(wimp_w from, wimp_w to)
+{
+ struct event_window *window;
+ int h;
+
+ LOG(("Transferring all events from window 0x%x to window 0x%x",
+ (unsigned int) from, (unsigned int) to));
+
+ window = ro_gui_wimp_event_remove_window(from);
+ if (window == NULL || window->w != from)
+ return false;
+
+ h = WIN_HASH(to);
+ window->w = to;
+ window->next = ro_gui_wimp_event_windows[h];
+ ro_gui_wimp_event_windows[h] = window;
+
+ ro_gui_menu_window_changed(from, to);
+
+ return true;
+}
/**
* Free any resources associated with a window.
@@ -280,6 +317,61 @@ void ro_gui_wimp_event_finalise(wimp_w w)
/**
+ * Free any resources associated with a specific icon in a window.
+ *
+ * \param w The window containing the icon.
+ * \param i The icon to free resources for.
+ */
+
+void ro_gui_wimp_event_deregister(wimp_w w, wimp_i i)
+{
+ struct event_window *window;
+ struct icon_event *event, *parent, *child;
+
+ LOG(("Removing all events for window 0x%x, icon %d",
+ (unsigned int)w, (int)i));
+ window = ro_gui_wimp_event_get_window(w);
+ if (!window)
+ return;
+
+ /* Remove any events that apply to the given icon. */
+
+ event = window->first;
+ parent = NULL;
+
+ while (event != NULL) {
+ child = event->next;
+
+ if (event->i == i) {
+ LOG(("Removing event 0x%x", (unsigned int) event));
+
+ if (parent == NULL)
+ window->first = child;
+ else
+ parent->next = child;
+
+ switch (event->type) {
+ case EVENT_NUMERIC_FIELD:
+ case EVENT_TEXT_FIELD:
+ if (event->previous_value.textual)
+ free(event->previous_value.textual);
+ event->previous_value.textual = NULL;
+ break;
+ default:
+ break;
+ }
+
+ free(event);
+ } else {
+ parent = event;
+ }
+
+ event = child;
+ }
+}
+
+
+/**
* Set the associated help prefix for a given window.
*
* \param w the window to get the prefix for
@@ -316,6 +408,45 @@ const char *ro_gui_wimp_event_get_help_prefix(wimp_w w)
/**
+ * Register a handler to decode help suffixes for a given window.
+ *
+ */
+
+bool ro_gui_wimp_event_register_help_suffix(wimp_w w,
+ const char *(*get_help_suffix)(wimp_w w, wimp_i i,
+ os_coord *pos, wimp_mouse_state buttons))
+{
+ struct event_window *window;
+
+ window = ro_gui_wimp_event_get_window(w);
+ if (!window)
+ return false;
+ window->get_help_suffix = get_help_suffix;
+ return true;
+}
+
+
+/**
+ * Get the associated help suffix.
+ *
+ * \param w The window to get the suffix for
+ * \return The associated prefix, or NULL
+ */
+
+const char *ro_gui_wimp_event_get_help_suffix(wimp_w w, wimp_i i,
+ os_coord *pos, wimp_mouse_state buttons)
+{
+ struct event_window *window;
+
+ window = ro_gui_wimp_event_find_window(w);
+ if (window == NULL || window->get_help_suffix == NULL)
+ return NULL;
+
+ return window->get_help_suffix(w, i, pos, buttons);
+}
+
+
+/**
* Sets the user data associated with a window.
*
* \param w the window to associate the data with
@@ -371,7 +502,8 @@ void *ro_gui_wimp_event_get_user_data(wimp_w w)
* \param menu the menu that has been selected
* \param selection the selection information
* \param action the menu action info from menus.c
- * \return true if the event was handled, false otherwise
+ * \return true if the menu is OK for an Adjust re-open;
+ * else false.
*/
bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu,
wimp_selection *selection, menu_action action)
@@ -384,32 +516,33 @@ bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu,
wimp_caret caret;
wimp_icon_state ic;
unsigned int button_type;
+ bool prepared;
window = ro_gui_wimp_event_find_window(w);
- if (!window)
+ if (window == NULL)
return false;
/* Start by looking for an icon event that matches. If there isn't one,
- * then check to see if there is a window menu and associated
- * selection handler available instead.
+ * then return details for an unconnected menu. It's up to the
+ * event recipient to sort out if this is a window menu or not, based
+ * on the menu handle passed back.
*/
for (event = window->first; event; event = event->next)
if ((event->type == EVENT_MENU_GRIGHT) && (event->i == i))
break;
if (!event) {
- if ((window->window_menu) && (window->window_menu == menu)
- && (window->window_menu_selection)) {
- window->window_menu_selection(w, menu,
- selection, action);
+ if (window->menu_selection)
+ window->menu_selection(window->w, wimp_ICON_WINDOW,
+ menu, selection, action);
+
+ /* Prepare the menu pending a possible Adjust click. */
+ if (window->menu_prepare)
+ if (!window->menu_prepare(window->w, wimp_ICON_WINDOW,
+ menu, NULL))
+ return false;
- /* Prepare the menu pending a possible Adjust click. */
- if (window->window_menu_prepare)
- window->window_menu_prepare(w, menu);
- return true;
- } else {
- return false;
- }
+ return true;
}
menu_entry = &menu->entries[selection->items[0]];
@@ -423,9 +556,15 @@ bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu,
ro_gui_set_icon_string(window->w, event->data.menu_gright.field,
menu_entry->data.indirected_text.text, false);
- ro_gui_wimp_event_prepare_menu(window->w, event);
if (window->menu_selection)
- window->menu_selection(window->w, event->i);
+ window->menu_selection(window->w, event->i, menu,
+ selection, action);
+ prepared = true;
+ if (window->menu_prepare)
+ prepared = window->menu_prepare(window->w, event->i,
+ menu, NULL);
+ if (prepared)
+ ro_gui_wimp_event_prepare_gright_menu(window->w, event);
/* set the caret for writable icons and send a CTRL+U keypress to
* stimulate activity if needed */
@@ -441,7 +580,7 @@ bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu,
button_type = (ic.icon.flags & wimp_ICON_BUTTON_TYPE) >> wimp_ICON_BUTTON_TYPE_SHIFT;
if ((button_type != wimp_BUTTON_WRITABLE) &&
(button_type != wimp_BUTTON_WRITE_CLICK_DRAG))
- return true;
+ return prepared;
error = xwimp_get_caret_position(&caret);
if (error) {
LOG(("xwimp_get_caret_position: 0x%x: %s",
@@ -463,7 +602,7 @@ bool ro_gui_wimp_event_menu_selection(wimp_w w, wimp_i i, wimp_menu *menu,
key.c = 21; // ctrl+u
window->keypress(&key);
}
- return true;
+ return prepared;
}
@@ -493,6 +632,7 @@ bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
wimp_window_state open;
wimp_caret caret;
os_error *error;
+ bool prepared;
w = pointer->w;
window = ro_gui_wimp_event_find_window(w);
@@ -500,7 +640,9 @@ bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
return false;
/* Menu clicks take priority if there is an auto menu defined. */
- if ((window->window_menu) && (window->window_menu_auto)) {
+ if ((pointer->buttons == wimp_CLICK_MENU) &&
+ (window->window_menu != NULL) &&
+ (window->window_menu_auto)) {
ro_gui_wimp_event_process_window_menu_click(pointer);
return true;
}
@@ -574,7 +716,7 @@ bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
}
ro_gui_dialog_add_persistent(current_menu_window,
pointer->w);
- ro_gui_menu_closed(false);
+ ro_gui_menu_closed();
gui_poll(true);
error = xwimp_open_window(PTR_WIMP_OPEN(&open));
if (error) {
@@ -596,8 +738,15 @@ bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
}
}
/* display the menu */
- ro_gui_wimp_event_prepare_menu(pointer->w, event);
- ro_gui_popup_menu(event->data.menu_gright.menu, pointer->w, pointer->i);
+
+ prepared = true;
+ if (window->menu_prepare != NULL)
+ prepared = window->menu_prepare(pointer->w, pointer->i,
+ event->data.menu_gright.menu, pointer);
+ if (prepared) {
+ ro_gui_wimp_event_prepare_gright_menu(pointer->w, event);
+ ro_gui_popup_menu(event->data.menu_gright.menu, pointer->w, pointer->i);
+ }
break;
case EVENT_CHECKBOX:
break;
@@ -617,7 +766,7 @@ bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
if (pointer->buttons & wimp_CLICK_SELECT) {
ro_gui_dialog_close(pointer->w);
ro_gui_wimp_event_close_window(pointer->w);
- ro_gui_menu_closed(true);
+ ro_gui_menu_closed();
} else {
ro_gui_wimp_event_restore(pointer->w);
}
@@ -636,7 +785,7 @@ bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer)
* /param w the window owning the menu
* /param event the icon event owning the menu
*/
-void ro_gui_wimp_event_prepare_menu(wimp_w w, struct icon_event *event)
+void ro_gui_wimp_event_prepare_gright_menu(wimp_w w, struct icon_event *event)
{
int i;
const char *text;
@@ -699,7 +848,7 @@ void ro_gui_wimp_event_ok_click(struct event_window *window,
if (state & wimp_CLICK_SELECT) {
ro_gui_dialog_close(window->w);
ro_gui_wimp_event_close_window(window->w);
- ro_gui_menu_closed(true);
+ ro_gui_menu_closed();
} else {
ro_gui_wimp_event_memorise(window->w);
}
@@ -863,7 +1012,7 @@ bool ro_gui_wimp_event_keypress(wimp_key *key)
}
}
} else {
- k.c |= (1u<<31);
+ k.c |= IS_WIMP_KEY;
}
/* registered routines take priority */
@@ -894,7 +1043,7 @@ bool ro_gui_wimp_event_keypress(wimp_key *key)
return false;
ro_gui_dialog_close(key->w);
ro_gui_wimp_event_close_window(key->w);
- ro_gui_menu_closed(true);
+ ro_gui_menu_closed();
return true;
/* Return performs the OK action */
case wimp_KEY_RETURN:
@@ -975,23 +1124,102 @@ bool ro_gui_wimp_event_redraw_window(wimp_draw *redraw)
bool ro_gui_wimp_event_process_window_menu_click(wimp_pointer *pointer)
{
- struct event_window *window;
+ struct event_window *window;
+ int xpos, ypos, line_height, gap_height, entry;
window = ro_gui_wimp_event_find_window(pointer->w);
if ((window) && (window->window_menu)
&& (pointer->buttons == wimp_CLICK_MENU)) {
- if (window->window_menu_prepare)
- window->window_menu_prepare(window->w,
- window->window_menu);
+ if (window->menu_prepare)
+ if (!window->menu_prepare(window->w, wimp_ICON_WINDOW,
+ window->window_menu, pointer))
+ return false;
- ro_gui_menu_create(window->window_menu,
- pointer->pos.x, pointer->pos.y,
- window->w, false);
+ if (window->window_menu_iconbar) {
+ xpos = pointer->pos.x;
+ ypos = 96;
+
+ line_height = window->window_menu->height +
+ window->window_menu->gap;
+ gap_height = 24; /* The fixed dotted line height */
+
+ entry = 0;
+ do {
+ ypos += line_height;
+ if ((window->window_menu->
+ entries[entry].menu_flags &
+ wimp_MENU_SEPARATE) != 0)
+ ypos += gap_height;
+ } while ((window->window_menu->
+ entries[entry++].menu_flags &
+ wimp_MENU_LAST) == 0);
+ } else {
+ xpos = pointer->pos.x;
+ ypos = pointer->pos.y;
+ }
+
+ ro_gui_menu_create(window->window_menu, xpos, ypos, window->w);
return true;
}
return false;
}
+
+/**
+ * Trigger a window's Prepare Menu event.
+ *
+ * \param w The window to use.
+ * \param i The icon to use.
+ * \param *menu The menu handle to use.
+ * \return true if the affected menu was prepared OK; else
+ * false.
+ */
+
+bool ro_gui_wimp_event_prepare_menu(wimp_w w, wimp_i i, wimp_menu *menu)
+{
+ struct event_window *window;
+
+ window = ro_gui_wimp_event_find_window(w);
+ if (window == NULL)
+ return false;
+
+ if (window->menu_prepare)
+ return window->menu_prepare(w, i, menu, NULL);
+
+ /* The menu is always OK if there's no event handler. */
+
+ return true;
+}
+
+/**
+ * Register a window menu to be (semi-)automatically handled.
+ *
+ * \param w The window to attach the menu to.
+ * \param *m The menu to be attached.
+ * \param menu_auto true if the menu should be opened autimatically
+ * on Menu clicks with no task intervention; false
+ * to pass clicks to the window's Mouse Event
+ * handler and leave that to pass the menu click
+ * back to us for handling and menu opening.
+ * \param bool_position_ibar true if the menu should open in an iconbar
+ * position; false to open at the pointer.
+ * \return true if the menu was registed ok; else false.
+ */
+
+bool ro_gui_wimp_event_register_menu(wimp_w w, wimp_menu *m,
+ bool menu_auto, bool position_ibar)
+{
+ struct event_window *window;
+
+ window = ro_gui_wimp_event_get_window(w);
+ if (!window)
+ return false;
+ window->window_menu = m;
+ window->window_menu_auto = menu_auto;
+ window->window_menu_iconbar = position_ibar;
+ return true;
+}
+
/**
* Register a numeric field to be automatically handled
*/
@@ -1227,11 +1455,40 @@ bool ro_gui_wimp_event_register_redraw_window(wimp_w w,
return true;
}
+
+/**
+ * Register a function to be called before a menu is (re-)opened.
+ *
+ * \param *w The window for which events should be returned.
+ * \param *callback A function to be called beofre the menu is
+ * (re-)opened.
+ * \return true if the menu was registed ok; else false.
+ */
+bool ro_gui_wimp_event_register_menu_prepare(wimp_w w,
+ bool (*callback)(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_pointer *p))
+{
+ struct event_window *window;
+
+ window = ro_gui_wimp_event_get_window(w);
+ if (!window)
+ return false;
+ window->menu_prepare = callback;
+ return true;
+}
+
+
/**
* Register a function to be called following a menu selection.
+ *
+ * \param *w The window for which events should be returned.
+ * \param *callback A function to be called when a selection is
+ * made.
+ * \return true if the menu was registed ok; else false.
*/
bool ro_gui_wimp_event_register_menu_selection(wimp_w w,
- void (*callback)(wimp_w w, wimp_i i))
+ bool (*callback)(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_selection *s, menu_action a))
{
struct event_window *window;
@@ -1242,32 +1499,45 @@ bool ro_gui_wimp_event_register_menu_selection(wimp_w w,
return true;
}
+
/**
- * Register a set of functions to be called to handle a window menu.
+ * Register a function to be called when a sub-menu warning is received.
*
- * \param
+ * \param *w The window for which events should be returned.
+ * \param *callback A function to be called whenever a submenu
+ * warning is received for the menu.
+ * \return true if the menu was registed ok; else false.
*/
+bool ro_gui_wimp_event_register_menu_warning(wimp_w w,
+ void (*callback)(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_selection *s, menu_action a))
+{
+ struct event_window *window;
+
+ window = ro_gui_wimp_event_get_window(w);
+ if (!window)
+ return false;
+ window->menu_warning = callback;
+ return true;
+}
-bool ro_gui_wimp_event_register_window_menu(wimp_w w, wimp_menu *m,
- void (*callback_prepare)(wimp_w w, wimp_menu *m),
- bool (*callback_selection)(wimp_w w, wimp_menu *m,
- wimp_selection *s, menu_action action),
- void (*callback_close)(wimp_w w, wimp_menu *m),
- void (*callback_warning)(wimp_w w, wimp_menu *m,
- wimp_selection *s, menu_action action),
- bool menu_auto)
+
+/**
+ * Register a function to be called before a menu is finally closed.
+ *
+ * \param *w The window for which events should be returned.
+ * \param *callback A function to be called when the menu is closed.
+ * \return true if the menu was registed ok; else false.
+ */
+bool ro_gui_wimp_event_register_menu_close(wimp_w w,
+ void (*callback)(wimp_w w, wimp_i i, wimp_menu *m))
{
struct event_window *window;
window = ro_gui_wimp_event_get_window(w);
if (!window)
return false;
- window->window_menu = m;
- window->window_menu_prepare = callback_prepare;
- window->window_menu_selection = callback_selection;
- window->window_menu_close = callback_close;
- window->window_menu_warning = callback_warning;
- window->window_menu_auto = menu_auto;
+ window->menu_close = callback;
return true;
}
@@ -1408,20 +1678,29 @@ bool ro_gui_wimp_event_submenu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
for (event = window->first; event; event = event->next)
if ((event->type == EVENT_MENU_GRIGHT) && (event->i == i))
break;
- if (event)
+ if (event) {
+ if (window->menu_close != NULL &&
+ event->type == EVENT_MENU_GRIGHT &&
+ event->data.menu_gright.menu == menu) {
+ window->menu_close(w, i, menu);
+ return true;
+ }
+
return false;
+ }
/* If the warning is for a window menu, then pass the event on to it. */
if ((window->window_menu) && (window->window_menu == menu)) {
- if (window->window_menu_warning) {
- window->window_menu_warning(w, menu, selection, action);
+ if (window->menu_warning) {
+ window->menu_warning(w, wimp_ICON_WINDOW, menu,
+ selection, action);
return true;
}
}
return false;
-}
+}
/**
* Handle menus being closed. This is called from ro_gui_menu_closed(), in
@@ -1440,8 +1719,8 @@ void ro_gui_wimp_event_menus_closed(wimp_w w, wimp_i i, wimp_menu *menu)
ro_gui_wimp_event_register_submenu(0);
/* Process the event for any window menus. Find the window data, then
- * try and match to an icon event. If we can, then there isn't anything
- * to do.
+ * try and match to an icon event. If we can, then GRight menus are
+ * sent the event; otherwise, we do nothing.
*/
window = ro_gui_wimp_event_find_window(w);
@@ -1451,14 +1730,19 @@ void ro_gui_wimp_event_menus_closed(wimp_w w, wimp_i i, wimp_menu *menu)
for (event = window->first; event; event = event->next)
if ((event->type == EVENT_MENU_GRIGHT) && (event->i == i))
break;
- if (event)
+ if (event) {
+ if (window->menu_close != NULL &&
+ event->type == EVENT_MENU_GRIGHT &&
+ event->data.menu_gright.menu == menu)
+ window->menu_close(w, i, menu);
return;
+ }
/* If the close is for a window menu, then pass the event on to it. */
if ((window->window_menu) && (window->window_menu == menu) &&
- (window->window_menu_close))
- window->window_menu_close(w, menu);
+ (window->menu_close))
+ window->menu_close(w, wimp_ICON_WINDOW, menu);
}
/**
diff --git a/riscos/wimp_event.h b/riscos/wimp_event.h
index 54ae95ae5..f232291d8 100644
--- a/riscos/wimp_event.h
+++ b/riscos/wimp_event.h
@@ -1,6 +1,6 @@
/*
* Copyright 2005 Richard Wilson <info@tinct.net>
- * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
+ * Copyright 2010, 2011 Stephen Fryatt <stevef@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -31,7 +31,7 @@
#include <stdio.h>
#include <string.h>
#include "oslib/os.h"
-#include "oslib/wimp.h"
+#include "oslib/wimp.h"
#include "riscos/menus.h"
#define IS_WIMP_KEY (1u<<31)
@@ -39,10 +39,17 @@
bool ro_gui_wimp_event_memorise(wimp_w w);
bool ro_gui_wimp_event_restore(wimp_w w);
bool ro_gui_wimp_event_validate(wimp_w w);
+bool ro_gui_wimp_event_transfer(wimp_w from, wimp_w to);
void ro_gui_wimp_event_finalise(wimp_w w);
+void ro_gui_wimp_event_deregister(wimp_w w, wimp_i i);
bool ro_gui_wimp_event_set_help_prefix(wimp_w w, const char *help_prefix);
const char *ro_gui_wimp_event_get_help_prefix(wimp_w w);
+bool ro_gui_wimp_event_register_help_suffix(wimp_w w,
+ const char *(*get_help_suffix)(wimp_w w, wimp_i i,
+ os_coord *pos, wimp_mouse_state buttons));
+const char *ro_gui_wimp_event_get_help_suffix(wimp_w w, wimp_i i,
+ os_coord *pos, wimp_mouse_state buttons);
bool ro_gui_wimp_event_set_user_data(wimp_w w, void *user);
void *ro_gui_wimp_event_get_user_data(wimp_w w);
@@ -52,10 +59,13 @@ bool ro_gui_wimp_event_mouse_click(wimp_pointer *pointer);
bool ro_gui_wimp_event_keypress(wimp_key *key);
bool ro_gui_wimp_event_open_window(wimp_open *open);
bool ro_gui_wimp_event_close_window(wimp_w w);
-bool ro_gui_wimp_event_redraw_window(wimp_draw *redraw);
-
+bool ro_gui_wimp_event_redraw_window(wimp_draw *redraw);
+
bool ro_gui_wimp_event_process_window_menu_click(wimp_pointer *pointer);
+bool ro_gui_wimp_event_prepare_menu(wimp_w w, wimp_i i, wimp_menu *menu);
+bool ro_gui_wimp_event_register_menu(wimp_w w, wimp_menu *m,
+ bool menu_auto, bool position_ibar);
bool ro_gui_wimp_event_register_numeric_field(wimp_w w, wimp_i i, wimp_i up,
wimp_i down, int min, int max, int stepping,
int decimal_places);
@@ -80,18 +90,19 @@ bool ro_gui_wimp_event_register_close_window(wimp_w w,
void (*callback)(wimp_w w));
bool ro_gui_wimp_event_register_redraw_window(wimp_w w,
void (*callback)(wimp_draw *redraw));
+bool ro_gui_wimp_event_register_menu_prepare(wimp_w w,
+ bool (*callback)(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_pointer *p));
bool ro_gui_wimp_event_register_menu_selection(wimp_w w,
- void (*callback)(wimp_w w, wimp_i i));
-bool ro_gui_wimp_event_register_window_menu(wimp_w w, wimp_menu *m,
- void (*callback_prepare)(wimp_w w, wimp_menu *m),
- bool (*callback_selection)(wimp_w w, wimp_menu *m,
- wimp_selection *s, menu_action action),
- void (*callback_close)(wimp_w w, wimp_menu *m),
- void (*callback_warning)(wimp_w w, wimp_menu *m,
- wimp_selection *s, menu_action action),
- bool menu_auto);
+ bool (*callback)(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_selection *s, menu_action a));
+bool ro_gui_wimp_event_register_menu_warning(wimp_w w,
+ void (*callback)(wimp_w w, wimp_i i, wimp_menu *m,
+ wimp_selection *s, menu_action a));
+bool ro_gui_wimp_event_register_menu_close(wimp_w w,
+ void (*callback)(wimp_w w, wimp_i i, wimp_menu *m));
-bool ro_gui_wimp_event_submenu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
+bool ro_gui_wimp_event_submenu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
wimp_selection *selection, menu_action action);
void ro_gui_wimp_event_menus_closed(wimp_w w, wimp_i i, wimp_menu *menu);
void ro_gui_wimp_event_register_submenu(wimp_w w);
diff --git a/riscos/window.c b/riscos/window.c
index 1aa2a82f2..3f07e793d 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -5,7 +5,7 @@
* Copyright 2004 Andrew Timmins <atimmins@blueyonder.co.uk>
* Copyright 2005 Richard Wilson <info@tinct.net>
* Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net>
- * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
+ * Copyright 2010, 2011 Stephen Fryatt <stevef@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -46,9 +46,13 @@
#include "content/urldb.h"
#include "css/css.h"
#include "desktop/browser.h"
+#include "desktop/cookies.h"
#include "desktop/frames.h"
+#include "desktop/history_core.h"
+#include "desktop/hotlist.h"
#include "desktop/mouse.h"
#include "desktop/plotters.h"
+#include "desktop/selection.h"
#include "desktop/textinput.h"
#include "desktop/thumbnail.h"
#include "desktop/tree.h"
@@ -57,21 +61,26 @@
#include "render/form.h"
#include "riscos/bitmap.h"
#include "riscos/buffer.h"
+#include "riscos/cookies.h"
#include "riscos/dialog.h"
#include "riscos/global_history.h"
#include "riscos/gui.h"
#include "riscos/gui/status_bar.h"
+#include "riscos/help.h"
+#include "riscos/hotlist.h"
#include "riscos/menus.h"
#include "riscos/options.h"
#include "riscos/oslib_pre7.h"
#include "riscos/save.h"
#include "riscos/sprite.h"
-#include "riscos/theme.h"
+#include "riscos/toolbar.h"
#include "riscos/thumbnail.h"
#include "riscos/url_complete.h"
+#include "riscos/url_suggest.h"
#include "riscos/wimp.h"
#include "riscos/wimp_event.h"
#include "riscos/wimputils.h"
+#include "riscos/window.h"
#include "utils/log.h"
#include "utils/talloc.h"
#include "utils/url.h"
@@ -79,6 +88,66 @@
#include "utils/utils.h"
#include "utils/messages.h"
+
+static void gui_window_set_extent(struct gui_window *g, int width, int height);
+
+static void ro_gui_window_redraw(wimp_draw *redraw);
+static void ro_gui_window_open(wimp_open *open);
+static void ro_gui_window_close(wimp_w w);
+static bool ro_gui_window_click(wimp_pointer *mouse);
+static bool ro_gui_window_keypress(wimp_key *key);
+static void ro_gui_window_toolbar_keypress(void *data, wimp_key *key);
+static void ro_gui_window_handle_local_keypress(struct gui_window *g,
+ wimp_key *key, bool is_toolbar);
+static bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer);
+static void ro_gui_window_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action);
+static bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action);
+static void ro_gui_window_menu_close(wimp_w w, wimp_i i, wimp_menu *menu);
+
+static void ro_gui_window_toolbar_click(void *data,
+ toolbar_action_type action_type, union toolbar_action action);
+
+static bool ro_gui_window_content_export_types(hlcache_handle *h,
+ bool *export_draw, bool *export_sprite);
+static bool ro_gui_window_up_available(struct browser_window *bw);
+static void ro_gui_window_prepare_pageinfo(struct gui_window *g);
+static void ro_gui_window_prepare_objectinfo(hlcache_handle *object,
+ const char *href);
+
+static void ro_gui_window_launch_url(struct gui_window *g, const char *url);
+static bool ro_gui_window_navigate_up(struct gui_window *g, const char *url);
+static void ro_gui_window_action_home(struct gui_window *g);
+static void ro_gui_window_action_new_window(struct gui_window *g);
+static void ro_gui_window_action_local_history(struct gui_window *g);
+static void ro_gui_window_action_navigate_back_new(struct gui_window *g);
+static void ro_gui_window_action_navigate_forward_new(struct gui_window *g);
+static void ro_gui_window_action_save(struct gui_window *g,
+ gui_save_type save_type);
+static void ro_gui_window_action_search(struct gui_window *g);
+static void ro_gui_window_action_zoom(struct gui_window *g);
+static void ro_gui_window_action_add_bookmark(struct gui_window *g);
+static void ro_gui_window_action_print(struct gui_window *g);
+static void ro_gui_window_action_page_info(struct gui_window *g);
+
+static void ro_gui_window_remove_update_boxes(struct gui_window *g);
+static void ro_gui_window_update_toolbar_buttons(struct gui_window *g);
+static void ro_gui_window_update_toolbar(void *data);
+static void ro_gui_window_save_toolbar_buttons(void *data, char *config);
+static void ro_gui_window_update_theme(void *data, bool ok);
+
+static bool ro_gui_window_import_text(struct gui_window *g,
+ const char *filename, bool toolbar);
+static void ro_gui_window_clone_options(struct browser_window *new_bw,
+ struct browser_window *old_bw);
+
+static bool ro_gui_window_prepare_form_select_menu(struct browser_window *bw,
+ struct form_control *control);
+static void ro_gui_window_process_form_select_menu(struct gui_window *g,
+ wimp_selection *selection);
+
#ifndef wimp_KEY_END
#define wimp_KEY_END wimp_KEY_COPY
#endif
@@ -99,17 +168,25 @@ static bool mouse_drag_select;
static bool mouse_drag_adjust;
/** List of all browser windows. */
-static struct gui_window *window_list = 0;
+static struct gui_window *window_list = 0;
/** GUI window which is being redrawn. Valid only during redraw. */
-struct gui_window *ro_gui_current_redraw_gui;
+struct gui_window *ro_gui_current_redraw_gui;
+/** Form control which gui_form_select_menu is for. */
+static struct form_control *gui_form_select_control;
+/** The browser window menu handle. */
+static wimp_menu *ro_gui_browser_window_menu = NULL;
+/** Menu of options for form select controls. */
+static wimp_menu *gui_form_select_menu = NULL;
+/** Object under menu, or 0 if no object. */
+static hlcache_handle *current_menu_object = 0;
+/** URL of link under menu, or 0 if no link. */
+static const char *current_menu_url = 0;
static float scale_snap_to[] = {0.10, 0.125, 0.25, 0.333, 0.5, 0.75,
1.0,
1.5, 2.0, 3.0, 4.0, 6.0, 8.0, 12.0, 16.0};
#define SCALE_SNAP_TO_SIZE (sizeof scale_snap_to) / (sizeof(float))
-
-
/** An entry in ro_gui_pointer_table. */
struct ro_gui_pointer_entry {
bool wimp_area; /** The pointer is in the Wimp's sprite area. */
@@ -142,20 +219,6 @@ struct ro_gui_pointer_entry ro_gui_pointer_table[] = {
{ false, "ptr_progress", 0, 0 },
};
-
-static void ro_gui_window_remove_update_boxes(struct gui_window *g);
-static void gui_window_set_extent(struct gui_window *g, int width, int height);
-static void ro_gui_window_open(wimp_open *open);
-static void ro_gui_window_close(wimp_w w);
-static void ro_gui_window_redraw(wimp_draw *redraw);
-static bool ro_gui_window_click(wimp_pointer *mouse);
-static bool ro_gui_window_keypress(wimp_key *key);
-static void ro_gui_window_launch_url(struct gui_window *g, const char *url);
-static void ro_gui_window_clone_options(struct browser_window *new_bw,
- struct browser_window *old_bw);
-static bool ro_gui_window_import_text(struct gui_window *g,
- const char *filename, bool toolbar);
-
struct update_box {
int x0;
int y0;
@@ -170,6 +233,129 @@ struct update_box {
struct update_box *pending_updates;
#define MARGIN 4
+static const struct toolbar_callbacks ro_gui_window_toolbar_callbacks = {
+ ro_gui_window_update_theme,
+ ro_gui_window_update_toolbar,
+ (void (*)(void *)) ro_gui_window_update_toolbar_buttons,
+ ro_gui_window_toolbar_click,
+ ro_gui_window_toolbar_keypress,
+ ro_gui_window_save_toolbar_buttons
+};
+
+
+/**
+ * Initialise the browser window module and its menus.
+ */
+
+void ro_gui_window_initialise(void)
+{
+ /* Build the browser window menu. */
+
+ static const struct ns_menu browser_definition = {
+ "NetSurf", {
+ { "Page", BROWSER_PAGE, 0 },
+ { "Page.PageInfo",BROWSER_PAGE_INFO, &dialog_pageinfo },
+ { "Page.Save", BROWSER_SAVE, &dialog_saveas },
+ { "Page.SaveComp", BROWSER_SAVE_COMPLETE, &dialog_saveas },
+ { "Page.Export", NO_ACTION, 0 },
+#ifdef WITH_DRAW_EXPORT
+ { "Page.Export.Draw", BROWSER_EXPORT_DRAW, &dialog_saveas },
+#endif
+#ifdef WITH_PDF_EXPORT
+ { "Page.Export.PDF", BROWSER_EXPORT_PDF, &dialog_saveas },
+#endif
+ { "Page.Export.Text", BROWSER_EXPORT_TEXT, &dialog_saveas },
+ { "Page.SaveURL", NO_ACTION, 0 },
+ { "Page.SaveURL.URI", BROWSER_SAVE_URL_URI, &dialog_saveas },
+ { "Page.SaveURL.URL", BROWSER_SAVE_URL_URL, &dialog_saveas },
+ { "Page.SaveURL.LinkText", BROWSER_SAVE_URL_TEXT, &dialog_saveas },
+ { "_Page.Print", BROWSER_PRINT, &dialog_print },
+ { "Page.NewWindow", BROWSER_NEW_WINDOW, 0 },
+ { "Page.FindText", BROWSER_FIND_TEXT, &dialog_search },
+ { "Page.ViewSrc", BROWSER_VIEW_SOURCE, 0 },
+ { "Object", BROWSER_OBJECT, 0 },
+ { "Object.Object", BROWSER_OBJECT_OBJECT, 0 },
+ { "Object.Object.ObjInfo", BROWSER_OBJECT_INFO, &dialog_objinfo },
+ { "Object.Object.ObjSave", BROWSER_OBJECT_SAVE, &dialog_saveas },
+ { "Object.Object.Export", BROWSER_OBJECT_EXPORT, 0 },
+ { "Object.Object.Export.Sprite", BROWSER_OBJECT_EXPORT_SPRITE, &dialog_saveas },
+#ifdef WITH_DRAW_EXPORT
+ { "Object.Object.Export.ObjDraw", BROWSER_OBJECT_EXPORT_DRAW, &dialog_saveas },
+#endif
+ { "Object.Object.SaveURL", NO_ACTION, 0 },
+ { "Object.Object.SaveURL.URI", BROWSER_OBJECT_SAVE_URL_URI, &dialog_saveas },
+ { "Object.Object.SaveURL.URL", BROWSER_OBJECT_SAVE_URL_URL, &dialog_saveas },
+ { "Object.Object.SaveURL.LinkText", BROWSER_OBJECT_SAVE_URL_TEXT, &dialog_saveas },
+ { "Object.Object.ObjPrint", BROWSER_OBJECT_PRINT, 0 },
+ { "Object.Object.ObjReload", BROWSER_OBJECT_RELOAD, 0 },
+ { "Object.Link", BROWSER_OBJECT_LINK, 0 },
+ { "Object.Link.LinkSave", BROWSER_LINK_SAVE, 0 },
+ { "Object.Link.LinkSave.URI", BROWSER_LINK_SAVE_URI, &dialog_saveas },
+ { "Object.Link.LinkSave.URL", BROWSER_LINK_SAVE_URL, &dialog_saveas },
+ { "Object.Link.LinkSave.LinkText", BROWSER_LINK_SAVE_TEXT, &dialog_saveas },
+ { "_Object.Link.LinkDload", BROWSER_LINK_DOWNLOAD, 0 },
+ { "Object.Link.LinkNew", BROWSER_LINK_NEW_WINDOW, 0 },
+ { "Selection", BROWSER_SELECTION, 0 },
+ { "_Selection.SelSave", BROWSER_SELECTION_SAVE, &dialog_saveas },
+ { "Selection.Copy", BROWSER_SELECTION_COPY, 0 },
+ { "Selection.Cut", BROWSER_SELECTION_CUT, 0 },
+ { "_Selection.Paste", BROWSER_SELECTION_PASTE, 0 },
+ { "Selection.Clear", BROWSER_SELECTION_CLEAR, 0 },
+ { "Selection.SelectAll", BROWSER_SELECTION_ALL, 0 },
+ { "Navigate", NO_ACTION, 0 },
+ { "Navigate.Home", BROWSER_NAVIGATE_HOME, 0 },
+ { "Navigate.Back", BROWSER_NAVIGATE_BACK, 0 },
+ { "Navigate.Forward", BROWSER_NAVIGATE_FORWARD, 0 },
+ { "_Navigate.UpLevel", BROWSER_NAVIGATE_UP, 0 },
+ { "Navigate.Reload", BROWSER_NAVIGATE_RELOAD_ALL, 0 },
+ { "Navigate.Stop", BROWSER_NAVIGATE_STOP, 0 },
+ { "View", NO_ACTION, 0 },
+ { "View.ScaleView", BROWSER_SCALE_VIEW, &dialog_zoom },
+ { "View.Images", NO_ACTION, 0 },
+ { "View.Images.ForeImg", BROWSER_IMAGES_FOREGROUND, 0 },
+ { "View.Images.BackImg", BROWSER_IMAGES_BACKGROUND, 0 },
+ { "View.Toolbars", NO_ACTION, 0 },
+ { "View.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
+ { "View.Toolbars.ToolAddress", TOOLBAR_ADDRESS_BAR, 0 },
+ { "_View.Toolbars.ToolThrob", TOOLBAR_THROBBER, 0 },
+ { "View.Toolbars.EditToolbar", TOOLBAR_EDIT, 0 },
+ { "_View.Render", NO_ACTION, 0 },
+ { "View.Render.RenderAnims", BROWSER_BUFFER_ANIMS, 0 },
+ { "View.Render.RenderAll", BROWSER_BUFFER_ALL, 0 },
+ { "_View.OptDefault", BROWSER_SAVE_VIEW, 0 },
+ { "View.Window", NO_ACTION, 0 },
+ { "View.Window.WindowSave", BROWSER_WINDOW_DEFAULT, 0 },
+ { "View.Window.WindowStagr", BROWSER_WINDOW_STAGGER, 0 },
+ { "_View.Window.WindowSize", BROWSER_WINDOW_COPY, 0 },
+ { "View.Window.WindowReset", BROWSER_WINDOW_RESET, 0 },
+ { "Utilities", NO_ACTION, 0 },
+ { "Utilities.Hotlist", HOTLIST_SHOW, 0 },
+ { "Utilities.Hotlist.HotlistAdd", HOTLIST_ADD_URL, 0 },
+ { "Utilities.Hotlist.HotlistShow", HOTLIST_SHOW, 0 },
+ { "Utilities.History", HISTORY_SHOW_GLOBAL, 0 },
+ { "Utilities.History.HistLocal", HISTORY_SHOW_LOCAL, 0 },
+ { "Utilities.History.HistGlobal", HISTORY_SHOW_GLOBAL, 0 },
+ { "Utilities.Cookies", COOKIES_SHOW, 0 },
+ { "Utilities.Cookies.ShowCookies", COOKIES_SHOW, 0 },
+ { "Utilities.Cookies.DeleteCookies", COOKIES_DELETE, 0 },
+ { "Help", HELP_OPEN_CONTENTS, 0 },
+ { "Help.HelpContent", HELP_OPEN_CONTENTS, 0 },
+ { "Help.HelpGuide", HELP_OPEN_GUIDE, 0 },
+ { "_Help.HelpInfo", HELP_OPEN_INFORMATION, 0 },
+ { "_Help.HelpAbout", HELP_OPEN_ABOUT, 0 },
+ { "Help.HelpInter", HELP_LAUNCH_INTERACTIVE, 0 },
+ {NULL, 0, 0}
+ }
+ };
+ ro_gui_browser_window_menu =
+ ro_gui_menu_define_menu(&browser_definition);
+
+}
+
+
+/*
+ * Interface With Core
+ */
/**
* Create and open a new browser window.
@@ -203,8 +389,6 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
g->old_height = 0;
g->update_extent = true;
strcpy(g->title, "NetSurf");
- g->throbber = 0;
- g->throbtime = 0;
g->iconise_icon = -1;
/* Set the window position */
@@ -365,27 +549,47 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
/* Add in a toolbar and status bar */
if (bw->browser_window_type == BROWSER_WINDOW_NORMAL) {
g->status_bar = ro_gui_status_bar_create(g->window, option_toolbar_status_width);
- g->toolbar = ro_gui_theme_create_toolbar(NULL, THEME_BROWSER_TOOLBAR);
- ro_gui_theme_attach_toolbar(g->toolbar, g->window);
+ g->toolbar = ro_toolbar_create(NULL, g->window,
+ THEME_STYLE_BROWSER_TOOLBAR, TOOLBAR_FLAGS_NONE,
+ &ro_gui_window_toolbar_callbacks, g,
+ "HelpToolbar");
+ if (g->toolbar != NULL) {
+ ro_toolbar_add_buttons(g->toolbar,
+ brower_toolbar_buttons,
+ option_toolbar_browser);
+ ro_toolbar_add_url(g->toolbar);
+ ro_toolbar_add_throbber(g->toolbar);
+ ro_toolbar_rebuild(g->toolbar);
+ }
} else {
g->toolbar = NULL;
}
- /* Set the window options */
- bw->window = g;
- ro_gui_window_clone_options(bw, clone);
- ro_gui_prepare_navigate(g);
-
- /* Register event handlers */
+ /* Register event handlers. Do this quickly, as some of the things
+ * that follow will indirectly look up our user data: this MUST
+ * be set first!
+ */
ro_gui_wimp_event_set_user_data(g->window, g);
ro_gui_wimp_event_register_open_window(g->window, ro_gui_window_open);
ro_gui_wimp_event_register_close_window(g->window, ro_gui_window_close);
ro_gui_wimp_event_register_redraw_window(g->window, ro_gui_window_redraw);
ro_gui_wimp_event_register_keypress(g->window, ro_gui_window_keypress);
- if (g->toolbar)
- ro_gui_wimp_event_register_keypress(g->toolbar->toolbar_handle,
- ro_gui_window_keypress);
ro_gui_wimp_event_register_mouse_click(g->window, ro_gui_window_click);
+ ro_gui_wimp_event_register_menu(g->window, ro_gui_browser_window_menu,
+ true, false);
+ ro_gui_wimp_event_register_menu_prepare(g->window,
+ ro_gui_window_menu_prepare);
+ ro_gui_wimp_event_register_menu_selection(g->window,
+ ro_gui_window_menu_select);
+ ro_gui_wimp_event_register_menu_warning(g->window,
+ ro_gui_window_menu_warning);
+ ro_gui_wimp_event_register_menu_close(g->window,
+ ro_gui_window_menu_close);
+
+ /* Set the window options */
+ bw->window = g;
+ ro_gui_window_clone_options(bw, clone);
+ ro_gui_window_update_toolbar_buttons(g);
/* Open the window at the top of the stack */
state.w = g->window;
@@ -417,17 +621,9 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
/* Claim the caret for top-level windows */
if (bw->browser_window_type == BROWSER_WINDOW_NORMAL) {
- if (g->toolbar && g->toolbar->display_url) {
- error = xwimp_set_caret_position(
- g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL, -1, -1, -1, 0);
- ro_gui_url_complete_start(g);
- if (error) {
- LOG(("xwimp_set_caret_position: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
- } else
+ if (ro_toolbar_take_caret(g->toolbar))
+ ro_gui_url_complete_start(g->toolbar);
+ else
gui_window_place_caret(g, -100, -100, 0);
}
return g;
@@ -463,15 +659,15 @@ void gui_window_destroy(struct gui_window *g)
/* destroy toolbar */
if (g->toolbar)
- ro_gui_theme_destroy_toolbar(g->toolbar);
+ ro_toolbar_destroy(g->toolbar);
if (g->status_bar)
ro_gui_status_bar_destroy(g->status_bar);
w = g->window;
- ro_gui_url_complete_close(NULL, 0);
+ ro_gui_url_complete_close();
ro_gui_dialog_close_persistent(w);
if (current_menu_window == w)
- ro_gui_menu_closed(true);
+ ro_gui_menu_closed();
ro_gui_window_remove_update_boxes(g);
/* delete window */
@@ -659,7 +855,7 @@ bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
}
if (g->toolbar)
- toolbar_height = ro_gui_theme_toolbar_full_height(g->toolbar);
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
*sx = state.xscroll / (2 * g->bw->scale);
*sy = -(state.yscroll - toolbar_height) / (2 * g->bw->scale);
return true;
@@ -693,7 +889,7 @@ void gui_window_set_scroll(struct gui_window *g, int sx, int sy)
state.xscroll = sx * 2 * g->bw->scale;
state.yscroll = -sy * 2 * g->bw->scale;
if (g->toolbar)
- state.yscroll += ro_gui_theme_toolbar_full_height(g->toolbar);
+ state.yscroll += ro_toolbar_full_height(g->toolbar);
ro_gui_window_open(PTR_WIMP_OPEN(&state));
}
@@ -728,7 +924,7 @@ void gui_window_scroll_visible(struct gui_window *g, int x0, int y0, int x1, int
}
if (g->toolbar)
- toolbar_height = ro_gui_theme_toolbar_full_height(g->toolbar);
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
x0 = x0 * 2 * g->bw->scale;
y0 = y0 * 2 * g->bw->scale;
@@ -898,25 +1094,27 @@ void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, bo
/**
- * Update the extent of the inside of a browser window to that of the current content.
+ * Update the extent of the inside of a browser window to that of the
+ * current content.
*
- * \param g gui_window to update the extent of
+ * \param g gui_window to update the extent of
*/
void gui_window_update_extent(struct gui_window *g)
{
- os_error *error;
- wimp_window_state state;
- bool update;
- unsigned int flags;
- int scroll = 0;
+ os_error *error;
+ wimp_window_info info;
+ wimp_window_state state;
+ bool update;
+ unsigned int flags;
+ int scroll = 0;
assert(g);
- state.w = g->window;
- error = xwimp_get_window_state(&state);
+ info.w = g->window;
+ error = xwimp_get_window_info_header_only(&info);
if (error) {
- LOG(("xwimp_get_window_state: 0x%x: %s",
+ LOG(("xwimp_get_window_info_header_only: 0x%x: %s",
error->errnum, error->errmess));
warn_user("WimpError", error->errmess);
return;
@@ -924,15 +1122,15 @@ void gui_window_update_extent(struct gui_window *g)
/* scroll on toolbar height change */
if (g->toolbar) {
- scroll = ro_gui_theme_height_change(g->toolbar);
- state.yscroll -= scroll;
+ scroll = ro_toolbar_height(g->toolbar) - info.extent.y1;
+ info.yscroll += scroll;
}
/* only allow a further reformat if we've gained/lost scrollbars */
- flags = state.flags & (wimp_WINDOW_HSCROLL | wimp_WINDOW_VSCROLL);
+ flags = info.flags & (wimp_WINDOW_HSCROLL | wimp_WINDOW_VSCROLL);
update = g->bw->reformat_pending;
g->update_extent = true;
- ro_gui_window_open(PTR_WIMP_OPEN(&state));
+ ro_gui_window_open(PTR_WIMP_OPEN(&info));
state.w = g->window;
error = xwimp_get_window_state(&state);
@@ -1033,41 +1231,11 @@ void gui_window_hide_pointer(struct gui_window *g)
void gui_window_set_url(struct gui_window *g, const char *url)
{
- wimp_caret caret;
- os_error *error;
- const char *toolbar_url;
-
if (!g->toolbar)
return;
- ro_gui_set_icon_string(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL, url, true);
- ro_gui_force_redraw_icon(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_FAVICON);
-
- /* if the caret is in the address bar, move it to the end */
- error = xwimp_get_caret_position(&caret);
- if (error) {
- LOG(("xwimp_get_caret_position: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- return;
- }
-
- if (!(caret.w == g->toolbar->toolbar_handle &&
- caret.i == ICON_TOOLBAR_URL))
- return;
-
- toolbar_url = ro_gui_get_icon_string(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL);
- error = xwimp_set_caret_position(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL, 0, 0, -1, (int)strlen(toolbar_url));
- if (error) {
- LOG(("xwimp_set_caret_position: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
- ro_gui_url_complete_start(g);
+ ro_toolbar_set_url(g->toolbar, url, true, false);
+ ro_gui_url_complete_start(g->toolbar);
}
@@ -1079,10 +1247,10 @@ void gui_window_set_url(struct gui_window *g, const char *url)
void gui_window_start_throbber(struct gui_window *g)
{
- ro_gui_menu_objects_moved();
- ro_gui_prepare_navigate(g);
- xos_read_monotonic_time(&g->throbtime);
- g->throbber = 0;
+ ro_gui_window_update_toolbar_buttons(g);
+ ro_gui_menu_refresh(ro_gui_browser_window_menu);
+ if (g->toolbar != NULL)
+ ro_toolbar_start_throbbing(g->toolbar);
}
@@ -1095,24 +1263,22 @@ void gui_window_start_throbber(struct gui_window *g)
void gui_window_stop_throbber(struct gui_window *g)
{
- char throb_buf[12];
- ro_gui_prepare_navigate(g);
- g->throbber = 0;
- if (g->toolbar) {
- strcpy(throb_buf, "throbber0");
- ro_gui_set_icon_string(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_THROBBER, throb_buf, true);
- if ((g->toolbar->descriptor) && (g->toolbar->descriptor->throbber_redraw))
- ro_gui_force_redraw_icon(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_THROBBER);
- }
+ ro_gui_window_update_toolbar_buttons(g);
+ ro_gui_menu_refresh(ro_gui_browser_window_menu);
+ if (g->toolbar != NULL)
+ ro_toolbar_stop_throbbing(g->toolbar);
}
/**
* set favicon
*/
+
void gui_window_set_icon(struct gui_window *g, hlcache_handle *icon)
{
+ if (g == NULL || g->toolbar == NULL)
+ return;
+
+ ro_toolbar_set_site_favicon(g->toolbar, icon);
}
/**
@@ -1185,9 +1351,10 @@ void gui_window_remove_caret(struct gui_window *g)
void gui_window_new_content(struct gui_window *g)
{
- ro_gui_menu_objects_moved();
- ro_gui_prepare_navigate(g);
+ ro_gui_menu_refresh(ro_gui_browser_window_menu);
+ ro_gui_window_update_toolbar_buttons(g);
ro_gui_dialog_close_persistent(g->window);
+ ro_toolbar_set_content_favicon(g->toolbar, g->bw->current_content);
}
@@ -1233,7 +1400,7 @@ bool gui_window_scroll_start(struct gui_window *g)
drag.bbox.y1 = drag.bbox.y0 + (height - (info.visible.y1 - info.visible.y0));
if (g->toolbar) {
- int tbar_height = ro_gui_theme_toolbar_full_height(g->toolbar);
+ int tbar_height = ro_toolbar_full_height(g->toolbar);
drag.bbox.y0 -= tbar_height;
drag.bbox.y1 -= tbar_height;
}
@@ -1339,7 +1506,7 @@ bool gui_window_frame_resize_start(struct gui_window *g)
/* convert to screen co-ordinates */
top = browser_window_owner(bw);
if (top->window->toolbar)
- toolbar_height = ro_gui_theme_toolbar_full_height(top->window->toolbar);
+ toolbar_height = ro_toolbar_full_height(top->window->toolbar);
state.w = top->window->window;
error = xwimp_get_window_state(&state);
if (error) {
@@ -1422,16 +1589,111 @@ void gui_window_set_scale(struct gui_window *g, float scale)
/**
- * Redraws the content for all windows.
+ * Updates a windows extent.
+ *
+ * \param g the gui_window to update
+ * \param width the minimum width, or -1 to use window width
+ * \param height the minimum height, or -1 to use window height
*/
-void ro_gui_window_redraw_all(void)
+void gui_window_set_extent(struct gui_window *g, int width, int height)
{
- struct gui_window *g;
- for (g = window_list; g; g = g->next)
- gui_window_redraw_window(g);
+ int screen_width;
+ int toolbar_height = 0;
+ hlcache_handle *h;
+ wimp_window_state state;
+ os_error *error;
+
+ h = g->bw->current_content;
+ if (g->toolbar)
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
+
+ /* get the current state */
+ if ((height == -1) || (width == -1)) {
+ state.w = g->window;
+ 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;
+ }
+ if (width == -1)
+ width = state.visible.x1 - state.visible.x0;
+ if (height == -1) {
+ height = state.visible.y1 - state.visible.y0;
+ height -= toolbar_height;
+ }
+ }
+
+ /* the top-level framed window is a total pain. to get it to maximise
+ * to the top of the screen we need to fake it having a suitably large
+ * extent */
+ if (g->bw->children &&
+ (g->bw->browser_window_type == BROWSER_WINDOW_NORMAL)) {
+ ro_gui_screen_size(&screen_width, &height);
+ if (g->toolbar)
+ height -= ro_toolbar_full_height(g->toolbar);
+ height -= ro_get_hscroll_height(g->window);
+ height -= ro_get_title_height(g->window);
+ }
+ if (h) {
+ width = max(width, content_get_width(h) * 2 * g->bw->scale);
+ height = max(height, content_get_height(h) * 2 * g->bw->scale);
+ }
+ os_box extent = { 0, -height, width, toolbar_height };
+ error = xwimp_set_extent(g->window, &extent);
+ if (error) {
+ LOG(("xwimp_set_extent: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return;
+ }
+}
+
+
+/**
+ * Display a menu of options for a form select control.
+ *
+ * \param bw browser window containing form control
+ * \param control form control of type GADGET_SELECT
+ */
+
+void gui_create_form_select_menu(struct browser_window *bw,
+ struct form_control *control)
+{
+ os_error *error;
+ wimp_pointer pointer;
+
+ /* The first time the menu is opened, control bypasses the normal
+ * Menu Prepare event and so we prepare here. On any re-opens,
+ * ro_gui_window_prepare_form_select_menu() is called from the
+ * normal wimp event.
+ */
+
+ if (!ro_gui_window_prepare_form_select_menu(bw, control))
+ 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);
+ ro_gui_menu_closed();
+ return;
+ }
+
+ gui_form_select_control = control;
+ ro_gui_menu_create(gui_form_select_menu,
+ pointer.pos.x, pointer.pos.y, bw->window->window);
}
+
+/*
+ * RISC OS Wimp Event Handlers
+ */
+
+
/**
* Handle a Redraw_Window_Request for a browser window.
*/
@@ -1512,218 +1774,6 @@ void ro_gui_window_redraw(wimp_draw *redraw)
}
-
-/**
- * Remove all pending update boxes for a window
- *
- * \param g gui_window
- */
-void ro_gui_window_remove_update_boxes(struct gui_window *g) {
- struct update_box *cur;
-
- for (cur = pending_updates; cur != NULL; cur = cur->next) {
- if (cur->g == g)
- cur->g = NULL;
- }
-}
-
-
-/**
- * Redraw any pending update boxes.
- */
-void ro_gui_window_update_boxes(void) {
- osbool more;
- bool use_buffer;
- wimp_draw update;
- struct rect clip;
- os_error *error;
- struct update_box *cur;
- struct gui_window *g;
- const union content_msg_data *data;
-
- for (cur = pending_updates; cur != NULL; cur = cur->next) {
- g = cur->g;
- if (!g)
- continue;
-
- data = &cur->data;
- use_buffer = cur->use_buffer;
-
- update.w = g->window;
- update.box.x0 = cur->x0;
- update.box.y0 = cur->y0;
- update.box.x1 = cur->x1;
- update.box.y1 = cur->y1;
-
- error = xwimp_update_window(&update, &more);
- if (error) {
- LOG(("xwimp_update_window: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- continue;
- }
-
- /* Set the current redraw gui_window to get options from */
- ro_gui_current_redraw_gui = g;
- current_redraw_browser = g->bw;
-
- plot = ro_plotters;
- ro_plot_origin_x = update.box.x0 - update.xscroll;
- ro_plot_origin_y = update.box.y1 - update.yscroll;
- ro_plot_set_scale(g->bw->scale);
-
- while (more) {
- clip.x0 = (update.clip.x0 - ro_plot_origin_x) / 2;
- clip.y0 = (ro_plot_origin_y - update.clip.y1) / 2;
- clip.x1 = (update.clip.x1 - ro_plot_origin_x) / 2;
- clip.y1 = (ro_plot_origin_y - update.clip.y0) / 2;
-
- if (use_buffer)
- ro_gui_buffer_open(&update);
-
- browser_window_redraw(g->bw, 0, 0, &clip);
-
- if (use_buffer)
- ro_gui_buffer_close();
-
- error = xwimp_get_rectangle(&update, &more);
- /* RISC OS 3.7 returns an error here if enough buffer
- * was claimed to cause a new dynamic area to be
- * created. It doesn't actually stop anything working,
- * so we mask it out for now until a better fix is
- * found. This appears to be a bug in RISC OS. */
- if (error && !(use_buffer &&
- error->errnum == error_WIMP_GET_RECT)) {
- LOG(("xwimp_get_rectangle: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- ro_gui_current_redraw_gui = NULL;
- current_redraw_browser = NULL;
- continue;
- }
- }
-
- /* Reset the current redraw gui_window to prevent
- * thumbnails from retaining options */
- ro_gui_current_redraw_gui = NULL;
- current_redraw_browser = NULL;
- }
- while (pending_updates) {
- cur = pending_updates;
- pending_updates = pending_updates->next;
- free(cur);
- }
-
-}
-
-
-/**
- * Launch a new url in the given window.
- *
- * \param g gui_window to update
- * \param url url to be launched
- */
-
-void ro_gui_window_launch_url(struct gui_window *g, const char *url)
-{
- url_func_result res;
- char *url_norm;
-
- ro_gui_url_complete_close(NULL, 0);
- res = url_normalize(url, &url_norm);
- if (res == URL_FUNC_OK) {
- gui_window_set_url(g, url_norm);
- browser_window_go(g->bw, url_norm, 0, true);
- free(url_norm);
- }
-}
-
-
-/**
- * Forces all windows to be set to the current theme
- */
-void ro_gui_window_update_theme(void) {
- struct gui_window *g;
- for (g = window_list; g; g = g->next) {
- if (g->toolbar) {
- if (g->toolbar->editor)
- if (!ro_gui_theme_update_toolbar(NULL, g->toolbar->editor))
- g->toolbar->editor = NULL;
- if (!ro_gui_theme_update_toolbar(NULL, g->toolbar)) {
- ro_gui_theme_destroy_toolbar(g->toolbar);
- g->toolbar = NULL;
- }
- ro_gui_theme_toolbar_editor_sync(g->toolbar);
- gui_window_update_extent(g);
- }
- }
-}
-
-
-/**
- * Updates a windows extent.
- *
- * \param g the gui_window to update
- * \param width the minimum width, or -1 to use window width
- * \param height the minimum height, or -1 to use window height
- */
-
-void gui_window_set_extent(struct gui_window *g, int width, int height)
-{
- int screen_width;
- int toolbar_height = 0;
- hlcache_handle *h;
- wimp_window_state state;
- os_error *error;
-
- h = g->bw->current_content;
- if (g->toolbar)
- toolbar_height = ro_gui_theme_toolbar_full_height(g->toolbar);
-
- /* get the current state */
- if ((height == -1) || (width == -1)) {
- state.w = g->window;
- 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;
- }
- if (width == -1)
- width = state.visible.x1 - state.visible.x0;
- if (height == -1) {
- height = state.visible.y1 - state.visible.y0;
- height -= toolbar_height;
- }
- }
-
- /* the top-level framed window is a total pain. to get it to maximise
- * to the top of the screen we need to fake it having a suitably large
- * extent */
- if (g->bw->children &&
- (g->bw->browser_window_type == BROWSER_WINDOW_NORMAL)) {
- ro_gui_screen_size(&screen_width, &height);
- if (g->toolbar)
- height -= ro_gui_theme_toolbar_full_height(g->toolbar);
- height -= ro_get_hscroll_height(g->window);
- height -= ro_get_title_height(g->window);
- }
- if (h) {
- width = max(width, content_get_width(h) * 2 * g->bw->scale);
- height = max(height, content_get_height(h) * 2 * g->bw->scale);
- }
- os_box extent = { 0, -height, width, toolbar_height };
- error = xwimp_set_extent(g->window, &extent);
- if (error) {
- LOG(("xwimp_set_extent: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- return;
- }
-}
-
-
/**
* Open a window using the given wimp_open, handling toolbars and resizing.
*/
@@ -1762,7 +1812,7 @@ void ro_gui_window_open(wimp_open *open)
/* account for toolbar height, if present */
if (g->toolbar)
- toolbar_height = ro_gui_theme_toolbar_full_height(g->toolbar);
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
height -= toolbar_height;
/* work with the state from now on so we can modify flags */
@@ -1871,7 +1921,7 @@ void ro_gui_window_open(wimp_open *open)
}
/* first resize stops any flickering by making the URL window on top */
- ro_gui_url_complete_resize(g, PTR_WIMP_OPEN(&state));
+ ro_gui_url_complete_resize(g->toolbar, PTR_WIMP_OPEN(&state));
error = xwimp_open_window_nested_with_flags(&state, parent, linkage);
if (error) {
@@ -1885,9 +1935,9 @@ void ro_gui_window_open(wimp_open *open)
if (g->status_bar)
ro_gui_status_bar_resize(g->status_bar);
if (g->toolbar) {
- ro_gui_theme_process_toolbar(g->toolbar, -1);
+ ro_toolbar_process(g->toolbar, -1, false);
/* second resize updates to the new URL bar width */
- ro_gui_url_complete_resize(g, open);
+ ro_gui_url_complete_resize(g->toolbar, open);
}
/* set the new scale from a ctrl-resize. this must be done at the end as
@@ -1901,7 +1951,9 @@ void ro_gui_window_open(wimp_open *open)
/**
* Handle wimp closing event
*/
-void ro_gui_window_close(wimp_w w) {
+
+void ro_gui_window_close(wimp_w w)
+{
struct gui_window *g = (struct gui_window *)ro_gui_wimp_event_get_user_data(w);
wimp_pointer pointer;
os_error *error;
@@ -1950,9 +2002,11 @@ void ro_gui_window_close(wimp_w w) {
} else {
/* this is pointless if we are about to close the
* window */
- if (!destroy)
- ro_gui_menu_handle_action(w,
- BROWSER_NAVIGATE_UP, true);
+ if (!destroy && g->bw != NULL &&
+ g->bw->current_content != NULL)
+ ro_gui_window_navigate_up(g->bw->window,
+ content_get_url(
+ g->bw->current_content));
}
}
else
@@ -1964,606 +2018,347 @@ void ro_gui_window_close(wimp_w w) {
/**
- * Destroy all browser windows.
- */
-
-void ro_gui_window_quit(void)
-{
- struct gui_window *cur;
-
- while (window_list) {
- cur = window_list;
- window_list = window_list->next;
-
- /* framesets and iframes are destroyed by their parents */
- if (!cur->bw->parent)
- browser_window_destroy(cur->bw);
- }
-}
-
-
-/**
- * Animate the "throbbers" of all browser windows.
- */
-
-void ro_gui_throb(void)
-{
- os_t t;
- struct gui_window *g, *top_g;
- struct browser_window *top;
- char throb_buf[12];
-
- xos_read_monotonic_time(&t);
-
- for (g = window_list; g; g = g->next) {
- if (!g->bw->throbbing)
- continue;
- for (top = g->bw; top->parent; top = top->parent);
- top_g = top->window;
- if (!top_g->toolbar || !top_g->toolbar->display_throbber ||
- !top_g->toolbar->descriptor ||
- !top_g->toolbar->descriptor->theme ||
- (t < top_g->throbtime + 10))
- continue;
- top_g->throbtime = t;
- top_g->throbber++;
- if (top_g->toolbar->descriptor->theme->throbber_frames < top_g->throbber)
- top_g->throbber = 1;
- sprintf(throb_buf, "throbber%i", top_g->throbber);
- ro_gui_set_icon_string(top_g->toolbar->toolbar_handle,
- ICON_TOOLBAR_THROBBER, throb_buf, true);
- if (top_g->toolbar->descriptor->throbber_redraw)
- ro_gui_force_redraw_icon(top_g->toolbar->toolbar_handle,
- ICON_TOOLBAR_THROBBER);
- }
-}
-
-
-/**
- * Convert a RISC OS window handle to a gui_window.
+ * Handle Mouse_Click events in a browser window. This should never see
+ * Menu clicks, as these will be routed to the menu handlers.
*
- * \param w RISC OS window handle
- * \return pointer to a structure if found, 0 otherwise
+ * \param *pointer details of mouse click
+ * \return true if click handled, false otherwise
*/
-struct gui_window *ro_gui_window_lookup(wimp_w window)
+bool ro_gui_window_click(wimp_pointer *pointer)
{
struct gui_window *g;
- for (g = window_list; g; g = g->next)
- if (g->window == window)
- return g;
- return 0;
-}
+ os_coord pos;
+ /* We should never see Menu clicks. */
-/**
- * Convert a toolbar RISC OS window handle to a gui_window.
- *
- * \param w RISC OS window handle of a toolbar
- * \return pointer to a structure if found, 0 otherwise
- */
-
-struct gui_window *ro_gui_toolbar_lookup(wimp_w window)
-{
- struct gui_window *g;
- for (g = window_list; g; g = g->next) {
- if ((g->toolbar) && ((g->toolbar->toolbar_handle == window) ||
- ((g->toolbar->editor) &&
- (g->toolbar->editor->toolbar_handle == window))))
- return g;
- }
- return 0;
-}
+ if (pointer->buttons == wimp_CLICK_MENU)
+ return false;
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(pointer->w);
-/**
- * Handle pointer movements in a browser window.
- *
- * \param g browser window that the pointer is in
- * \param pointer new mouse position
- */
+ /* try to close url-completion */
+ ro_gui_url_complete_close();
-void ro_gui_window_mouse_at(struct gui_window *g, wimp_pointer *pointer)
-{
- os_coord pos;
+ /* set input focus */
+ if (pointer->buttons == wimp_CLICK_SELECT ||
+ pointer->buttons == wimp_CLICK_ADJUST)
+ gui_window_place_caret(g, -100, -100, 0);
if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos))
- browser_window_mouse_track(g->bw,
- ro_gui_mouse_drag_state(pointer->buttons,
- wimp_BUTTON_CLICK_DRAG),
+ browser_window_mouse_click(g->bw,
+ ro_gui_mouse_click_state(pointer->buttons,
+ wimp_BUTTON_CLICK_DRAG),
pos.x, pos.y);
+
+ return true;
}
/**
- * Process Mouse_Click events in a toolbar.
+ * Process Key_Pressed events in a browser window.
*/
-bool ro_gui_toolbar_click(wimp_pointer *pointer)
+bool ro_gui_window_keypress(wimp_key *key)
{
- struct gui_window *g = ro_gui_toolbar_lookup(pointer->w);
- struct browser_window *new_bw;
-
- /* toolbars in the options window have no gui_window */
- if (!g)
- return true;
-
- /* try to close url-completion */
- ro_gui_url_complete_close(g, pointer->i);
+ struct gui_window *g;
+ hlcache_handle *h;
+ os_error *error;
+ wimp_pointer pointer;
+ uint32_t c = (uint32_t) key->c;
+
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(key->w);
+ if (g == NULL)
+ return false;
- /* Handle Menu clicks */
- if (pointer->buttons == wimp_CLICK_MENU) {
- ro_gui_menu_create(browser_toolbar_menu, pointer->pos.x,
- pointer->pos.y, g->window, true);
- return true;
- }
+ h = g->bw->current_content;
- /* Handle toolbar edits */
- if ((g->toolbar->editor) && (pointer->i < ICON_TOOLBAR_URL)) {
- ro_gui_theme_toolbar_editor_click(g->toolbar, pointer);
- return true;
+ error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG(("xwimp_get_pointer_info: 0x%x: %s\n",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return false;
}
- /* Handle the buttons appropriately */
- switch (pointer->i) {
- case ICON_TOOLBAR_BACK:
- if (pointer->buttons == wimp_CLICK_ADJUST) {
- new_bw = browser_window_create(NULL,
- g->bw, NULL, false, false);
- ro_gui_menu_handle_action(
- new_bw->window->window,
- BROWSER_NAVIGATE_BACK, true);
- } else {
- ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_BACK, true);
- }
- break;
-
- case ICON_TOOLBAR_FORWARD:
- if (pointer->buttons == wimp_CLICK_ADJUST) {
- new_bw = browser_window_create(NULL,
- g->bw, NULL, false, false);
- ro_gui_menu_handle_action(
- new_bw->window->window,
- BROWSER_NAVIGATE_FORWARD, true);
- } else {
- ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_FORWARD, true);
- }
- break;
+ /* First send the key to the browser window, eg. form fields. */
- case ICON_TOOLBAR_STOP:
- ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_STOP, true);
- break;
+ if ((unsigned)c < 0x20 || (0x7f <= c && c <= 0x9f) ||
+ (c & IS_WIMP_KEY)) {
+ /* Munge control keys into unused control chars */
+ /* We can't map onto 1->26 (reserved for ctrl+<qwerty>
+ That leaves 27->31 and 128->159 */
+ switch (c & ~IS_WIMP_KEY) {
+ case wimp_KEY_TAB: c = 9; break;
+ case wimp_KEY_SHIFT | wimp_KEY_TAB: c = 11; break;
- case ICON_TOOLBAR_RELOAD:
- if (pointer->buttons == wimp_CLICK_SELECT)
- ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_RELOAD, true);
- else if (pointer->buttons == wimp_CLICK_ADJUST)
- ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_RELOAD_ALL,
- true);
+ /* cursor movement keys */
+ case wimp_KEY_HOME:
+ case wimp_KEY_CONTROL | wimp_KEY_LEFT:
+ c = KEY_LINE_START;
break;
-
- case ICON_TOOLBAR_HISTORY:
- if (pointer->buttons == wimp_CLICK_SELECT)
- ro_gui_menu_handle_action(g->window,
- HISTORY_SHOW_LOCAL, true);
+ case wimp_KEY_END:
+ if (os_version >= RISCOS5)
+ c = KEY_LINE_END;
else
- ro_gui_menu_handle_action(g->window,
- HISTORY_SHOW_GLOBAL, true);
+ c = KEY_DELETE_RIGHT;
break;
- case ICON_TOOLBAR_HOME:
- ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_HOME, true);
+ case wimp_KEY_CONTROL | wimp_KEY_RIGHT: c = KEY_LINE_END; break;
+ case wimp_KEY_CONTROL | wimp_KEY_UP: c = KEY_TEXT_START; break;
+ case wimp_KEY_CONTROL | wimp_KEY_DOWN: c = KEY_TEXT_END; break;
+ case wimp_KEY_SHIFT | wimp_KEY_LEFT: c = KEY_WORD_LEFT ; break;
+ case wimp_KEY_SHIFT | wimp_KEY_RIGHT: c = KEY_WORD_RIGHT; break;
+ case wimp_KEY_SHIFT | wimp_KEY_UP: c = KEY_PAGE_UP; break;
+ case wimp_KEY_SHIFT | wimp_KEY_DOWN: c = KEY_PAGE_DOWN; break;
+ case wimp_KEY_LEFT: c = KEY_LEFT; break;
+ case wimp_KEY_RIGHT: c = KEY_RIGHT; break;
+ case wimp_KEY_UP: c = KEY_UP; break;
+ case wimp_KEY_DOWN: c = KEY_DOWN; break;
+
+ /* editing */
+ case wimp_KEY_CONTROL | wimp_KEY_END:
+ c = KEY_DELETE_LINE_END;
break;
- case ICON_TOOLBAR_SEARCH:
- ro_gui_menu_handle_action(g->window,
- BROWSER_FIND_TEXT, true);
- break;
- case ICON_TOOLBAR_SCALE:
- ro_gui_menu_handle_action(g->window,
- BROWSER_SCALE_VIEW, true);
+ case wimp_KEY_DELETE:
+ if (ro_gui_ctrl_pressed())
+ c = KEY_DELETE_LINE_START;
+ else if (os_version < RISCOS5)
+ c = KEY_DELETE_LEFT;
break;
- case ICON_TOOLBAR_BOOKMARK:
- if (pointer->buttons == wimp_CLICK_ADJUST)
- ro_gui_menu_handle_action(g->window,
- HOTLIST_ADD_URL, true);
- else
- ro_gui_menu_handle_action(g->window,
- HOTLIST_SHOW, true);
+ default:
break;
+ }
+ }
- case ICON_TOOLBAR_SAVE:
- if (pointer->buttons == wimp_CLICK_ADJUST)
- ro_gui_menu_handle_action(g->window,
- BROWSER_SAVE_COMPLETE, true);
- else
- ro_gui_menu_handle_action(g->window,
- BROWSER_SAVE, true);
- break;
- case ICON_TOOLBAR_PRINT:
- ro_gui_menu_handle_action(g->window,
- BROWSER_PRINT, true);
- break;
- case ICON_TOOLBAR_UP:
- if (pointer->buttons == wimp_CLICK_ADJUST) {
- if (g->bw && g->bw->current_content) {
- hlcache_handle *h =
- g->bw->current_content;
- new_bw = browser_window_create(NULL,
- g->bw, NULL, false,
- false);
- /* do it without loading the content
- * into the new window */
- ro_gui_window_navigate_up(
- new_bw->window,
- content_get_url(h));
- }
- } else {
- ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_UP, true);
- }
- break;
- case ICON_TOOLBAR_URL:
- if (pointer->buttons &
- (wimp_DRAG_SELECT | wimp_DRAG_ADJUST)) {
- if (g->bw->current_content) {
- hlcache_handle *h =
- g->bw->current_content;
- gui_save_type save_type;
-
- if (ro_gui_shift_pressed())
- save_type = GUI_SAVE_LINK_URL;
- else
- save_type = GUI_SAVE_LINK_TEXT;
-
- ro_gui_drag_save_link(save_type,
- content_get_url(h),
- content_get_title(h),
- g);
- }
- }
- else
- ro_gui_url_complete_start(g);
- break;
- case ICON_TOOLBAR_SUGGEST:
- ro_gui_popup_menu(url_suggest_menu,
- g->toolbar->toolbar_handle,
- ICON_TOOLBAR_SUGGEST);
- break;
+ if (!(c & IS_WIMP_KEY)) {
+ if (browser_window_key_press(g->bw, c))
+ return true;
}
+
+ ro_gui_window_handle_local_keypress(g, key, false);
+
return true;
}
/**
- * Handle Mouse_Click events in a browser window.
+ * Callback handler for keypresses within browser window toolbars.
*
- * \param pointer details of mouse click
- * \return true if click handled, false otherwise
+ * \param *data Client data, pointing to the GUI Window.
+ * \param *key The keypress data.
*/
-bool ro_gui_window_click(wimp_pointer *pointer)
+void ro_gui_window_toolbar_keypress(void *data, wimp_key *key)
{
- struct gui_window *g;
- os_coord pos;
-
- g = (struct gui_window *)ro_gui_wimp_event_get_user_data(pointer->w);
-
- /* try to close url-completion */
- ro_gui_url_complete_close(g, pointer->i);
+ struct gui_window *g = (struct gui_window *) data;
- /* set input focus */
- if (pointer->buttons == wimp_CLICK_SELECT ||
- pointer->buttons == wimp_CLICK_ADJUST)
- gui_window_place_caret(g, -100, -100, 0);
-
- if (pointer->buttons == wimp_CLICK_MENU) {
- ro_gui_menu_create(browser_menu, pointer->pos.x, pointer->pos.y, pointer->w, true);
- } else {
- if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos))
- browser_window_mouse_click(g->bw,
- ro_gui_mouse_click_state(pointer->buttons,
- wimp_BUTTON_CLICK_DRAG),
- pos.x, pos.y);
- }
- return true;
+ if (g != NULL)
+ ro_gui_window_handle_local_keypress(g, key, true);
}
/**
- * Process Key_Pressed events in a browser window.
+ * Handle keypresses within the RISC OS GUI: this is to be called after the
+ * core has been given a chance to act, or on keypresses in the toolbar where
+ * the core doesn't get involved.
+ *
+ * \param *g The gui window to which the keypress applies.
+ * \param *key The keypress data.
+ * \param is_toolbar true if the keypress is from a toolbar;
+ * else false.
*/
-bool ro_gui_window_keypress(wimp_key *key)
+void ro_gui_window_handle_local_keypress(struct gui_window *g, wimp_key *key,
+ bool is_toolbar)
{
- struct gui_window *g;
- bool toolbar;
- hlcache_handle *h;
- wimp_window_state state;
- int y;
- const char *toolbar_url;
- os_error *error;
- wimp_pointer pointer;
- float scale;
- uint32_t c = (uint32_t) key->c;
-
- /* Find gui window */
- if ((g = ro_gui_window_lookup(key->w)) != NULL) {
- toolbar = false;
- } else if ((g = ro_gui_toolbar_lookup(key->w)) != NULL) {
- toolbar = true;
- } else {
- /* nothing to do with us */
- return false;
- }
+ hlcache_handle *h;
+ wimp_window_state state;
+ int y;
+ const char *toolbar_url;
+ os_error *error;
+ float scale;
+ uint32_t c = (uint32_t) key->c;
+
+ if (g == NULL)
+ return;
h = g->bw->current_content;
- error = xwimp_get_pointer_info(&pointer);
- if (error) {
- LOG(("xwimp_get_pointer_info: 0x%x: %s\n",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- return false;
- }
+ switch (c) {
+ case IS_WIMP_KEY + wimp_KEY_F1: /* Help. */
+ ro_gui_open_help_page("documentation/index");
+ return;
- /* First send the key to the browser window, eg. form fields. */
- if (!toolbar) {
- if ((unsigned)c < 0x20 || (0x7f <= c && c <= 0x9f) ||
- (c & IS_WIMP_KEY)) {
- /* Munge control keys into unused control chars */
- /* We can't map onto 1->26 (reserved for ctrl+<qwerty>
- That leaves 27->31 and 128->159 */
- switch (c & ~IS_WIMP_KEY) {
- case wimp_KEY_TAB: c = 9; break;
- case wimp_KEY_SHIFT | wimp_KEY_TAB: c = 11; break;
-
- /* cursor movement keys */
- case wimp_KEY_HOME:
- case wimp_KEY_CONTROL | wimp_KEY_LEFT:
- c = KEY_LINE_START;
- break;
- case wimp_KEY_END:
- if (os_version >= RISCOS5)
- c = KEY_LINE_END;
- else
- c = KEY_DELETE_RIGHT;
- break;
- case wimp_KEY_CONTROL | wimp_KEY_RIGHT: c = KEY_LINE_END; break;
- case wimp_KEY_CONTROL | wimp_KEY_UP: c = KEY_TEXT_START; break;
- case wimp_KEY_CONTROL | wimp_KEY_DOWN: c = KEY_TEXT_END; break;
- case wimp_KEY_SHIFT | wimp_KEY_LEFT: c = KEY_WORD_LEFT ; break;
- case wimp_KEY_SHIFT | wimp_KEY_RIGHT: c = KEY_WORD_RIGHT; break;
- case wimp_KEY_SHIFT | wimp_KEY_UP: c = KEY_PAGE_UP; break;
- case wimp_KEY_SHIFT | wimp_KEY_DOWN: c = KEY_PAGE_DOWN; break;
- case wimp_KEY_LEFT: c = KEY_LEFT; break;
- case wimp_KEY_RIGHT: c = KEY_RIGHT; break;
- case wimp_KEY_UP: c = KEY_UP; break;
- case wimp_KEY_DOWN: c = KEY_DOWN; break;
-
- /* editing */
- case wimp_KEY_CONTROL | wimp_KEY_END:
- c = KEY_DELETE_LINE_END;
- break;
- case wimp_KEY_DELETE:
- if (ro_gui_ctrl_pressed())
- c = KEY_DELETE_LINE_START;
- else if (os_version < RISCOS5)
- c = KEY_DELETE_LEFT;
- break;
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F1:
+ ro_gui_window_action_page_info(g);
+ return;
- default:
- break;
- }
- }
+ case IS_WIMP_KEY + wimp_KEY_F2:
+ if (g->toolbar == NULL)
+ return;
+ ro_gui_url_complete_close();
+ ro_toolbar_set_url(g->toolbar, "www.", true, true);
+ ro_gui_url_complete_start(g->toolbar);
+ ro_gui_url_complete_keypress(g->toolbar, wimp_KEY_DOWN);
+ return;
- if (!(c & IS_WIMP_KEY)) {
- if (browser_window_key_press(g->bw, c))
- return true;
- }
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F2:
+ /* Close window. */
+ ro_gui_url_complete_close();
+ browser_window_destroy(g->bw);
+ return;
- /* Reset c to incoming character / key code
- * as we may have corrupted it above */
- c = (uint32_t) key->c;
- }
+ case 19: /* Ctrl + S */
+ case IS_WIMP_KEY + wimp_KEY_F3:
+ ro_gui_window_action_save(g, GUI_SAVE_SOURCE);
+ return;
- switch (c) {
- case IS_WIMP_KEY + wimp_KEY_F1: /* Help. */
- return ro_gui_menu_handle_action(g->window,
- HELP_OPEN_CONTENTS, false);
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F3:
+ ro_gui_window_action_save(g, GUI_SAVE_TEXT);
+ return;
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F1:
- return ro_gui_menu_handle_action(g->window,
- BROWSER_PAGE_INFO, false);
+ case IS_WIMP_KEY + wimp_KEY_SHIFT + wimp_KEY_F3:
+ ro_gui_window_action_save(g, GUI_SAVE_COMPLETE);
+ return;
- case IS_WIMP_KEY + wimp_KEY_F2:
- if (!g->toolbar)
- return false;
- ro_gui_url_complete_close(NULL, 0);
- ro_gui_set_icon_string(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL, "www.", true);
- xwimp_set_caret_position(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL, 0, 0, -1, 4);
- ro_gui_url_complete_start(g);
- ro_gui_url_complete_keypress(g, wimp_KEY_DOWN);
- return true;
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_SHIFT + wimp_KEY_F3:
+ ro_gui_window_action_save(g, GUI_SAVE_DRAW);
+ return;
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F2:
- /* Close window. */
- ro_gui_url_complete_close(NULL, 0);
- browser_window_destroy(g->bw);
- return true;
+ case 6: /* Ctrl + F */
+ case IS_WIMP_KEY + wimp_KEY_F4: /* Search */
+ ro_gui_window_action_search(g);
+ return;
- case 19: /* Ctrl + S */
- case IS_WIMP_KEY + wimp_KEY_F3:
- return ro_gui_menu_handle_action(g->window,
- BROWSER_SAVE, false);
-
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F3:
- return ro_gui_menu_handle_action(g->window,
- BROWSER_EXPORT_TEXT, false);
-
- case IS_WIMP_KEY + wimp_KEY_SHIFT + wimp_KEY_F3:
- return ro_gui_menu_handle_action(g->window,
- BROWSER_SAVE_COMPLETE, false);
-
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_SHIFT +
- wimp_KEY_F3:
- return ro_gui_menu_handle_action(g->window,
- BROWSER_EXPORT_DRAW, false);
-
- case 6: /* Ctrl + F */
- case IS_WIMP_KEY + wimp_KEY_F4: /* Search */
- return ro_gui_menu_handle_action(g->window,
- BROWSER_FIND_TEXT, false);
-
- case IS_WIMP_KEY + wimp_KEY_F5: /* Reload */
- return ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_RELOAD, false);
-
- case 18: /* Ctrl+R (Full reload) */
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F5:
- /* Full reload */
- return ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_RELOAD_ALL, false);
-
- case IS_WIMP_KEY + wimp_KEY_F6: /* Hotlist */
- return ro_gui_menu_handle_action(g->window,
- HOTLIST_SHOW, false);
-
- case IS_WIMP_KEY + wimp_KEY_F7: /* Show local history */
- return ro_gui_menu_handle_action(g->window,
- HISTORY_SHOW_LOCAL, false);
-
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F7:
- /* Show global history */
- return ro_gui_menu_handle_action(g->window,
- HISTORY_SHOW_GLOBAL, false);
-
- case IS_WIMP_KEY + wimp_KEY_F8: /* View source */
- ro_gui_view_source(h);
- return true;
+ case IS_WIMP_KEY + wimp_KEY_F5: /* Reload */
+ if (g->bw != NULL)
+ browser_window_reload(g->bw, false);
+ return;
- case IS_WIMP_KEY + wimp_KEY_F9:
- /* Dump content for debugging. */
- ro_gui_dump_content(h);
- return true;
+ case 18: /* Ctrl+R (Full reload) */
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F5:
+ if (g->bw != NULL)
+ browser_window_reload(g->bw, true);
+ return;
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F9:
- urldb_dump();
- return true;
+ case IS_WIMP_KEY + wimp_KEY_F6: /* Hotlist */
+ ro_gui_hotlist_open();
+ return;
- case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_SHIFT +
- wimp_KEY_F9:
- talloc_report_full(0, stderr);
- return true;
+ case IS_WIMP_KEY + wimp_KEY_F7: /* Show local history */
+ ro_gui_window_action_local_history(g);
+ return;
- case IS_WIMP_KEY + wimp_KEY_F11: /* Zoom */
- return ro_gui_menu_handle_action(g->window,
- BROWSER_SCALE_VIEW, false);
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F7:
+ /* Show global history */
+ ro_gui_global_history_open();
+ return;
- case IS_WIMP_KEY + wimp_KEY_SHIFT + wimp_KEY_F11:
- /* Toggle display of box outlines. */
- html_redraw_debug = !html_redraw_debug;
- gui_window_redraw_window(g);
- return true;
+ case IS_WIMP_KEY + wimp_KEY_F8: /* View source */
+ ro_gui_view_source(h);
+ return;
- case wimp_KEY_RETURN:
- if (!toolbar)
- break;
- toolbar_url = ro_gui_get_icon_string(
- g->toolbar->toolbar_handle,
- ICON_TOOLBAR_URL);
- ro_gui_window_launch_url(g, toolbar_url);
- return true;
+ case IS_WIMP_KEY + wimp_KEY_F9:
+ /* Dump content for debugging. */
+ ro_gui_dump_content(h);
+ return;
- case wimp_KEY_ESCAPE:
- if (ro_gui_url_complete_close(NULL, 0)) {
- ro_gui_url_complete_start(g);
- return true;
- }
- return ro_gui_menu_handle_action(g->window,
- BROWSER_NAVIGATE_STOP, false);
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_F9:
+ urldb_dump();
+ return;
- case 8: /* CTRL+H / Backspace */
- if (toolbar)
- return ro_gui_url_complete_keypress(g, c);
- break;
+ case IS_WIMP_KEY + wimp_KEY_CONTROL + wimp_KEY_SHIFT + wimp_KEY_F9:
+ talloc_report_full(0, stderr);
+ return;
- case 14: /* CTRL+N */
- return ro_gui_menu_handle_action(g->window,
- BROWSER_NEW_WINDOW, false);
+ case IS_WIMP_KEY + wimp_KEY_F11: /* Zoom */
+ ro_gui_window_action_zoom(g);
+ return;
- case 17: /* CTRL+Q (Zoom out) */
- case 23: /* CTRL+W (Zoom in) */
- if (!h)
- break;
- scale = g->bw->scale;
- if (ro_gui_shift_pressed() && c == 17)
- scale = g->bw->scale - 0.1;
- else if (ro_gui_shift_pressed() && c == 23)
- scale = g->bw->scale + 0.1;
- else if (c == 17) {
- for (int i = SCALE_SNAP_TO_SIZE - 1;
- i >= 0; i--)
- if (scale_snap_to[i] <
- g->bw->scale) {
- scale = scale_snap_to[i];
- break;
- }
- } else {
- for (unsigned int i = 0;
- i < SCALE_SNAP_TO_SIZE; i++)
- if (scale_snap_to[i] >
- g->bw->scale) {
- scale = scale_snap_to[i];
- break;
- }
- }
- if (scale < scale_snap_to[0])
- scale = scale_snap_to[0];
- if (scale > scale_snap_to[SCALE_SNAP_TO_SIZE - 1])
- scale = scale_snap_to[SCALE_SNAP_TO_SIZE - 1];
- if (g->bw->scale != scale) {
- browser_window_set_scale(g->bw, scale, true);
-// g->reformat_pending = true;
-// if ((h) && (content_get_type(h) != CONTENT_HTML))
-// browser_window_update(g->bw, false);
-// browser_reformat_pending = true;
- }
- return true;
+ case IS_WIMP_KEY + wimp_KEY_SHIFT + wimp_KEY_F11:
+ /* Toggle display of box outlines. */
+ html_redraw_debug = !html_redraw_debug;
+ gui_window_redraw_window(g);
+ return;
- case IS_WIMP_KEY + wimp_KEY_PRINT:
- return ro_gui_menu_handle_action(g->window,
- BROWSER_PRINT, false);
+ case wimp_KEY_RETURN:
+ if (is_toolbar) {
+ toolbar_url = ro_toolbar_get_url(g->toolbar);
+ if (toolbar_url != NULL)
+ ro_gui_window_launch_url(g, toolbar_url);
+ }
+ return;
- case IS_WIMP_KEY | wimp_KEY_LEFT:
- case IS_WIMP_KEY | wimp_KEY_RIGHT:
- case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_LEFT:
- case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_RIGHT:
- if (toolbar)
- return false;
- break;
- case IS_WIMP_KEY + wimp_KEY_UP:
- case IS_WIMP_KEY + wimp_KEY_DOWN:
- case IS_WIMP_KEY + wimp_KEY_PAGE_UP:
- case IS_WIMP_KEY + wimp_KEY_PAGE_DOWN:
- case wimp_KEY_HOME:
- case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_UP:
- case IS_WIMP_KEY + wimp_KEY_END:
- case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_DOWN:
- if (toolbar)
- return ro_gui_url_complete_keypress(g, c);
+ case wimp_KEY_ESCAPE:
+ if (ro_gui_url_complete_close()) {
+ ro_gui_url_complete_start(g->toolbar);
+ return;
+ }
+
+ if (g->bw != NULL)
+ browser_window_stop(g->bw);
+ return;
+
+ case 14: /* CTRL+N */
+ ro_gui_window_action_new_window(g);
+ return;
+
+ case 17: /* CTRL+Q (Zoom out) */
+ case 23: /* CTRL+W (Zoom in) */
+ if (!h)
break;
- default:
- if (toolbar)
- return ro_gui_url_complete_keypress(g, c);
- return false;
+ scale = g->bw->scale;
+ if (ro_gui_shift_pressed() && c == 17)
+ scale = g->bw->scale - 0.1;
+ else if (ro_gui_shift_pressed() && c == 23)
+ scale = g->bw->scale + 0.1;
+ else if (c == 17) {
+ for (int i = SCALE_SNAP_TO_SIZE - 1; i >= 0; i--)
+ if (scale_snap_to[i] < g->bw->scale) {
+ scale = scale_snap_to[i];
+ break;
+ }
+ } else {
+ for (unsigned int i = 0; i < SCALE_SNAP_TO_SIZE; i++)
+ if (scale_snap_to[i] > g->bw->scale) {
+ scale = scale_snap_to[i];
+ break;
+ }
+ }
+ if (scale < scale_snap_to[0])
+ scale = scale_snap_to[0];
+ if (scale > scale_snap_to[SCALE_SNAP_TO_SIZE - 1])
+ scale = scale_snap_to[SCALE_SNAP_TO_SIZE - 1];
+ if (g->bw->scale != scale) {
+ browser_window_set_scale(g->bw, scale, true);
+// g->reformat_pending = true;
+// if ((h) && (content_get_type(h) != CONTENT_HTML))
+// browser_window_update(g->bw, false);
+// browser_reformat_pending = true;
+ }
+ return;
+
+ case IS_WIMP_KEY + wimp_KEY_PRINT:
+ ro_gui_window_action_print(g);
+ return;
+
+ case IS_WIMP_KEY | wimp_KEY_LEFT:
+ case IS_WIMP_KEY | wimp_KEY_RIGHT:
+ case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_LEFT:
+ case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_RIGHT:
+ if (is_toolbar)
+ return;
+ break;
+ case IS_WIMP_KEY + wimp_KEY_UP:
+ case IS_WIMP_KEY + wimp_KEY_DOWN:
+ case IS_WIMP_KEY + wimp_KEY_PAGE_UP:
+ case IS_WIMP_KEY + wimp_KEY_PAGE_DOWN:
+ case wimp_KEY_HOME:
+ case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_UP:
+ case IS_WIMP_KEY + wimp_KEY_END:
+ default:
+ break;
}
state.w = g->window;
@@ -2571,12 +2366,12 @@ bool ro_gui_window_keypress(wimp_key *key)
if (error) {
LOG(("xwimp_get_window_state: 0x%x: %s",
error->errnum, error->errmess));
- return true;
+ return;
}
y = state.visible.y1 - state.visible.y0 - 32;
if (g->toolbar)
- y -= ro_gui_theme_toolbar_full_height(g->toolbar);
+ y -= ro_toolbar_full_height(g->toolbar);
switch (c) {
case IS_WIMP_KEY | wimp_KEY_LEFT:
@@ -2618,17 +2413,870 @@ bool ro_gui_window_keypress(wimp_key *key)
LOG(("xwimp_open_window: 0x%x: %s",
error->errnum, error->errmess));
}
+}
+
+
+/**
+ * Prepare the browser window menu for (re-)opening
+ *
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param *menu The menu about to be opened.
+ * \param *pointer Pointer to the relevant wimp event block, or
+ * NULL for an Adjust click.
+ * \return true if the event was handled; else false.
+ */
+
+bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_pointer *pointer)
+{
+ struct gui_window *g;
+ struct browser_window *bw;
+ hlcache_handle *h;
+ struct toolbar *toolbar;
+ bool export_sprite, export_draw;
+ os_coord pos;
+
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(w);
+ toolbar = g->toolbar;
+ bw = g->bw;
+ h = bw->current_content;
+
+ /* If this is the form select menu, handle it now and then exit.
+ * Otherwise, carry on to the main browser window menu.
+ */
+
+ if (menu == gui_form_select_menu) {
+ return ro_gui_window_prepare_form_select_menu(g->bw,
+ gui_form_select_control);
+ }
+
+ if (menu != ro_gui_browser_window_menu)
+ return false;
+
+ /* If this is a new opening for the browser window menu (ie. not for a
+ * toolbar menu), get details of the object under the pointer.
+ */
+
+ if (pointer != NULL && g->window == w) {
+ ro_gui_url_complete_close();
+
+ current_menu_object = NULL;
+ current_menu_url = NULL;
+
+ if (h != NULL &&
+ ro_gui_window_to_window_pos(g, pointer->pos.x,
+ pointer->pos.y, &pos)) {
+ switch (content_get_type(h)) {
+ case CONTENT_HTML: {
+ struct box *box;
+ box = box_object_at_point(h, pos.x, pos.y);
+ current_menu_object = box ? box->object : NULL;
+ box = box_href_at_point(h, pos.x, pos.y);
+ current_menu_url = box ? box->href : NULL;
+ }
+ break;
+ case CONTENT_TEXTPLAIN:
+ /* no object, no url */
+ break;
+ default:
+ current_menu_object = h;
+ break;
+ }
+ }
+ }
+
+ /* Shade menu entries according to the state of the window and object
+ * under the pointer.
+ */
+
+ /* Toolbar (Sub)Menu */
+
+ ro_gui_menu_set_entry_shaded(menu, TOOLBAR_BUTTONS,
+ ro_toolbar_menu_option_shade(toolbar));
+ ro_gui_menu_set_entry_ticked(menu, TOOLBAR_BUTTONS,
+ ro_toolbar_menu_buttons_tick(toolbar));
+
+ ro_gui_menu_set_entry_shaded(menu, TOOLBAR_ADDRESS_BAR,
+ ro_toolbar_menu_edit_shade(toolbar));
+ ro_gui_menu_set_entry_ticked(menu, TOOLBAR_ADDRESS_BAR,
+ ro_toolbar_menu_url_tick(toolbar));
+
+ ro_gui_menu_set_entry_shaded(menu, TOOLBAR_THROBBER,
+ ro_toolbar_menu_edit_shade(toolbar));
+ ro_gui_menu_set_entry_ticked(menu, TOOLBAR_THROBBER,
+ ro_toolbar_menu_throbber_tick(toolbar));
+
+ ro_gui_menu_set_entry_shaded(menu, TOOLBAR_EDIT,
+ ro_toolbar_menu_edit_shade(toolbar));
+ ro_gui_menu_set_entry_ticked(menu, TOOLBAR_EDIT,
+ ro_toolbar_menu_edit_tick(toolbar));
+
+ /* Page Submenu */
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_PAGE, h == NULL ||
+ (content_get_type(h) != CONTENT_HTML &&
+ content_get_type(h) != CONTENT_TEXTPLAIN));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_PAGE_INFO, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_PRINT, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_NEW_WINDOW, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_FIND_TEXT,
+ h == NULL || (content_get_type(h) != CONTENT_HTML &&
+ content_get_type(h) != CONTENT_TEXTPLAIN));
+
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_VIEW_SOURCE, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE_URL_URI, h == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE_URL_URL, h == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE_URL_TEXT, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE, h == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SAVE_COMPLETE, h == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_EXPORT_DRAW, h == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_EXPORT_PDF, h == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_EXPORT_TEXT, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_LINK_SAVE_URI,
+ !current_menu_url);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_LINK_SAVE_URL,
+ !current_menu_url);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_LINK_SAVE_TEXT,
+ !current_menu_url);
+
+
+
+ /* Object Submenu */
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT,
+ current_menu_object == NULL &&
+ current_menu_url == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_LINK,
+ current_menu_url == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_INFO,
+ current_menu_object == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_RELOAD,
+ current_menu_object == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_OBJECT,
+ current_menu_object == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_PRINT, true);
+ /* Not yet implemented */
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_SAVE,
+ current_menu_object == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_SAVE_URL_URI,
+ current_menu_object == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_SAVE_URL_URL,
+ current_menu_object == NULL);
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_SAVE_URL_TEXT,
+ current_menu_object == NULL);
+
+ if (current_menu_object != NULL)
+ ro_gui_window_content_export_types(current_menu_object,
+ &export_draw, &export_sprite);
+ else
+ ro_gui_window_content_export_types(h,
+ &export_draw, &export_sprite);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_EXPORT,
+ (h == NULL && current_menu_object == NULL)
+ || !(export_sprite || export_draw));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_EXPORT_SPRITE,
+ (h == NULL && current_menu_object == NULL)
+ || !export_sprite);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_EXPORT_DRAW,
+ (h == NULL && current_menu_object == NULL)
+ || !export_draw);
+
+
+ /* Selection Submenu */
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION,
+ h == NULL || (content_get_type(h) != CONTENT_HTML &&
+ content_get_type(h) != CONTENT_TEXTPLAIN));
+ /* make menu available if there's anything that /could/
+ * be selected */
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_SAVE, h == NULL ||
+ bw->sel == NULL || !selection_defined(bw->sel));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_COPY, h == NULL ||
+ bw->sel == NULL || !selection_defined(bw->sel));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_CUT, h == NULL ||
+ bw->sel == NULL || !selection_defined(bw->sel) ||
+ selection_read_only(bw->sel));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_PASTE,
+ h == NULL || bw->paste_callback == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SELECTION_CLEAR, h == NULL ||
+ bw->sel == NULL || !selection_defined(bw->sel));
+
+
+ /* Navigate Submenu */
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_BACK,
+ !browser_window_back_available(bw));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_FORWARD,
+ !browser_window_forward_available(bw));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_RELOAD_ALL,
+ !browser_window_reload_available(bw));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_STOP,
+ !browser_window_stop_available(bw));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_NAVIGATE_UP,
+ !ro_gui_window_up_available(bw));
+
+
+
+ /* View Submenu */
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_IMAGES_FOREGROUND, true);
+ ro_gui_menu_set_entry_ticked(menu, BROWSER_IMAGES_FOREGROUND, true);
+ /* Not yet implemented. */
+
+ ro_gui_menu_set_entry_ticked(menu, BROWSER_IMAGES_BACKGROUND,
+ g != NULL && g->option.background_images);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_BUFFER_ANIMS,
+ g == NULL || g->option.buffer_everything);
+ ro_gui_menu_set_entry_ticked(menu, BROWSER_BUFFER_ANIMS, g != NULL &&
+ (g->option.buffer_animations ||
+ g->option.buffer_everything));
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_BUFFER_ALL, g == NULL);
+ ro_gui_menu_set_entry_ticked(menu, BROWSER_BUFFER_ALL,
+ g != NULL && g->option.buffer_everything);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_SCALE_VIEW, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_WINDOW_STAGGER,
+ option_window_screen_width == 0);
+ ro_gui_menu_set_entry_ticked(menu, BROWSER_WINDOW_STAGGER,
+ ((option_window_screen_width == 0) ||
+ option_window_stagger));
+
+ ro_gui_menu_set_entry_ticked(menu, BROWSER_WINDOW_COPY,
+ option_window_size_clone);
+
+ ro_gui_menu_set_entry_shaded(menu, BROWSER_WINDOW_RESET,
+ option_window_screen_width == 0);
+
+
+ /* Utilities Submenu */
+
+ ro_gui_menu_set_entry_shaded(menu, HOTLIST_ADD_URL, h == NULL);
+
+ ro_gui_menu_set_entry_shaded(menu, HISTORY_SHOW_LOCAL,
+ (bw == NULL || (bw->history == NULL) ||
+ !(h != NULL || history_back_available(bw->history) ||
+ history_forward_available(bw->history))));
+
+
+ /* Help Submenu */
+
+ ro_gui_menu_set_entry_ticked(menu, HELP_LAUNCH_INTERACTIVE,
+ ro_gui_interactive_help_available() &&
+ option_interactive_help);
return true;
}
/**
+ * Handle submenu warnings for a browser window menu
+ *
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param *menu The menu to which the warning applies.
+ * \param *selection The wimp menu selection data.
+ * \param action The selected menu action.
+ */
+
+void ro_gui_window_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action)
+{
+ struct gui_window *g;
+ struct browser_window *bw;
+ hlcache_handle *h;
+ struct toolbar *toolbar;
+ bool export;
+
+ if (menu != ro_gui_browser_window_menu)
+ return;
+
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(w);
+ toolbar = g->toolbar;
+ bw = g->bw;
+ h = bw->current_content;
+
+ switch (action) {
+ case BROWSER_PAGE_INFO:
+ if (h != NULL)
+ ro_gui_window_prepare_pageinfo(g);
+ break;
+
+ case BROWSER_FIND_TEXT:
+ if (h != NULL && (content_get_type(h) == CONTENT_HTML ||
+ content_get_type(h) == CONTENT_TEXTPLAIN))
+ ro_gui_search_prepare(g->bw);
+ break;
+
+ case BROWSER_SCALE_VIEW:
+ if (h != NULL)
+ ro_gui_dialog_prepare_zoom(g);
+ break;
+
+ case BROWSER_PRINT:
+ if (h != NULL)
+ ro_gui_print_prepare(g);
+ break;
+
+ case BROWSER_OBJECT_INFO:
+ if (current_menu_object != NULL)
+ ro_gui_window_prepare_objectinfo(current_menu_object,
+ current_menu_url);
+ break;
+
+ case BROWSER_OBJECT_SAVE:
+ if (current_menu_object != NULL)
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_ORIG,
+ current_menu_object, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_SELECTION_SAVE:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL,
+ bw->sel, NULL, NULL);
+ break;
+
+ case BROWSER_SAVE_URL_URI:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
+ content_get_url(h),
+ content_get_title(h));
+ break;
+
+ case BROWSER_SAVE_URL_URL:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
+ content_get_url(h),
+ content_get_title(h));
+ break;
+
+ case BROWSER_SAVE_URL_TEXT:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
+ content_get_url(h),
+ content_get_title(h));
+ break;
+
+ case BROWSER_OBJECT_SAVE_URL_URI:
+ if (current_menu_object != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
+ content_get_url(current_menu_object),
+ content_get_title(current_menu_object));
+ break;
+
+ case BROWSER_OBJECT_SAVE_URL_URL:
+ if (current_menu_object != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
+ content_get_url(current_menu_object),
+ content_get_title(current_menu_object));
+ break;
+
+ case BROWSER_OBJECT_SAVE_URL_TEXT:
+ if (current_menu_object != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
+ content_get_url(current_menu_object),
+ content_get_title(current_menu_object));
+ break;
+
+ case BROWSER_SAVE:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_SOURCE, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_SAVE_COMPLETE:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_COMPLETE, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_EXPORT_DRAW:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_DRAW, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_EXPORT_PDF:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_PDF, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_EXPORT_TEXT:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_TEXT, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_LINK_SAVE_URI:
+ if (current_menu_url != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
+ current_menu_url, NULL);
+ break;
+
+ case BROWSER_LINK_SAVE_URL:
+ if (current_menu_url != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
+ current_menu_url, NULL);
+ break;
+
+ case BROWSER_LINK_SAVE_TEXT:
+ if (current_menu_url != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
+ current_menu_url, NULL);
+ break;
+
+ case BROWSER_OBJECT_EXPORT_SPRITE:
+ if (current_menu_object != NULL) {
+ ro_gui_window_content_export_types(current_menu_object,
+ NULL, &export);
+
+ if (export)
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ current_menu_object,
+ NULL, NULL, NULL);
+ } else if (h != NULL) {
+ ro_gui_window_content_export_types(h, NULL, &export);
+
+ if (export)
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ h, NULL, NULL, NULL);
+ }
+ break;
+
+ case BROWSER_OBJECT_EXPORT_DRAW:
+ if (current_menu_object != NULL) {
+ ro_gui_window_content_export_types(current_menu_object,
+ &export, NULL);
+
+ if (export)
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ current_menu_object,
+ NULL, NULL, NULL);
+ } else if (h != NULL) {
+ ro_gui_window_content_export_types(h, &export, NULL);
+
+ if (export)
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ h, NULL, NULL, NULL);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/**
+ * Handle selections from a browser window menu
+ *
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param *menu The menu from which the selection was made.
+ * \param *selection The wimp menu selection data.
+ * \param action The selected menu action.
+ * \return true if action accepted; else false.
+ */
+
+bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
+ wimp_selection *selection, menu_action action)
+{
+ struct gui_window *g;
+ struct browser_window *bw;
+ hlcache_handle *h;
+ struct toolbar *toolbar;
+ wimp_window_state state;
+ os_error *error;
+
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(w);
+ toolbar = g->toolbar;
+ bw = g->bw;
+ h = bw->current_content;
+
+ /* If this is a form menu from the core, handle it now and then exit.
+ * Otherwise, carry on to the main browser window menu.
+ */
+
+ if (menu == gui_form_select_menu && w == g->window) {
+ ro_gui_window_process_form_select_menu(g, selection);
+
+ return true;
+ }
+
+ /* We're now safe to assume that this is either the browser or
+ * toolbar window menu.
+ */
+
+ switch (action) {
+
+ /* help actions */
+ case HELP_OPEN_CONTENTS:
+ ro_gui_open_help_page("documentation/index");
+ break;
+ case HELP_OPEN_GUIDE:
+ ro_gui_open_help_page("documentation/guide");
+ break;
+ case HELP_OPEN_INFORMATION:
+ ro_gui_open_help_page("documentation/info");
+ break;
+ case HELP_OPEN_ABOUT:
+ ro_gui_open_help_page("about/index");
+ break;
+ case HELP_LAUNCH_INTERACTIVE:
+ if (!ro_gui_interactive_help_available()) {
+ ro_gui_interactive_help_start();
+ option_interactive_help = true;
+ } else {
+ option_interactive_help = !option_interactive_help;
+ }
+ break;
+
+ /* history actions */
+ case HISTORY_SHOW_LOCAL:
+ ro_gui_window_action_local_history(g);
+ break;
+ case HISTORY_SHOW_GLOBAL:
+ ro_gui_global_history_open();
+ break;
+
+ /* hotlist actions */
+ case HOTLIST_ADD_URL:
+ ro_gui_window_action_add_bookmark(g);
+ break;
+ case HOTLIST_SHOW:
+ ro_gui_hotlist_open();
+ break;
+
+ /* cookies actions */
+ case COOKIES_SHOW:
+ ro_gui_cookies_open();
+ break;
+
+ case COOKIES_DELETE:
+ cookies_delete_all();
+ break;
+
+ /* page actions */
+ case BROWSER_PAGE_INFO:
+ ro_gui_window_action_page_info(g);
+ break;
+ case BROWSER_PRINT:
+ ro_gui_window_action_print(g);
+ break;
+ case BROWSER_NEW_WINDOW:
+ ro_gui_window_action_new_window(g);
+ break;
+ case BROWSER_VIEW_SOURCE:
+ if (h != NULL)
+ ro_gui_view_source(h);
+ break;
+
+ /* object actions */
+ case BROWSER_OBJECT_INFO:
+ if (current_menu_object != NULL) {
+ ro_gui_window_prepare_objectinfo(current_menu_object,
+ current_menu_url);
+ ro_gui_dialog_open_persistent(g->window,
+ dialog_objinfo, false);
+ }
+ break;
+ case BROWSER_OBJECT_RELOAD:
+ if (current_menu_object != NULL) {
+ content_invalidate_reuse_data(current_menu_object);
+ browser_window_reload(bw, false);
+ }
+ break;
+
+ /* link actions */
+ case BROWSER_LINK_SAVE_URI:
+ if (current_menu_url != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
+ current_menu_url, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ false);
+ }
+ break;
+ case BROWSER_LINK_SAVE_URL:
+ if (current_menu_url != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
+ current_menu_url, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ false);
+ }
+ break;
+ case BROWSER_LINK_SAVE_TEXT:
+ if (current_menu_url != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
+ current_menu_url, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ false);
+ }
+ break;
+ case BROWSER_LINK_DOWNLOAD:
+ if (current_menu_url != NULL)
+ browser_window_download(bw, current_menu_url,
+ content_get_url(h));
+ break;
+ case BROWSER_LINK_NEW_WINDOW:
+ if (current_menu_url != NULL)
+ browser_window_create(current_menu_url, bw,
+ content_get_url(h), true, false);
+ break;
+
+ /* save actions */
+ case BROWSER_OBJECT_SAVE:
+ if (current_menu_object != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_ORIG,
+ current_menu_object, NULL, NULL, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ false);
+ }
+ break;
+ case BROWSER_OBJECT_EXPORT_SPRITE:
+ if (current_menu_object != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ current_menu_object, NULL, NULL, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ false);
+ }
+ break;
+ case BROWSER_OBJECT_EXPORT_DRAW:
+ if (current_menu_object != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ current_menu_object, NULL, NULL, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ false);
+ }
+ break;
+ case BROWSER_SAVE:
+ ro_gui_window_action_save(g, GUI_SAVE_SOURCE);
+ break;
+ case BROWSER_SAVE_COMPLETE:
+ ro_gui_window_action_save(g, GUI_SAVE_COMPLETE);
+ break;
+ case BROWSER_EXPORT_DRAW:
+ ro_gui_window_action_save(g, GUI_SAVE_DRAW);
+ break;
+ case BROWSER_EXPORT_PDF:
+ ro_gui_window_action_save(g, GUI_SAVE_PDF);
+ break;
+ case BROWSER_EXPORT_TEXT:
+ ro_gui_window_action_save(g, GUI_SAVE_TEXT);
+ break;
+ case BROWSER_SAVE_URL_URI:
+ ro_gui_window_action_save(g, GUI_SAVE_LINK_URI);
+ break;
+ case BROWSER_SAVE_URL_URL:
+ ro_gui_window_action_save(g, GUI_SAVE_LINK_URL);
+ break;
+ case BROWSER_SAVE_URL_TEXT:
+ ro_gui_window_action_save(g, GUI_SAVE_LINK_TEXT);
+ break;
+
+ /* selection actions */
+ case BROWSER_SELECTION_SAVE:
+ if (h != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL,
+ bw->sel, NULL, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ false);
+ }
+ break;
+ case BROWSER_SELECTION_COPY:
+ browser_window_key_press(bw, KEY_COPY_SELECTION);
+ break;
+ case BROWSER_SELECTION_CUT:
+ browser_window_key_press(bw, KEY_CUT_SELECTION);
+ break;
+ case BROWSER_SELECTION_PASTE:
+ browser_window_key_press(bw, KEY_PASTE);
+ break;
+ case BROWSER_SELECTION_ALL:
+ browser_window_key_press(bw, KEY_SELECT_ALL);
+ break;
+ case BROWSER_SELECTION_CLEAR:
+ browser_window_key_press(bw, KEY_CLEAR_SELECTION);
+ break;
+
+ /* navigation actions */
+ case BROWSER_NAVIGATE_HOME:
+ ro_gui_window_action_home(g);
+ break;
+ case BROWSER_NAVIGATE_BACK:
+ if (bw != NULL && bw->history != NULL)
+ history_back(bw, bw->history);
+ break;
+ case BROWSER_NAVIGATE_FORWARD:
+ if (bw != NULL && bw->history != NULL)
+ history_forward(bw, bw->history);
+ break;
+ case BROWSER_NAVIGATE_UP:
+ if (bw != NULL && h != NULL)
+ ro_gui_window_navigate_up(bw->window,
+ content_get_url(h));
+ break;
+ case BROWSER_NAVIGATE_RELOAD_ALL:
+ if (bw != NULL)
+ browser_window_reload(bw, true);
+ break;
+ case BROWSER_NAVIGATE_STOP:
+ if (bw != NULL)
+ browser_window_stop(bw);
+ break;
+
+ /* browser window/display actions */
+ case BROWSER_SCALE_VIEW:
+ ro_gui_window_action_zoom(g);
+ break;
+ case BROWSER_FIND_TEXT:
+ ro_gui_window_action_search(g);
+ break;
+ case BROWSER_IMAGES_BACKGROUND:
+ if (g != NULL) {
+ g->option.background_images =
+ !g->option.background_images;
+ gui_window_redraw_window(g);
+ }
+ break;
+ case BROWSER_BUFFER_ANIMS:
+ if (g != NULL)
+ g->option.buffer_animations =
+ !g->option.buffer_animations;
+ break;
+ case BROWSER_BUFFER_ALL:
+ if (g != NULL)
+ g->option.buffer_everything =
+ !g->option.buffer_everything;
+ break;
+ case BROWSER_SAVE_VIEW:
+ if (bw != NULL) {
+ ro_gui_window_default_options(bw);
+ ro_gui_save_options();
+ }
+ break;
+ case BROWSER_WINDOW_DEFAULT:
+ if (g != NULL) {
+ ro_gui_screen_size(&option_window_screen_width,
+ &option_window_screen_height);
+ state.w = 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);
+ }
+ option_window_x = state.visible.x0;
+ option_window_y = state.visible.y0;
+ option_window_width =
+ state.visible.x1 - state.visible.x0;
+ option_window_height =
+ state.visible.y1 - state.visible.y0;
+ ro_gui_save_options();
+ }
+ break;
+ case BROWSER_WINDOW_STAGGER:
+ option_window_stagger = !option_window_stagger;
+ ro_gui_save_options();
+ break;
+ case BROWSER_WINDOW_COPY:
+ option_window_size_clone = !option_window_size_clone;
+ ro_gui_save_options();
+ break;
+ case BROWSER_WINDOW_RESET:
+ option_window_screen_width = 0;
+ option_window_screen_height = 0;
+ ro_gui_save_options();
+ break;
+
+ /* toolbar actions */
+ case TOOLBAR_BUTTONS:
+ assert(toolbar);
+ ro_toolbar_set_display_buttons(toolbar,
+ !ro_toolbar_get_display_buttons(toolbar));
+ break;
+ case TOOLBAR_ADDRESS_BAR:
+ assert(toolbar);
+ ro_toolbar_set_display_url(toolbar,
+ !ro_toolbar_get_display_url(toolbar));
+ if (ro_toolbar_get_display_url(toolbar))
+ ro_toolbar_take_caret(toolbar);
+ break;
+ case TOOLBAR_THROBBER:
+ assert(toolbar);
+ ro_toolbar_set_display_throbber(toolbar,
+ !ro_toolbar_get_display_throbber(toolbar));
+ break;
+ case TOOLBAR_EDIT:
+ assert(toolbar);
+ ro_toolbar_toggle_edit(toolbar);
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ * Handle the closure of a browser window menu
+ *
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param *menu The menu that is being closed.
+ */
+
+void ro_gui_window_menu_close(wimp_w w, wimp_i i, wimp_menu *menu)
+{
+ if (menu == ro_gui_browser_window_menu) {
+ current_menu_object = NULL;
+ current_menu_url = NULL;
+ } else if (menu == gui_form_select_menu) {
+ gui_form_select_control = NULL;
+ }
+}
+
+
+/**
* Process Scroll_Request events.
+ *
+ * \TODO -- This handles Scroll Events for all windows, not just browser
+ * windows. Either it needs to move somewhere else, or the
+ * code needs to be split and Scroll Events dispatched via the
+ * Wimp_Event module. Currently it doesn't properly handle
+ * events affecting treeview windows, anyway.
*/
+
void ro_gui_scroll_request(wimp_scroll *scroll)
{
- struct gui_window *g = ro_gui_window_lookup(scroll->w);
+ struct gui_window *g = ro_gui_window_lookup(scroll->w);
+ struct toolbar *toolbar;
if (g && g->bw->current_content && ro_gui_shift_pressed()) {
/* extended scroll request with shift held down; change zoom */
@@ -2656,8 +3304,12 @@ void ro_gui_scroll_request(wimp_scroll *scroll)
int y = scroll->visible.y1 - scroll->visible.y0 - 32;
os_error *error;
- if (g && g->toolbar)
- y -= ro_gui_theme_toolbar_full_height(g->toolbar);
+ /* This has to handle all windows, not just browser ones. */
+ toolbar = ro_toolbar_parent_window_lookup(scroll->w);
+ assert(g == NULL || g->toolbar == NULL ||
+ g->toolbar == toolbar);
+ if (toolbar != NULL)
+ y -= ro_toolbar_full_height(toolbar);
switch (scroll->xmin) {
case wimp_SCROLL_PAGE_LEFT:
@@ -2705,70 +3357,6 @@ void ro_gui_scroll_request(wimp_scroll *scroll)
/**
- * Convert x,y screen co-ordinates into window co-ordinates.
- *
- * \param g gui window
- * \param x x ordinate
- * \param y y ordinate
- * \param pos receives position in window co-ordinatates
- * \return true iff conversion successful
- */
-
-bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y,
- os_coord *pos)
-{
- wimp_window_state state;
- os_error *error;
-
- assert(g);
-
- state.w = g->window;
- 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;
- }
- pos->x = (x - (state.visible.x0 - state.xscroll)) / 2 / g->bw->scale;
- pos->y = ((state.visible.y1 - state.yscroll) - y) / 2 / g->bw->scale;
- return true;
-}
-
-
-/**
- * Convert x,y window co-ordinates into screen co-ordinates.
- *
- * \param g gui window
- * \param x x ordinate
- * \param y y ordinate
- * \param pos receives position in screen co-ordinatates
- * \return true iff conversion successful
- */
-
-bool ro_gui_window_to_screen_pos(struct gui_window *g, int x, int y,
- os_coord *pos)
-{
- wimp_window_state state;
- os_error *error;
-
- assert(g);
-
- state.w = g->window;
- 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;
- }
- pos->x = (x * 2 * g->bw->scale) + (state.visible.x0 - state.xscroll);
- pos->y = (state.visible.y1 - state.yscroll) - (y * 2 * g->bw->scale);
- return true;
-}
-
-
-/**
* Handle Message_DataLoad (file dragged in) for a window.
*
* \param g window
@@ -2884,8 +3472,366 @@ bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message)
/**
+ * Handle pointer movements in a browser window.
+ *
+ * \param g browser window that the pointer is in
+ * \param pointer new mouse position
+ */
+
+void ro_gui_window_mouse_at(struct gui_window *g, wimp_pointer *pointer)
+{
+ os_coord pos;
+
+ if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos))
+ browser_window_mouse_track(g->bw,
+ ro_gui_mouse_drag_state(pointer->buttons,
+ wimp_BUTTON_CLICK_DRAG),
+ pos.x, pos.y);
+}
+
+
+/**
+ * Window is being iconised. Create a suitable thumbnail sprite
+ * (which, sadly, must be in the Wimp sprite pool), and return
+ * the sprite name and truncated title to the iconiser
+ *
+ * \param g the gui window being iconised
+ * \param wi the WindowInfo message from the iconiser
+ */
+
+void ro_gui_window_iconise(struct gui_window *g,
+ wimp_full_message_window_info *wi)
+{
+ /* sadly there is no 'legal' way to get the sprite into
+ * the Wimp sprite pool other than via a filing system */
+ const char *temp_fname = "Pipe:$._tmpfile";
+ struct browser_window *bw = g->bw;
+ osspriteop_header *overlay = NULL;
+ osspriteop_header *sprite_header;
+ struct bitmap *bitmap;
+ osspriteop_area *area;
+ int width = 34, height = 34;
+ hlcache_handle *h;
+ os_error *error;
+ int len, id;
+
+ assert(bw);
+
+ h = bw->current_content;
+ if (!h) return;
+
+ /* if an overlay sprite is defined, locate it and gets its dimensions
+ * so that we can produce a thumbnail with the same dimensions */
+ if (!ro_gui_wimp_get_sprite("ic_netsfxx", &overlay)) {
+ error = xosspriteop_read_sprite_info(osspriteop_PTR,
+ (osspriteop_area *)0x100,
+ (osspriteop_id)overlay, &width, &height, NULL,
+ NULL);
+ if (error) {
+ LOG(("xosspriteop_read_sprite_info: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("MiscError", error->errmess);
+ overlay = NULL;
+ }
+ else if (sprite_bpp(overlay) != 8) {
+ LOG(("overlay sprite is not 8bpp"));
+ overlay = NULL;
+ }
+ }
+
+ /* create the thumbnail sprite */
+ bitmap = bitmap_create(width, height, BITMAP_NEW | BITMAP_OPAQUE |
+ BITMAP_CLEAR_MEMORY);
+ if (!bitmap) {
+ LOG(("Thumbnail initialisation failed."));
+ return;
+ }
+ thumbnail_create(h, bitmap, NULL);
+ if (overlay)
+ bitmap_overlay_sprite(bitmap, overlay);
+ area = thumbnail_convert_8bpp(bitmap);
+ bitmap_destroy(bitmap);
+ if (!area) {
+ LOG(("Thumbnail conversion failed."));
+ return;
+ }
+
+ /* choose a suitable sprite name */
+ id = 0;
+ while (iconise_used[id])
+ if ((unsigned)++id >= NOF_ELEMENTS(iconise_used)) {
+ id = iconise_next;
+ if ((unsigned)++iconise_next >=
+ NOF_ELEMENTS(iconise_used))
+ iconise_next = 0;
+ break;
+ }
+
+ sprite_header = (osspriteop_header *)(area + 1);
+ len = sprintf(sprite_header->name, "ic_netsf%.2d", id);
+
+ error = xosspriteop_save_sprite_file(osspriteop_USER_AREA,
+ area, temp_fname);
+ if (error) {
+ LOG(("xosspriteop_save_sprite_file: 0x%x:%s",
+ error->errnum, error->errmess));
+ warn_user("MiscError", error->errmess);
+ free(area);
+ return;
+ }
+
+ error = xwimpspriteop_merge_sprite_file(temp_fname);
+ if (error) {
+ LOG(("xwimpspriteop_merge_sprite_file: 0x%x:%s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ remove(temp_fname);
+ free(area);
+ return;
+ }
+
+ memcpy(wi->sprite_name, sprite_header->name + 3, len - 2); /* inc NUL */
+ strncpy(wi->title, g->title, sizeof(wi->title));
+ wi->title[sizeof(wi->title) - 1] = '\0';
+
+ if (wimptextop_string_width(wi->title, 0) > 182) {
+ /* work around bug in Pinboard where it will fail to display
+ * the icon if the text is very wide */
+ if (strlen(wi->title) > 10)
+ wi->title[10] = '\0'; /* pinboard does this anyway */
+ while (wimptextop_string_width(wi->title, 0) > 182)
+ wi->title[strlen(wi->title) - 1] = '\0';
+ }
+
+ wi->size = sizeof(wimp_full_message_window_info);
+ wi->your_ref = wi->my_ref;
+ error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message*)wi,
+ wi->sender);
+ if (error) {
+ LOG(("xwimp_send_message: 0x%x:%s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+ else {
+ g->iconise_icon = id;
+ iconise_used[id] = true;
+ }
+
+ free(area);
+}
+
+
+/**
+ * Completes scrolling of a browser window
+ *
+ * \param g gui window
+ */
+
+void ro_gui_window_scroll_end(struct gui_window *g, wimp_dragged *drag)
+{
+ wimp_pointer pointer;
+ os_error *error;
+ os_coord pos;
+
+ gui_current_drag_type = GUI_DRAG_NONE;
+ if (!g)
+ return;
+
+ error = xwimp_drag_box((wimp_drag*)-1);
+ if (error) {
+ LOG(("xwimp_drag_box: 0x%x : %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+
+ 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;
+ }
+
+ error = xwimpspriteop_set_pointer_shape("ptr_default", 0x31, 0, 0, 0, 0);
+ if (error) {
+ LOG(("xwimpspriteop_set_pointer_shape: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+
+ if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos))
+ browser_window_mouse_drag_end(g->bw,
+ ro_gui_mouse_click_state(pointer.buttons,
+ wimp_BUTTON_CLICK_DRAG),
+ pos.x, pos.y);
+}
+
+
+/**
+ * Completes resizing of a browser frame
+ *
+ * \param g gui window
+ */
+
+void ro_gui_window_frame_resize_end(struct gui_window *g, wimp_dragged *drag)
+{
+ /* our clean-up is the same as for page scrolling */
+ ro_gui_window_scroll_end(g, drag);
+}
+
+
+/**
+ * Process Mouse_Click events in a toolbar's button bar. This does not handle
+ * other clicks in a toolbar: these are handled by the toolbar module itself.
+ *
+ * \param *data The GUI window associated with the click.
+ * \param action_type The action type to be handled.
+ * \param action The action to process.
+ */
+
+void ro_gui_window_toolbar_click(void *data,
+ toolbar_action_type action_type, union toolbar_action action)
+{
+ struct gui_window *g = data;
+ struct browser_window *new_bw;
+ gui_save_type save_type;
+
+ if (g == NULL)
+ return;
+
+
+ if (action_type == TOOLBAR_ACTION_URL &&
+ action.url == TOOLBAR_URL_DRAG_URL) {
+ if (g->bw->current_content) {
+ hlcache_handle *h = g->bw->current_content;
+
+ if (ro_gui_shift_pressed())
+ save_type = GUI_SAVE_LINK_URL;
+ else
+ save_type = GUI_SAVE_LINK_TEXT;
+
+ ro_gui_drag_save_link(save_type, content_get_url(h),
+ content_get_title(h), g);
+ }
+
+ return;
+ }
+
+
+ /* By now, the only valid action left is a button click. If it isn't
+ * one of those, give up.
+ */
+
+ if (action_type != TOOLBAR_ACTION_BUTTON)
+ return;
+
+ switch (action.button) {
+ case TOOLBAR_BUTTON_BACK:
+ if (g->bw != NULL && g->bw->history != NULL)
+ history_back(g->bw, g->bw->history);
+ break;
+
+ case TOOLBAR_BUTTON_BACK_NEW:
+ ro_gui_window_action_navigate_back_new(g);
+ break;
+
+ case TOOLBAR_BUTTON_FORWARD:
+ if (g->bw != NULL && g->bw->history != NULL)
+ history_forward(g->bw, g->bw->history);
+ break;
+
+ case TOOLBAR_BUTTON_FORWARD_NEW:
+ ro_gui_window_action_navigate_forward_new(g);
+ break;
+
+ case TOOLBAR_BUTTON_STOP:
+ if (g->bw != NULL)
+ browser_window_stop(g->bw);
+ break;
+
+ case TOOLBAR_BUTTON_RELOAD:
+ if (g->bw != NULL)
+ browser_window_reload(g->bw, false);
+ break;
+
+ case TOOLBAR_BUTTON_RELOAD_ALL:
+ if (g->bw != NULL)
+ browser_window_reload(g->bw, true);
+ break;
+
+ case TOOLBAR_BUTTON_HISTORY_LOCAL:
+ ro_gui_window_action_local_history(g);
+ break;
+
+ case TOOLBAR_BUTTON_HISTORY_GLOBAL:
+ ro_gui_global_history_open();
+ break;
+
+ case TOOLBAR_BUTTON_HOME:
+ ro_gui_window_action_home(g);
+ break;
+
+ case TOOLBAR_BUTTON_SEARCH:
+ ro_gui_window_action_search(g);
+ break;
+
+ case TOOLBAR_BUTTON_SCALE:
+ ro_gui_window_action_zoom(g);
+ break;
+
+ case TOOLBAR_BUTTON_BOOKMARK_OPEN:
+ ro_gui_hotlist_open();
+ break;
+
+ case TOOLBAR_BUTTON_BOOKMARK_ADD:
+ ro_gui_window_action_add_bookmark(g);
+ break;
+
+ case TOOLBAR_BUTTON_SAVE_SOURCE:
+ ro_gui_window_action_save(g, GUI_SAVE_SOURCE);
+ break;
+
+ case TOOLBAR_BUTTON_SAVE_COMPLETE:
+ ro_gui_window_action_save(g, GUI_SAVE_COMPLETE);
+ break;
+
+ case TOOLBAR_BUTTON_PRINT:
+ ro_gui_window_action_print(g);
+ break;
+
+ case TOOLBAR_BUTTON_UP:
+ if (g->bw != NULL && g->bw->current_content != NULL)
+ ro_gui_window_navigate_up(g->bw->window,
+ content_get_url(g->bw->current_content));
+ break;
+
+ case TOOLBAR_BUTTON_UP_NEW:
+ if (g->bw && g->bw->current_content) {
+ hlcache_handle *h = g->bw->current_content;
+ new_bw = browser_window_create(NULL,
+ g->bw, NULL, false,
+ false);
+ /* do it without loading the content
+ * into the new window */
+ ro_gui_window_navigate_up(new_bw->window,
+ content_get_url(h));
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ ro_gui_window_update_toolbar_buttons(g);
+}
+
+
+/**
* Handle Message_DataLoad (file dragged in) for a toolbar
*
+ * \TODO -- This belongs in the toolbar module, and should be moved there
+ * once the module is able to usefully handle its own events.
+ *
* \param g window
* \param message Message_DataLoad block
* \return true if the load was processed
@@ -2913,6 +3859,591 @@ bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message)
}
+/*
+ * Helper code for the Wimp Event Handlers.
+ */
+
+/**
+ * Check if a particular menu handle is a browser window menu
+ *
+ * \param *menu The menu in question.
+ * \return true if this menu is a browser window menu
+ */
+
+bool ro_gui_window_check_menu(wimp_menu *menu)
+{
+ return (ro_gui_browser_window_menu == menu) ? true : false;
+}
+
+
+/**
+ * Return boolean flags to show what RISC OS types we can sensibly convert
+ * the given object into.
+ *
+ * \TODO -- This should probably be somewhere else but in window.c, and
+ * should probably even be done in content_().
+ *
+ * \param *h The object to test.
+ * \param *export_draw true on exit if a drawfile would be possible.
+ * \param *export_sprite true on exit if a sprite would be possible.
+ * \return true if valid data is returned; else false.
+ */
+
+bool ro_gui_window_content_export_types(hlcache_handle *h,
+ bool *export_draw, bool *export_sprite)
+{
+ bool found_type = false;
+
+ if (export_draw != NULL)
+ *export_draw = false;
+ if (export_sprite != NULL)
+ *export_sprite = false;
+
+ if (h != NULL) {
+ switch (content_get_type(h)) {
+ /* bitmap types (Sprite export possible) */
+#ifdef WITH_JPEG
+ case CONTENT_JPEG:
+#endif
+#ifdef WITH_MNG
+ case CONTENT_JNG:
+ case CONTENT_MNG:
+#endif
+#ifdef WITH_GIF
+ case CONTENT_GIF:
+#endif
+#ifdef WITH_BMP
+ case CONTENT_BMP:
+ case CONTENT_ICO:
+#endif
+#if defined(WITH_MNG) || defined(WITH_PNG)
+ case CONTENT_PNG:
+#endif
+#ifdef WITH_SPRITE
+ case CONTENT_SPRITE:
+#endif
+ found_type = true;
+ if (export_sprite != NULL)
+ *export_sprite = true;
+ break;
+
+ /* vector types (Draw export possible) */
+#if defined(WITH_NS_SVG) || defined(WITH_RSVG)
+ case CONTENT_SVG:
+#endif
+#ifdef WITH_DRAW
+ case CONTENT_DRAW:
+#endif
+ found_type = true;
+ if (export_draw != NULL)
+ *export_draw = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return found_type;
+}
+
+
+/**
+ * Return true if a browser window can navigate upwards.
+ *
+ * \TODO -- This should probably be somewhere else but in window.c.
+ *
+ * \param *bw the browser window to test.
+ * \return true if navigation up is possible; else false.
+ */
+
+bool ro_gui_window_up_available(struct browser_window *bw)
+{
+ bool result = false, compare;
+ char *parent;
+ url_func_result res;
+
+ if (bw != NULL && bw->current_content != NULL) {
+ res = url_parent(content_get_url(bw->current_content), &parent);
+
+ if (res == URL_FUNC_OK) {
+ res = url_compare(content_get_url(bw->current_content),
+ parent, false, &compare);
+ if (res == URL_FUNC_OK)
+ result = !compare;
+ free(parent);
+ } else {
+ result = false;
+ }
+ }
+
+ return result;
+}
+
+
+/**
+ * Prepare the page info window for use.
+ *
+ * \param *g The GUI window block to use.
+ */
+
+void ro_gui_window_prepare_pageinfo(struct gui_window *g)
+{
+ hlcache_handle *h = g->bw->current_content;
+ char icon_buf[20] = "file_xxx";
+ char enc_buf[40];
+ char enc_token[10] = "Encoding0";
+ const char *icon = icon_buf;
+ const char *title, *url, *mime;
+ const char *enc = "-";
+
+ assert(h);
+
+ title = content_get_title(h);
+ if (title == NULL)
+ title = "-";
+ url = content_get_url(h);
+ if (url == NULL)
+ url = "-";
+ mime = content_get_mime_type(h);
+ if (mime == NULL)
+ mime = "-";
+
+ sprintf(icon_buf, "file_%x", ro_content_filetype(h));
+ if (!ro_gui_wimp_sprite_exists(icon_buf))
+ sprintf(icon_buf, "file_xxx");
+
+ if (content_get_type(h) == CONTENT_HTML) {
+ if (html_get_encoding(h)) {
+ enc_token[8] = '0' + html_get_encoding_source(h);
+ snprintf(enc_buf, sizeof enc_buf, "%s (%s)",
+ html_get_encoding(h),
+ messages_get(enc_token));
+ enc = enc_buf;
+ } else {
+ enc = messages_get("EncodingUnk");
+ }
+ }
+
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_ICON,
+ icon, true);
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_TITLE,
+ title, true);
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_URL,
+ url, true);
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_ENC,
+ enc, true);
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_TYPE,
+ mime, true);
+}
+
+
+/**
+ * Prepare the object info window for use
+ *
+ * \param *object the object for which information is to be displayed
+ * \param *href corresponding href, if any
+ */
+
+void ro_gui_window_prepare_objectinfo(hlcache_handle *object, const char *href)
+{
+ char icon_buf[20] = "file_xxx";
+ const char *url, *mime;
+ const char *target = "-";
+
+ sprintf(icon_buf, "file_%.3x",
+ ro_content_filetype(object));
+ if (!ro_gui_wimp_sprite_exists(icon_buf))
+ sprintf(icon_buf, "file_xxx");
+
+ url = content_get_url(object);
+ if (url == NULL)
+ url = "-";
+ mime = content_get_mime_type(object);
+ if (mime == NULL)
+ mime = "-";
+
+ if (href)
+ target = href;
+
+ ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_ICON,
+ icon_buf, true);
+ ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_URL,
+ url, true);
+ ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TARGET,
+ target, true);
+ ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TYPE,
+ mime, true);
+}
+
+
+/*
+ * User Actions in the browser window
+ */
+
+/**
+ * Launch a new url in the given window.
+ *
+ * \param g gui_window to update
+ * \param url url to be launched
+ */
+
+void ro_gui_window_launch_url(struct gui_window *g, const char *url)
+{
+ url_func_result res;
+ char *url_norm;
+
+ ro_gui_url_complete_close();
+ res = url_normalize(url, &url_norm);
+ if (res == URL_FUNC_OK) {
+ gui_window_set_url(g, url_norm);
+ browser_window_go(g->bw, url_norm, 0, true);
+ free(url_norm);
+ }
+}
+
+
+/**
+ * Navigate up one level
+ *
+ * \param g the gui_window to open the parent link in
+ * \param url the URL to open the parent of
+ */
+bool ro_gui_window_navigate_up(struct gui_window *g, const char *url) {
+ char *parent;
+ url_func_result res;
+ bool compare;
+
+ if (!g || (!g->bw))
+ return false;
+
+ res = url_parent(url, &parent);
+ if (res == URL_FUNC_OK) {
+ res = url_compare(url, parent, false, &compare);
+ if ((res == URL_FUNC_OK) && !compare)
+ browser_window_go(g->bw, parent, 0, true);
+ free(parent);
+ }
+ return true;
+}
+
+
+/**
+ * Perform a Navigate Home action on a browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_home(struct gui_window *g)
+{
+ char url[80];
+
+ if (g == NULL || g->bw == NULL)
+ return;
+
+ if ((option_homepage_url) && (option_homepage_url[0])) {
+ browser_window_go(g->bw, option_homepage_url, 0, true);
+ } else {
+ snprintf(url, sizeof url,
+ "file:///<NetSurf$Dir>/Docs/welcome/index_%s",
+ option_language);
+ browser_window_go(g->bw, url, 0, true);
+ }
+}
+
+
+/**
+ * Navigate back from a browser window into a new window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_navigate_back_new(struct gui_window *g)
+{
+ struct browser_window *new_bw;
+
+ if (g == NULL || g->bw == NULL)
+ return;
+
+ new_bw = browser_window_create(NULL, g->bw, NULL, false, false);
+
+ if (new_bw != NULL && new_bw->history != NULL)
+ history_back(new_bw, new_bw->history);
+}
+
+
+/**
+ * Navigate forward from a browser window into a new window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_navigate_forward_new(struct gui_window *g)
+{
+ struct browser_window *new_bw;
+
+ if (g == NULL || g->bw == NULL)
+ return;
+
+ new_bw = browser_window_create(NULL, g->bw, NULL, false, false);
+
+ if (new_bw != NULL && new_bw->history != NULL)
+ history_forward(new_bw, new_bw->history);
+}
+
+
+/**
+ * Open a new browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_new_window(struct gui_window *g)
+{
+ if (g == NULL || g->bw == NULL || g->bw->current_content == NULL)
+ return;
+
+ browser_window_create(content_get_url(g->bw->current_content), g->bw,
+ 0, false, false);
+}
+
+
+/**
+ * Open a local history pane for a browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_local_history(struct gui_window *g)
+{
+ if (g != NULL && g->bw != NULL && g->bw->history != NULL)
+ ro_gui_history_open(g->bw, g->bw->history, true);
+}
+
+
+/**
+ * Open a save dialogue for a browser window contents.
+ *
+ * \param *g The browser window to act on.
+ * \param save_type The type of save to open.
+ */
+
+void ro_gui_window_action_save(struct gui_window *g, gui_save_type save_type)
+{
+ if (g == NULL || g->bw == NULL || g->bw->current_content == NULL)
+ return;
+
+ ro_gui_save_prepare(save_type, g->bw->current_content,
+ NULL, NULL, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas, true);
+}
+
+
+/**
+ * Open a text search dialogue for a browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_search(struct gui_window *g)
+{
+ if (g == NULL || g->bw == NULL || g->bw->current_content == NULL ||
+ (content_get_type(g->bw->current_content) !=
+ CONTENT_HTML &&
+ content_get_type(g->bw->current_content) !=
+ CONTENT_TEXTPLAIN))
+ return;
+
+ ro_gui_search_prepare(g->bw);
+ ro_gui_dialog_open_persistent(g->window, dialog_search, true);
+}
+
+
+/**
+ * Open a zoom dialogue for a browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_zoom(struct gui_window *g)
+{
+ if (g == NULL)
+ return;
+
+ ro_gui_dialog_prepare_zoom(g);
+ ro_gui_dialog_open_persistent(g->window, dialog_zoom, true);
+}
+
+
+/**
+ * Add a hotlist entry for a browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_add_bookmark(struct gui_window *g)
+{
+ if (g == NULL || g->bw == NULL || g->bw->current_content == NULL ||
+ content_get_url(g->bw->current_content) == NULL)
+ return;
+
+ hotlist_add_page(content_get_url(g->bw->current_content));
+}
+
+
+/**
+ * Open a print dialogue for a browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_print(struct gui_window *g)
+{
+ if (g == NULL)
+ return;
+
+ ro_gui_print_prepare(g);
+ ro_gui_dialog_open_persistent(g->window, dialog_print, true);
+}
+
+
+/**
+ * Open a page info box for a browser window.
+ *
+ * \param *g The browser window to act on.
+ */
+
+void ro_gui_window_action_page_info(struct gui_window *g)
+{
+ if (g == NULL || g->bw == NULL || g->bw->current_content == NULL)
+ return;
+
+ ro_gui_window_prepare_pageinfo(g);
+ ro_gui_dialog_open_persistent(g->window, dialog_pageinfo, false);
+}
+
+
+/*
+ * Window and Toolbar Redraw and Update
+ */
+
+/**
+ * Redraws the content for all windows.
+ */
+
+void ro_gui_window_redraw_all(void)
+{
+ struct gui_window *g;
+ for (g = window_list; g; g = g->next)
+ gui_window_redraw_window(g);
+}
+
+
+/**
+ * Remove all pending update boxes for a window
+ *
+ * \param g gui_window
+ */
+void ro_gui_window_remove_update_boxes(struct gui_window *g)
+{
+ struct update_box *cur;
+
+ for (cur = pending_updates; cur != NULL; cur = cur->next) {
+ if (cur->g == g)
+ cur->g = NULL;
+ }
+}
+
+
+/**
+ * Redraw any pending update boxes.
+ */
+void ro_gui_window_update_boxes(void)
+{
+ osbool more;
+ bool use_buffer;
+ wimp_draw update;
+ struct rect clip;
+ os_error *error;
+ struct update_box *cur;
+ struct gui_window *g;
+ const union content_msg_data *data;
+
+ for (cur = pending_updates; cur != NULL; cur = cur->next) {
+ g = cur->g;
+ if (!g)
+ continue;
+
+ data = &cur->data;
+ use_buffer = cur->use_buffer;
+
+ update.w = g->window;
+ update.box.x0 = cur->x0;
+ update.box.y0 = cur->y0;
+ update.box.x1 = cur->x1;
+ update.box.y1 = cur->y1;
+
+ error = xwimp_update_window(&update, &more);
+ if (error) {
+ LOG(("xwimp_update_window: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ continue;
+ }
+
+ /* Set the current redraw gui_window to get options from */
+ ro_gui_current_redraw_gui = g;
+ current_redraw_browser = g->bw;
+
+ plot = ro_plotters;
+ ro_plot_origin_x = update.box.x0 - update.xscroll;
+ ro_plot_origin_y = update.box.y1 - update.yscroll;
+ ro_plot_set_scale(g->bw->scale);
+
+ while (more) {
+ clip.x0 = (update.clip.x0 - ro_plot_origin_x) / 2;
+ clip.y0 = (ro_plot_origin_y - update.clip.y1) / 2;
+ clip.x1 = (update.clip.x1 - ro_plot_origin_x) / 2;
+ clip.y1 = (ro_plot_origin_y - update.clip.y0) / 2;
+
+ if (use_buffer)
+ ro_gui_buffer_open(&update);
+
+ browser_window_redraw(g->bw, 0, 0, &clip);
+
+ if (use_buffer)
+ ro_gui_buffer_close();
+
+ error = xwimp_get_rectangle(&update, &more);
+ /* RISC OS 3.7 returns an error here if enough buffer
+ * was claimed to cause a new dynamic area to be
+ * created. It doesn't actually stop anything working,
+ * so we mask it out for now until a better fix is
+ * found. This appears to be a bug in RISC OS. */
+ if (error && !(use_buffer &&
+ error->errnum == error_WIMP_GET_RECT)) {
+ LOG(("xwimp_get_rectangle: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ ro_gui_current_redraw_gui = NULL;
+ current_redraw_browser = NULL;
+ continue;
+ }
+ }
+
+ /* Reset the current redraw gui_window to prevent
+ * thumbnails from retaining options */
+ ro_gui_current_redraw_gui = NULL;
+ current_redraw_browser = NULL;
+ }
+ while (pending_updates) {
+ cur = pending_updates;
+ pending_updates = pending_updates->next;
+ free(cur);
+ }
+}
+
+
/**
* Process pending reformats
*/
@@ -2934,6 +4465,237 @@ void ro_gui_window_process_reformats(void)
/**
+ * Destroy all browser windows.
+ */
+
+void ro_gui_window_quit(void)
+{
+ struct gui_window *cur;
+
+ while (window_list) {
+ cur = window_list;
+ window_list = window_list->next;
+
+ /* framesets and iframes are destroyed by their parents */
+ if (!cur->bw->parent)
+ browser_window_destroy(cur->bw);
+ }
+}
+
+
+/**
+ * Animate the "throbbers" of all browser windows.
+ */
+
+void ro_gui_throb(void)
+{
+ struct gui_window *g;
+ struct browser_window *top;
+
+ for (g = window_list; g; g = g->next) {
+ if (!g->bw->throbbing)
+ continue;
+ for (top = g->bw; top->parent; top = top->parent);
+ if (top->window != NULL && top->window->toolbar != NULL)
+ ro_toolbar_throb(top->window->toolbar);
+ }
+}
+
+
+/**
+ * Update the toolbar buttons for a given browser window to reflect the
+ * current state of its contents.
+ *
+ * Note that the parameters to this function are arranged so that it can be
+ * supplied to the toolbar module as an button state update callback.
+ *
+ * \param *g The browser window to update.
+ */
+
+void ro_gui_window_update_toolbar_buttons(struct gui_window *g)
+{
+ struct browser_window *bw;
+ hlcache_handle *h;
+ struct toolbar *toolbar;
+
+ if (g == NULL || g->toolbar == NULL)
+ return;
+
+ bw = g->bw;
+ h = bw->current_content;
+ toolbar = g->toolbar;
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_RELOAD,
+ !browser_window_reload_available(bw));
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_STOP,
+ !browser_window_stop_available(bw));
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_BACK,
+ !browser_window_back_available(bw));
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_FORWARD,
+ !browser_window_forward_available(bw));
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_UP,
+ !ro_gui_window_up_available(bw));
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SEARCH,
+ h == NULL || (content_get_type(h) != CONTENT_HTML &&
+ content_get_type(h) != CONTENT_TEXTPLAIN));
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SCALE,
+ h == NULL);
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_PRINT,
+ h == NULL);
+
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SAVE_SOURCE,
+ h == NULL);
+
+ ro_toolbar_update_urlsuggest(toolbar);
+}
+
+
+/**
+ * Update a window to reflect a change in toolbar size: used as a callback by
+ * the toolbar module when a toolbar height changes.
+ *
+ * \param *data void pointer the window's gui_window struct
+ */
+
+void ro_gui_window_update_toolbar(void *data)
+{
+ struct gui_window *g = (struct gui_window *) data;
+
+ if (g != NULL)
+ gui_window_update_extent(g);
+}
+
+
+/**
+ * Save a new toolbar button configuration: used as a callback by the toolbar
+ * module when a buttonbar edit has finished.
+ *
+ * \param *data void pointer to the window's gui_window struct
+ * \param *config pointer to a malloc()'d button config string.
+ */
+
+void ro_gui_window_save_toolbar_buttons(void *data, char *config)
+{
+ if (option_toolbar_browser != NULL)
+ free(option_toolbar_browser);
+ option_toolbar_browser = config;
+ ro_gui_save_options();
+}
+
+
+/**
+ * Update a window and its toolbar to reflect a new theme: used as a callback
+ * by the toolbar module when a theme change affects a toolbar.
+ *
+ * \param *data void pointer to the window's gui_window struct
+ * \param ok true if the bar still exists; else false.
+ */
+
+void ro_gui_window_update_theme(void *data, bool ok)
+{
+ struct gui_window *g = (struct gui_window *) data;
+
+ if (g != NULL && g->toolbar != NULL) {
+ if (ok) {
+ gui_window_update_extent(g);
+ } else {
+ g->toolbar = NULL;
+ }
+ }
+}
+
+
+/*
+ * General Window Support
+ */
+
+/**
+ * Import text file into window or its toolbar
+ *
+ * \param g gui window containing textarea
+ * \param filename pathname of file to be imported
+ * \param toolbar true iff imported to toolbar rather than main window
+ * \return true iff successful
+ */
+
+bool ro_gui_window_import_text(struct gui_window *g, const char *filename,
+ bool toolbar)
+{
+ fileswitch_object_type obj_type;
+ os_error *error;
+ char *buf, *utf8_buf;
+ int size;
+ utf8_convert_ret ret;
+
+ error = xosfile_read_stamped(filename, &obj_type, NULL, NULL,
+ &size, NULL, NULL);
+ if (error) {
+ LOG(("xosfile_read_stamped: 0x%x:%s",
+ error->errnum, error->errmess));
+ warn_user("FileError", error->errmess);
+ return true; /* was for us, but it didn't work! */
+ }
+
+ buf = malloc(size);
+ if (!buf) {
+ warn_user("NoMemory", NULL);
+ return true;
+ }
+
+ error = xosfile_load_stamped(filename, (byte*)buf,
+ NULL, NULL, NULL, NULL, NULL);
+ if (error) {
+ LOG(("xosfile_load_stamped: 0x%x:%s",
+ error->errnum, error->errmess));
+ warn_user("LoadError", error->errmess);
+ free(buf);
+ return true;
+ }
+
+ ret = utf8_from_local_encoding(buf, size, &utf8_buf);
+ if (ret != UTF8_CONVERT_OK) {
+ /* bad encoding shouldn't happen */
+ assert(ret != UTF8_CONVERT_BADENC);
+ LOG(("utf8_from_local_encoding failed"));
+ free(buf);
+ warn_user("NoMemory", NULL);
+ return true;
+ }
+ size = strlen(utf8_buf);
+
+ if (toolbar) {
+ const char *ep = utf8_buf + size;
+ const char *sp;
+ char *p = utf8_buf;
+
+ /* skip leading whitespace */
+ while (isspace(*p)) p++;
+
+ sp = p;
+ while (*p && *p != '\r' && *p != '\n')
+ p += utf8_next(p, ep - p, 0);
+ *p = '\0';
+
+ if (p > sp)
+ ro_gui_window_launch_url(g, sp);
+ }
+ else
+ browser_window_paste_text(g->bw, utf8_buf, size, true);
+
+ free(buf);
+ free(utf8_buf);
+ return true;
+}
+
+
+/**
* Clones a browser window's options.
*
* \param new_bw the new browser window
@@ -2941,7 +4703,8 @@ void ro_gui_window_process_reformats(void)
*/
void ro_gui_window_clone_options(struct browser_window *new_bw,
- struct browser_window *old_bw) {
+ struct browser_window *old_bw)
+{
struct gui_window *old_gui = NULL;
struct gui_window *new_gui;
@@ -2968,15 +4731,23 @@ void ro_gui_window_clone_options(struct browser_window *new_bw,
/* Set up the toolbar
*/
if (new_gui->toolbar) {
- new_gui->toolbar->display_buttons = option_toolbar_show_buttons;
- new_gui->toolbar->display_url = option_toolbar_show_address;
- new_gui->toolbar->display_throbber = option_toolbar_show_throbber;
+ ro_toolbar_set_display_buttons(new_gui->toolbar,
+ option_toolbar_show_buttons);
+ ro_toolbar_set_display_url(new_gui->toolbar,
+ option_toolbar_show_address);
+ ro_toolbar_set_display_throbber(new_gui->toolbar,
+ option_toolbar_show_throbber);
if ((old_gui) && (old_gui->toolbar)) {
- new_gui->toolbar->display_buttons = old_gui->toolbar->display_buttons;
- new_gui->toolbar->display_url = old_gui->toolbar->display_url;
- new_gui->toolbar->display_throbber = old_gui->toolbar->display_throbber;
- new_gui->toolbar->reformat_buttons = true;
- ro_gui_theme_process_toolbar(new_gui->toolbar, -1);
+ ro_toolbar_set_display_buttons(new_gui->toolbar,
+ ro_toolbar_get_display_buttons(
+ old_gui->toolbar));
+ ro_toolbar_set_display_url(new_gui->toolbar,
+ ro_toolbar_get_display_url(
+ old_gui->toolbar));
+ ro_toolbar_set_display_throbber(new_gui->toolbar,
+ ro_toolbar_get_display_throbber(
+ old_gui->toolbar));
+ ro_toolbar_process(new_gui->toolbar, -1, true);
}
}
}
@@ -2988,7 +4759,8 @@ void ro_gui_window_clone_options(struct browser_window *new_bw,
* \param bw the browser window to read options from
*/
-void ro_gui_window_default_options(struct browser_window *bw) {
+void ro_gui_window_default_options(struct browser_window *bw)
+{
struct gui_window *gui;
assert(bw);
@@ -3006,33 +4778,277 @@ void ro_gui_window_default_options(struct browser_window *bw) {
/* Set up the toolbar
*/
- if (gui->toolbar) {
- option_toolbar_show_buttons = gui->toolbar->display_buttons;
- option_toolbar_show_address = gui->toolbar->display_url;
- option_toolbar_show_throbber = gui->toolbar->display_throbber;
+ if (gui->toolbar != NULL) {
+ option_toolbar_show_buttons =
+ ro_toolbar_get_display_buttons(gui->toolbar);
+ option_toolbar_show_address =
+ ro_toolbar_get_display_url(gui->toolbar);
+ option_toolbar_show_throbber =
+ ro_toolbar_get_display_throbber(gui->toolbar);
}
- if (gui->status_bar)
- option_toolbar_status_width = ro_gui_status_bar_get_width(gui->status_bar);
+ if (gui->status_bar != NULL)
+ option_toolbar_status_width =
+ ro_gui_status_bar_get_width(gui->status_bar);
}
+/*
+ * Custom Menu Support
+ */
+/**
+ * Prepare or reprepare a form select menu, setting up the menu handle
+ * global in the process.
+ *
+ * \param *bw The browser window to contain the menu.
+ * \param *control The form control needing a menu.
+ * \return true if the menu is OK to be opened; else false.
+ */
+
+bool ro_gui_window_prepare_form_select_menu(struct browser_window *bw,
+ struct form_control *control)
+{
+ unsigned int i, entries;
+ char *text_convert, *temp;
+ struct form_option *option;
+ bool reopen = true;
+ utf8_convert_ret err;
+
+ assert(control);
+
+ for (entries = 0, option = control->data.select.items; option;
+ option = option->next)
+ entries++;
+ if (entries == 0) {
+ ro_gui_menu_closed();
+ return false;
+ }
+
+ if ((gui_form_select_menu) && (control != gui_form_select_control)) {
+ for (i = 0; ; i++) {
+ free(gui_form_select_menu->entries[i].data.
+ indirected_text.text);
+ if (gui_form_select_menu->entries[i].menu_flags &
+ wimp_MENU_LAST)
+ break;
+ }
+ free(gui_form_select_menu->title_data.indirected_text.text);
+ free(gui_form_select_menu);
+ gui_form_select_menu = 0;
+ }
+
+ if (!gui_form_select_menu) {
+ reopen = false;
+ gui_form_select_menu = malloc(wimp_SIZEOF_MENU(entries));
+ if (!gui_form_select_menu) {
+ warn_user("NoMemory", 0);
+ ro_gui_menu_closed();
+ return false;
+ }
+ err = utf8_to_local_encoding(messages_get("SelectMenu"), 0,
+ &text_convert);
+ if (err != UTF8_CONVERT_OK) {
+ /* badenc should never happen */
+ assert(err != UTF8_CONVERT_BADENC);
+ LOG(("utf8_to_local_encoding failed"));
+ warn_user("NoMemory", 0);
+ ro_gui_menu_closed();
+ return false;
+ }
+ gui_form_select_menu->title_data.indirected_text.text =
+ text_convert;
+ ro_gui_menu_init_structure(gui_form_select_menu, entries);
+ }
+
+ for (i = 0, option = control->data.select.items; option;
+ i++, option = option->next) {
+ gui_form_select_menu->entries[i].menu_flags = 0;
+ if (option->selected)
+ gui_form_select_menu->entries[i].menu_flags =
+ wimp_MENU_TICKED;
+ if (!reopen) {
+
+ /* convert spaces to hard spaces to stop things
+ * like 'Go Home' being treated as if 'Home' is a
+ * keyboard shortcut and right aligned in the menu.
+ */
+
+ temp = cnv_space2nbsp(option->text);
+ if (!temp) {
+ LOG(("cnv_space2nbsp failed"));
+ warn_user("NoMemory", 0);
+ ro_gui_menu_closed();
+ return false;
+ }
+
+ err = utf8_to_local_encoding(temp,
+ 0, &text_convert);
+ if (err != UTF8_CONVERT_OK) {
+ /* A bad encoding should never happen,
+ * so assert this */
+ assert(err != UTF8_CONVERT_BADENC);
+ LOG(("utf8_to_enc failed"));
+ warn_user("NoMemory", 0);
+ ro_gui_menu_closed();
+ return false;
+ }
+
+ free(temp);
+
+ gui_form_select_menu->entries[i].data.indirected_text.text =
+ text_convert;
+ gui_form_select_menu->entries[i].data.indirected_text.size =
+ strlen(gui_form_select_menu->entries[i].
+ data.indirected_text.text) + 1;
+ }
+ }
+
+ gui_form_select_menu->entries[0].menu_flags |=
+ wimp_MENU_TITLE_INDIRECTED;
+ gui_form_select_menu->entries[i - 1].menu_flags |= wimp_MENU_LAST;
+
+ return true;
+}
/**
- * Updates the navigation controls for all toolbars;
+ * Process selections from a form select menu, passing them back to the core.
*
- * \param g the gui_window to launch the URL into
- * \param url the URL to launch, or NULL to simply update the suggestion icon
+ * \param *g The browser window affected by the menu.
+ * \param *selection The menu selection.
*/
-void ro_gui_window_prepare_navigate_all(void) {
- struct gui_window *g;
+void ro_gui_window_process_form_select_menu(struct gui_window *g,
+ wimp_selection *selection)
+{
+ assert(g != NULL);
+
+ if (selection->items[0] >= 0)
+ form_select_process_selection(g->bw->current_content,
+ gui_form_select_control,
+ selection->items[0]);
+}
+
+
+/*
+ * Window and Toolbar Lookup
+ */
+
+/**
+ * Convert a RISC OS window handle to a gui_window.
+ *
+ * \param w RISC OS window handle
+ * \return pointer to a structure if found, 0 otherwise
+ */
+
+struct gui_window *ro_gui_window_lookup(wimp_w window)
+{
+ struct gui_window *g;
for (g = window_list; g; g = g->next)
- ro_gui_prepare_navigate(g);
+ if (g->window == window)
+ return g;
+ return 0;
}
/**
+ * Convert a toolbar RISC OS window handle to a gui_window.
+ *
+ * \param w RISC OS window handle of a toolbar
+ * \return pointer to a structure if found, 0 otherwise
+ */
+
+struct gui_window *ro_gui_toolbar_lookup(wimp_w window)
+{
+ struct gui_window *g = NULL;
+ struct toolbar *toolbar;
+ wimp_w parent;
+
+ toolbar = ro_toolbar_window_lookup(window);
+
+ if (toolbar != NULL) {
+ parent = ro_toolbar_get_parent_window(toolbar);
+ g = ro_gui_window_lookup(parent);
+ }
+
+ return g;
+}
+
+
+/*
+ * Core to RISC OS Conversions
+ */
+
+/**
+ * Convert x,y screen co-ordinates into window co-ordinates.
+ *
+ * \param g gui window
+ * \param x x ordinate
+ * \param y y ordinate
+ * \param pos receives position in window co-ordinatates
+ * \return true iff conversion successful
+ */
+
+bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y,
+ os_coord *pos)
+{
+ wimp_window_state state;
+ os_error *error;
+
+ assert(g);
+
+ state.w = g->window;
+ 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;
+ }
+ pos->x = (x - (state.visible.x0 - state.xscroll)) / 2 / g->bw->scale;
+ pos->y = ((state.visible.y1 - state.yscroll) - y) / 2 / g->bw->scale;
+ return true;
+}
+
+
+/**
+ * Convert x,y window co-ordinates into screen co-ordinates.
+ *
+ * \param g gui window
+ * \param x x ordinate
+ * \param y y ordinate
+ * \param pos receives position in screen co-ordinatates
+ * \return true iff conversion successful
+ */
+
+bool ro_gui_window_to_screen_pos(struct gui_window *g, int x, int y,
+ os_coord *pos)
+{
+ wimp_window_state state;
+ os_error *error;
+
+ assert(g);
+
+ state.w = g->window;
+ 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;
+ }
+ pos->x = (x * 2 * g->bw->scale) + (state.visible.x0 - state.xscroll);
+ pos->y = (state.visible.y1 - state.yscroll) - (y * 2 * g->bw->scale);
+ return true;
+}
+
+
+/*
+ * Miscellaneous Functions
+ *
+ * \TODO -- These items might well belong elsewhere.
+ */
+
+/**
* Returns the state of the mouse buttons and modifiers keys for a
* mouse action, suitable for passing to the OS-independent
* browser window/ treeview/ etc code.
@@ -3099,6 +5115,7 @@ browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons,
return state;
}
+
/**
* Returns the state of the mouse buttons and modifiers keys whilst
* dragging, for passing to the OS-independent browser window/ treeview/
@@ -3173,295 +5190,3 @@ bool ro_gui_alt_pressed(void)
return (alt == 0xff);
}
-
-/**
- * Completes scrolling of a browser window
- *
- * \param g gui window
- */
-
-void ro_gui_window_scroll_end(struct gui_window *g, wimp_dragged *drag)
-{
- wimp_pointer pointer;
- os_error *error;
- os_coord pos;
-
- gui_current_drag_type = GUI_DRAG_NONE;
- if (!g)
- return;
-
- error = xwimp_drag_box((wimp_drag*)-1);
- if (error) {
- LOG(("xwimp_drag_box: 0x%x : %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
-
- 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;
- }
-
- error = xwimpspriteop_set_pointer_shape("ptr_default", 0x31, 0, 0, 0, 0);
- if (error) {
- LOG(("xwimpspriteop_set_pointer_shape: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
-
- if (ro_gui_window_to_window_pos(g, drag->final.x0, drag->final.y0, &pos))
- browser_window_mouse_drag_end(g->bw,
- ro_gui_mouse_click_state(pointer.buttons,
- wimp_BUTTON_CLICK_DRAG),
- pos.x, pos.y);
-}
-
-
-/**
- * Completes resizing of a browser frame
- *
- * \param g gui window
- */
-
-void ro_gui_window_frame_resize_end(struct gui_window *g, wimp_dragged *drag)
-{
- /* our clean-up is the same as for page scrolling */
- ro_gui_window_scroll_end(g, drag);
-}
-
-/**
- * Import text file into window or its toolbar
- *
- * \param g gui window containing textarea
- * \param filename pathname of file to be imported
- * \param toolbar true iff imported to toolbar rather than main window
- * \return true iff successful
- */
-
-bool ro_gui_window_import_text(struct gui_window *g, const char *filename,
- bool toolbar)
-{
- fileswitch_object_type obj_type;
- os_error *error;
- char *buf, *utf8_buf;
- int size;
- utf8_convert_ret ret;
-
- error = xosfile_read_stamped(filename, &obj_type, NULL, NULL,
- &size, NULL, NULL);
- if (error) {
- LOG(("xosfile_read_stamped: 0x%x:%s",
- error->errnum, error->errmess));
- warn_user("FileError", error->errmess);
- return true; /* was for us, but it didn't work! */
- }
-
- buf = malloc(size);
- if (!buf) {
- warn_user("NoMemory", NULL);
- return true;
- }
-
- error = xosfile_load_stamped(filename, (byte*)buf,
- NULL, NULL, NULL, NULL, NULL);
- if (error) {
- LOG(("xosfile_load_stamped: 0x%x:%s",
- error->errnum, error->errmess));
- warn_user("LoadError", error->errmess);
- free(buf);
- return true;
- }
-
- ret = utf8_from_local_encoding(buf, size, &utf8_buf);
- if (ret != UTF8_CONVERT_OK) {
- /* bad encoding shouldn't happen */
- assert(ret != UTF8_CONVERT_BADENC);
- LOG(("utf8_from_local_encoding failed"));
- free(buf);
- warn_user("NoMemory", NULL);
- return true;
- }
- size = strlen(utf8_buf);
-
- if (toolbar) {
- const char *ep = utf8_buf + size;
- const char *sp;
- char *p = utf8_buf;
-
- /* skip leading whitespace */
- while (isspace(*p)) p++;
-
- sp = p;
- while (*p && *p != '\r' && *p != '\n')
- p += utf8_next(p, ep - p, 0);
- *p = '\0';
-
- if (p > sp)
- ro_gui_window_launch_url(g, sp);
- }
- else
- browser_window_paste_text(g->bw, utf8_buf, size, true);
-
- free(buf);
- free(utf8_buf);
- return true;
-}
-
-
-/**
- * Window is being iconised. Create a suitable thumbnail sprite
- * (which, sadly, must be in the Wimp sprite pool), and return
- * the sprite name and truncated title to the iconiser
- *
- * \param g the gui window being iconised
- * \param wi the WindowInfo message from the iconiser
- */
-
-void ro_gui_window_iconise(struct gui_window *g,
- wimp_full_message_window_info *wi)
-{
- /* sadly there is no 'legal' way to get the sprite into
- * the Wimp sprite pool other than via a filing system */
- const char *temp_fname = "Pipe:$._tmpfile";
- struct browser_window *bw = g->bw;
- osspriteop_header *overlay = NULL;
- osspriteop_header *sprite_header;
- struct bitmap *bitmap;
- osspriteop_area *area;
- int width = 34, height = 34;
- hlcache_handle *h;
- os_error *error;
- int len, id;
-
- assert(bw);
-
- h = bw->current_content;
- if (!h) return;
-
- /* if an overlay sprite is defined, locate it and gets its dimensions
- * so that we can produce a thumbnail with the same dimensions */
- if (!ro_gui_wimp_get_sprite("ic_netsfxx", &overlay)) {
- error = xosspriteop_read_sprite_info(osspriteop_PTR,
- (osspriteop_area *)0x100,
- (osspriteop_id)overlay, &width, &height, NULL,
- NULL);
- if (error) {
- LOG(("xosspriteop_read_sprite_info: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("MiscError", error->errmess);
- overlay = NULL;
- }
- else if (sprite_bpp(overlay) != 8) {
- LOG(("overlay sprite is not 8bpp"));
- overlay = NULL;
- }
- }
-
- /* create the thumbnail sprite */
- bitmap = bitmap_create(width, height, BITMAP_NEW | BITMAP_OPAQUE |
- BITMAP_CLEAR_MEMORY);
- if (!bitmap) {
- LOG(("Thumbnail initialisation failed."));
- return;
- }
- thumbnail_create(h, bitmap, NULL);
- if (overlay)
- bitmap_overlay_sprite(bitmap, overlay);
- area = thumbnail_convert_8bpp(bitmap);
- bitmap_destroy(bitmap);
- if (!area) {
- LOG(("Thumbnail conversion failed."));
- return;
- }
-
- /* choose a suitable sprite name */
- id = 0;
- while (iconise_used[id])
- if ((unsigned)++id >= NOF_ELEMENTS(iconise_used)) {
- id = iconise_next;
- if ((unsigned)++iconise_next >=
- NOF_ELEMENTS(iconise_used))
- iconise_next = 0;
- break;
- }
-
- sprite_header = (osspriteop_header *)(area + 1);
- len = sprintf(sprite_header->name, "ic_netsf%.2d", id);
-
- error = xosspriteop_save_sprite_file(osspriteop_USER_AREA,
- area, temp_fname);
- if (error) {
- LOG(("xosspriteop_save_sprite_file: 0x%x:%s",
- error->errnum, error->errmess));
- warn_user("MiscError", error->errmess);
- free(area);
- return;
- }
-
- error = xwimpspriteop_merge_sprite_file(temp_fname);
- if (error) {
- LOG(("xwimpspriteop_merge_sprite_file: 0x%x:%s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- remove(temp_fname);
- free(area);
- return;
- }
-
- memcpy(wi->sprite_name, sprite_header->name + 3, len - 2); /* inc NUL */
- strncpy(wi->title, g->title, sizeof(wi->title));
- wi->title[sizeof(wi->title) - 1] = '\0';
-
- if (wimptextop_string_width(wi->title, 0) > 182) {
- /* work around bug in Pinboard where it will fail to display
- * the icon if the text is very wide */
- if (strlen(wi->title) > 10)
- wi->title[10] = '\0'; /* pinboard does this anyway */
- while (wimptextop_string_width(wi->title, 0) > 182)
- wi->title[strlen(wi->title) - 1] = '\0';
- }
-
- wi->size = sizeof(wimp_full_message_window_info);
- wi->your_ref = wi->my_ref;
- error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message*)wi,
- wi->sender);
- if (error) {
- LOG(("xwimp_send_message: 0x%x:%s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- }
- else {
- g->iconise_icon = id;
- iconise_used[id] = true;
- }
-
- free(area);
-}
-
-
-/**
- * Navigate up one level
- *
- * \param g the gui_window to open the parent link in
- * \param url the URL to open the parent of
- */
-bool ro_gui_window_navigate_up(struct gui_window *g, const char *url) {
- char *parent;
- url_func_result res;
- bool compare;
-
- if (!g || (!g->bw))
- return false;
-
- res = url_parent(url, &parent);
- if (res == URL_FUNC_OK) {
- res = url_compare(url, parent, false, &compare);
- if ((res == URL_FUNC_OK) && !compare)
- browser_window_go(g->bw, parent, 0, true);
- free(parent);
- }
- return true;
-}
diff --git a/riscos/window.h b/riscos/window.h
new file mode 100644
index 000000000..adbd999f9
--- /dev/null
+++ b/riscos/window.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010, 2011 Stephen Fryatt <stevef@netsurf-browser.org>
+ *
+ * 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
+ * Browser window handling (interface).
+ */
+
+#include <stdbool.h>
+
+#ifndef _NETSURF_RISCOS_WINDOW_H_
+#define _NETSURF_RISCOS_WINDOW_H_
+
+void ro_gui_window_initialise(void);
+
+bool ro_gui_window_check_menu(wimp_menu *menu);
+
+#endif
+