summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--!NetSurf/!Sprites22,ff9bin13020 -> 19724 bytes
-rw-r--r--!NetSurf/Resources/en/Templates,fecbin8908 -> 8908 bytes
-rw-r--r--!NetSurf/Resources/fr/Templates,fecbin9042 -> 9042 bytes
-rw-r--r--makefile2
-rw-r--r--riscos.mk2
-rw-r--r--riscos/dialog.c406
-rw-r--r--riscos/gui.c39
-rw-r--r--riscos/gui.h10
-rw-r--r--riscos/help.c2
-rw-r--r--riscos/hotlist.c4
-rw-r--r--riscos/htmlredraw.c2
-rw-r--r--riscos/menus.c42
-rw-r--r--riscos/options.h4
-rw-r--r--riscos/theme.c1451
-rw-r--r--riscos/theme.h108
-rw-r--r--riscos/wimp.c22
-rw-r--r--riscos/wimp.h4
-rw-r--r--riscos/window.c157
18 files changed, 1595 insertions, 660 deletions
diff --git a/!NetSurf/!Sprites22,ff9 b/!NetSurf/!Sprites22,ff9
index 1aba72e95..80372b3ae 100644
--- a/!NetSurf/!Sprites22,ff9
+++ b/!NetSurf/!Sprites22,ff9
Binary files differ
diff --git a/!NetSurf/Resources/en/Templates,fec b/!NetSurf/Resources/en/Templates,fec
index 8f637ae40..01a9280bd 100644
--- a/!NetSurf/Resources/en/Templates,fec
+++ b/!NetSurf/Resources/en/Templates,fec
Binary files differ
diff --git a/!NetSurf/Resources/fr/Templates,fec b/!NetSurf/Resources/fr/Templates,fec
index 14aa4b72c..eed7972f6 100644
--- a/!NetSurf/Resources/fr/Templates,fec
+++ b/!NetSurf/Resources/fr/Templates,fec
Binary files differ
diff --git a/makefile b/makefile
index 31489ee10..ecefa1770 100644
--- a/makefile
+++ b/makefile
@@ -31,7 +31,7 @@ OBJECTS_RISCOS += 401login.o debugwin.o \
jpeg.o menus.o mng.o mouseactions.o plugin.o print.o \
save.o save_complete.o save_draw.o save_text.o \
schedule.o search.o sprite.o textselection.o theme.o thumbnail.o \
- toolbar.o ufont.o uri.o url_protocol.o wimp.o window.o # riscos/
+ ufont.o uri.o url_protocol.o wimp.o window.o # riscos/
# OBJECTS_RISCOS += memdebug.o
OBJECTS_NCOS = $(OBJECTS_RISCOS)
diff --git a/riscos.mk b/riscos.mk
index 65aac2a8f..36e7ceae5 100644
--- a/riscos.mk
+++ b/riscos.mk
@@ -6,7 +6,7 @@ PLATFORM_CFLAGS_DEBUG = -INSLibs:include -IOSLib:
LDFLAGS_RISCOS = NSLibs:lib/libxml2 NSLibs:lib/libz NSLibs:lib/libcurl \
NSLibs:lib/libssl NSLibs:lib/libcrypto NSLibs:lib/libares \
- NSLibs:lib/libmng NSLibs:lib/liblcms NSLibs:lib/libjpeg OSLib:o.oslib32
+ NSLibs:lib/libmng NSLibs:lib/libjpeg OSLib:o.oslib32
LDFLAGS_SMALL = NSLibs:lib/libxml2 NSLibs:lib/libz NSLibs:lib/libcurl \
NSLibs:lib/libares NSLibs:lib/libmng \
NSLibs:lib/libjpeg OSLib:o.oslib32
diff --git a/riscos/dialog.c b/riscos/dialog.c
index 04782f532..943954b8d 100644
--- a/riscos/dialog.c
+++ b/riscos/dialog.c
@@ -32,6 +32,8 @@
*/
#define MAX_PERSISTANT 8
+
+
wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br,
dialog_config_prox, dialog_config_th, download_template,
#ifdef WITH_AUTH
@@ -45,17 +47,30 @@ static int ro_gui_choices_font_size;
static int ro_gui_choices_font_min_size;
static bool ro_gui_choices_http_proxy;
static int ro_gui_choices_http_proxy_auth;
-static char *theme_choice = 0;
-static struct theme_entry *theme_list = 0;
-static unsigned int theme_list_entries = 0;
static int config_br_icon = -1;
static const char *ro_gui_choices_lang = 0;
static const char *ro_gui_choices_alang = 0;
+
+struct toolbar_display {
+ struct toolbar *toolbar;
+ struct theme_descriptor *descriptor;
+ int icon_number;
+ struct toolbar_display *next;
+};
+
+static struct theme_descriptor *theme_choice = NULL;
+static struct theme_descriptor *theme_list = NULL;
+static int theme_count = 0;
+static struct toolbar_display *toolbars = NULL;
+static char theme_radio_validation[] = "Sradiooff,radioon\0";
+
+
static const char *ro_gui_proxy_auth_name[] = {
"ProxyNone", "ProxyBasic", "ProxyNTLM"
};
+
/* A simple mapping of parent and child
*/
static struct {
@@ -72,12 +87,14 @@ static void ro_gui_dialog_click_config_prox(wimp_pointer *pointer);
static void ro_gui_dialog_config_proxy_update(void);
static void ro_gui_dialog_click_config_th(wimp_pointer *pointer);
static void ro_gui_dialog_click_config_th_pane(wimp_pointer *pointer);
-static void ro_gui_redraw_config_th_pane_plot(wimp_draw *redraw);
static void ro_gui_dialog_click_zoom(wimp_pointer *pointer);
static void ro_gui_dialog_reset_zoom(void);
static void ro_gui_dialog_click_warning(wimp_pointer *pointer);
static const char *language_name(const char *code);
-static struct theme_entry *ro_gui_theme_entry(int index);
+
+static void ro_gui_dialog_load_themes(void);
+static void ro_gui_dialog_free_themes(void);
+
/**
* Load and create dialogs from template file.
@@ -483,13 +500,8 @@ void ro_gui_dialog_config_prepare(void)
ro_gui_dialog_config_proxy_update();
/* themes pane */
- free(theme_choice);
- theme_choice = 0;
- if (option_theme)
- theme_choice = strdup(option_theme);
- if (theme_list)
- ro_theme_free(theme_list);
- theme_list = ro_theme_list(&theme_list_entries);
+ ro_gui_dialog_load_themes();
+ theme_choice = ro_gui_theme_find(option_theme);
}
@@ -497,8 +509,7 @@ void ro_gui_dialog_config_prepare(void)
* Set the current options to the settings in the choices panes.
*/
-void ro_gui_dialog_config_set(void)
-{
+void ro_gui_dialog_config_set(void) {
/* browser pane */
option_font_size = ro_gui_choices_font_size;
option_font_min_size = ro_gui_choices_font_min_size;
@@ -537,8 +548,14 @@ void ro_gui_dialog_config_set(void)
ICON_CONFIG_PROX_AUTHPASS));
/* theme pane */
- free(option_theme);
- option_theme = strdup(theme_choice);
+ if (option_theme) {
+ free(option_theme);
+ option_theme = NULL;
+ }
+ if (theme_choice) {
+ option_theme = strdup(theme_choice->filename);
+ ro_gui_theme_apply(theme_choice);
+ }
}
@@ -554,16 +571,16 @@ void ro_gui_dialog_click_config(wimp_pointer *pointer)
ro_gui_save_options();
if (pointer->buttons == wimp_CLICK_SELECT) {
ro_gui_dialog_close(dialog_config);
- if (theme_list) {
- ro_theme_free(theme_list);
- theme_list = 0;
- }
+ ro_gui_dialog_free_themes();
}
break;
case ICON_CONFIG_CANCEL:
- if (pointer->buttons == wimp_CLICK_SELECT)
+ if (pointer->buttons == wimp_CLICK_SELECT) {
ro_gui_dialog_close(dialog_config);
- ro_gui_dialog_config_prepare();
+ ro_gui_dialog_free_themes();
+ } else {
+ ro_gui_dialog_config_prepare();
+ }
break;
case ICON_CONFIG_BROWSER:
/* set selected state of radio icon to prevent
@@ -809,172 +826,24 @@ void ro_gui_dialog_click_config_th(wimp_pointer *pointer)
/**
* Handle clicks in the scrolling Theme Choices list pane.
*/
+void ro_gui_dialog_click_config_th_pane(wimp_pointer *pointer) {
+ struct toolbar_display *link;
+ int i = pointer->i;
+ if (i < 0) return;
-void ro_gui_dialog_click_config_th_pane(wimp_pointer *pointer)
-{
- unsigned int i, y;
- wimp_window_state state;
- os_error *error;
-
- state.w = dialog_config_th_pane;
- 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;
- }
-
- y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) /
- THEME_HEIGHT;
-
- if (!theme_list || theme_list_entries <= y)
- return;
-
- if (theme_choice && strcmp(theme_choice, ro_gui_theme_entry(y)->name) == 0)
- return;
-
- if (theme_choice) {
- for (i = 0; i != theme_list_entries &&
- strcmp(theme_choice, ro_gui_theme_entry(i)->name); i++)
- ;
- if (i != theme_list_entries) {
- error = xwimp_force_redraw(dialog_config_th_pane,
- 0, -i * THEME_HEIGHT - THEME_HEIGHT - 2,
- THEME_WIDTH, -i * THEME_HEIGHT + 2);
- if (error) {
- LOG(("xwimp_force_redraw: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- return;
- }
- }
- }
-
- free(theme_choice);
- theme_choice = strdup(ro_gui_theme_entry(y)->name);
-
- error = xwimp_force_redraw(dialog_config_th_pane,
- 0, -y * THEME_HEIGHT - THEME_HEIGHT - 2,
- THEME_WIDTH, -y * THEME_HEIGHT + 2);
- if (error) {
- LOG(("xwimp_force_redraw: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
- return;
- }
-}
-
-struct theme_entry *ro_gui_theme_entry(int index) {
- struct theme_entry *entry = theme_list;
- for (int i = 0; i < index; i++) entry = entry->next;
- return entry;
-}
-
-/**
- * Redraw the scrolling Theme Choices list pane.
- */
-
-void ro_gui_redraw_config_th_pane(wimp_draw *redraw)
-{
- osbool more;
- os_error *error;
-
- 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_gui_redraw_config_th_pane_plot(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;
- }
- }
-}
-
-
-/**
- * Redraw the scrolling Theme Choices list pane.
- */
-
-void ro_gui_redraw_config_th_pane_plot(wimp_draw *redraw)
-{
- unsigned int i, j;
- int x0 = redraw->box.x0 - redraw->xscroll;
- int y0 = redraw->box.y1 - redraw->yscroll;
- int x;
- static char sprite[][10] = { "back", "forward", "stop", "reload",
- "history", "scale", "save" };
- wimp_icon icon;
- os_error *error = 0;
-
- icon.flags = wimp_ICON_SPRITE | wimp_ICON_HCENTRED |
- wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED;
-
- for (i = 0; i != theme_list_entries; i++) {
- error = xwimptextop_set_colour(os_COLOUR_BLACK,
- os_COLOUR_VERY_LIGHT_GREY);
- if (error)
- break;
-
- /* plot background for selected theme */
- if (theme_choice &&
- strcmp(ro_gui_theme_entry(i)->name, theme_choice) == 0) {
- error = xcolourtrans_set_gcol(os_COLOUR_LIGHT_GREY,
- 0, os_ACTION_OVERWRITE, 0, 0);
- if (error)
- break;
- error = xos_plot(os_MOVE_TO, x0, y0 - i * THEME_HEIGHT);
- if (error)
- break;
- error = xos_plot(os_PLOT_RECTANGLE | os_PLOT_BY,
- THEME_WIDTH, -THEME_HEIGHT);
- if (error)
- break;
- error = xwimptextop_set_colour(os_COLOUR_BLACK,
- os_COLOUR_LIGHT_GREY);
- if (error)
- break;
- }
-
- /* icons */
- if (ro_gui_theme_entry(i)->sprite_area) {
- icon.extent.y0 = -i * THEME_HEIGHT - THEME_HEIGHT;
- icon.extent.y1 = -i * THEME_HEIGHT;
- icon.data.indirected_sprite.area = ro_gui_theme_entry(i)->sprite_area;
- icon.data.indirected_sprite.size = 12;
- for (j = 0, x = 0; j != sizeof sprite / sizeof sprite[0]; j++) {
- icon.extent.x0 = x;
- icon.extent.x1 = x + 50;
- icon.data.indirected_sprite.id =
- (osspriteop_id) sprite[j];
- error = xwimp_plot_icon(&icon);
- if (error)
- break;
- x += 50;
- }
- }
- if (error)
- break;
-
- /* theme name */
- error = xwimptextop_paint(0, ro_gui_theme_entry(i)->name,
- x0 + 400,
- y0 - i * THEME_HEIGHT - THEME_HEIGHT / 2);
- if (error)
- break;
- }
-
- if (error) {
- LOG(("0x%x: %s", error->errnum, error->errmess));
- warn_user("MiscError", error->errmess);
+ /* Set the clicked theme as selected
+ */
+ link = toolbars;
+ while (link) {
+ if (link->icon_number == i) {
+ theme_choice = link->descriptor;
+ ro_gui_set_icon_selected_state(dialog_config_th_pane,
+ link->icon_number, true);
+ } else {
+ ro_gui_set_icon_selected_state(dialog_config_th_pane,
+ link->icon_number, false);
+ }
+ link = link->next;
}
}
@@ -1114,3 +983,166 @@ const char *language_name(const char *code)
key[6] = code[1];
return messages_get(key);
}
+
+
+/**
+ * Loads and nests all available themes in the theme pane.
+ */
+void ro_gui_dialog_load_themes(void) {
+ os_error *error;
+ os_box extent = { 0, 0, 0, 0 };
+ struct theme_descriptor *descriptor;
+ struct toolbar_display *link;
+ struct toolbar_display *toolbar_display;
+ struct toolbar *toolbar;
+ wimp_icon_create new_icon;
+ wimp_window_state state;
+ int parent_width, nested_y, min_extent, base_extent;
+
+ /* Delete our old list and get/open a new one
+ */
+ ro_gui_dialog_free_themes();
+ theme_list = ro_gui_theme_get_available();
+ ro_gui_theme_open(theme_list, true);
+ theme_choice = ro_gui_theme_find(option_theme);
+
+ /* Create toolbars for each theme
+ */
+ theme_count = 0;
+ descriptor = theme_list;
+ while (descriptor) {
+ /* Try to create a toolbar
+ */
+ toolbar = ro_gui_theme_create_toolbar(descriptor, THEME_BROWSER_TOOLBAR);
+ if (toolbar) {
+ toolbar_display = calloc(sizeof(struct toolbar_display), 1);
+ if (!toolbar_display) {
+ LOG(("No memory for calloc()"));
+ warn_user("NoMemory", 0);
+ return;
+ }
+ toolbar_display->toolbar = toolbar;
+ toolbar_display->descriptor = descriptor;
+ if (!toolbars) {
+ toolbars = toolbar_display;
+ } else {
+ link = toolbars;
+ while (link->next) link = link->next;
+ link->next = toolbar_display;
+ }
+ theme_count++;
+ }
+ descriptor = descriptor->next;
+ }
+
+ /* Nest the toolbars
+ */
+ state.w = dialog_config_th_pane;
+ 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;
+ }
+ parent_width = state.visible.x1 - state.visible.x0;
+ min_extent = state.visible.y0 - state.visible.y1;
+ nested_y = 0;
+ base_extent = state.visible.y1;
+ extent.x1 = parent_width;
+ link = toolbars;
+ new_icon.w = dialog_config_th_pane;
+ new_icon.icon.extent.x0 = 0;
+ new_icon.icon.extent.x1 = parent_width;
+ new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_INDIRECTED |
+ wimp_ICON_VCENTRED |
+ (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) |
+ (wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT) |
+ (wimp_BUTTON_RADIO << wimp_ICON_BUTTON_TYPE_SHIFT) |
+ (1 << wimp_ICON_ESG_SHIFT);
+ new_icon.icon.data.indirected_text_and_sprite.validation =
+ theme_radio_validation;
+ while (link) {
+ /* Update the toolbar and extent
+ */
+ ro_gui_theme_process_toolbar(link->toolbar, parent_width);
+ extent.y0 = nested_y - link->toolbar->height - 48;
+ if (link->next) extent.y0 -= 16;
+ if (extent.y0 > min_extent) extent.y0 = min_extent;
+ xwimp_set_extent(dialog_config_th_pane, &extent);
+
+ /* Create the descriptor icon
+ */
+ new_icon.icon.extent.y1 = nested_y - link->toolbar->height;
+ new_icon.icon.extent.y0 = nested_y - link->toolbar->height - 48;
+ new_icon.icon.data.indirected_text_and_sprite.text =
+ link->descriptor->filename;
+ new_icon.icon.data.indirected_text_and_sprite.size =
+ strlen(link->descriptor->filename) + 1;
+ xwimp_create_icon(&new_icon, &link->icon_number);
+
+ /* Nest the toolbar window
+ */
+ state.w = link->toolbar->toolbar_handle;
+ state.visible.y1 = nested_y + base_extent;
+ state.visible.y0 = state.visible.y1 - link->toolbar->height + 2;
+ xwimp_open_window_nested((wimp_open *)&state, dialog_config_th_pane,
+ wimp_CHILD_LINKS_PARENT_WORK_AREA
+ << wimp_CHILD_XORIGIN_SHIFT |
+ wimp_CHILD_LINKS_PARENT_WORK_AREA
+ << wimp_CHILD_YORIGIN_SHIFT |
+ wimp_CHILD_LINKS_PARENT_WORK_AREA
+ << wimp_CHILD_LS_EDGE_SHIFT |
+ wimp_CHILD_LINKS_PARENT_WORK_AREA
+ << wimp_CHILD_BS_EDGE_SHIFT |
+ wimp_CHILD_LINKS_PARENT_WORK_AREA
+ << wimp_CHILD_RS_EDGE_SHIFT |
+ wimp_CHILD_LINKS_PARENT_WORK_AREA
+ << wimp_CHILD_TS_EDGE_SHIFT);
+
+ /* Continue processing
+ */
+ nested_y -= link->toolbar->height + 48 + 16;
+ link = link->next;
+ }
+
+ /* Set the current theme as selected
+ */
+ link = toolbars;
+ while (link) {
+ if (link->descriptor == theme_choice) {
+ ro_gui_set_icon_selected_state(dialog_config_th_pane,
+ link->icon_number, true);
+ break;
+ }
+ link = link->next;
+ }
+}
+
+
+/**
+ * Removes and closes all themes in the theme pane.
+ */
+void ro_gui_dialog_free_themes(void) {
+ struct toolbar_display *toolbar;
+ struct toolbar_display *next_toolbar;
+
+ /* Free all our toolbars
+ */
+ next_toolbar = toolbars;
+ while ((toolbar = next_toolbar) != NULL) {
+ xwimp_delete_icon(dialog_config_th_pane, toolbar->icon_number);
+ ro_gui_theme_destroy_toolbar(toolbar->toolbar);
+ next_toolbar = toolbar->next;
+ free(toolbar);
+ }
+ toolbars = NULL;
+
+ /* Close all our themes
+ */
+ if (theme_list) ro_gui_theme_close(theme_list, true);
+ theme_list = NULL;
+ theme_count = 0;
+ theme_choice = NULL;
+}
+
diff --git a/riscos/gui.c b/riscos/gui.c
index 732adb472..8d4d340a6 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -49,7 +49,6 @@
#endif
#include "netsurf/riscos/save_complete.h"
#include "netsurf/riscos/theme.h"
-#include "netsurf/riscos/toolbar.h"
#ifdef WITH_URI
#include "netsurf/riscos/uri.h"
#endif
@@ -61,7 +60,6 @@
#include "netsurf/utils/messages.h"
#include "netsurf/utils/utils.h"
-
const char *__dynamic_da_name = "NetSurf"; /**< For UnixLib. */
int __feature_imagefs_is_file = 1; /**< For UnixLib. */
/* default filename handling */
@@ -172,10 +170,9 @@ static char *ro_path_to_url(const char *path);
void gui_init(int argc, char** argv)
{
char path[40];
- char theme_fname[256];
os_error *error;
int length;
- struct theme_entry *theme;
+ struct theme_descriptor *descriptor = NULL;
xhourglass_start(1);
@@ -222,23 +219,15 @@ void gui_init(int argc, char** argv)
if (getenv("NetSurf$Start_URI_Handler"))
xwimp_start_task("Desktop", 0);
- if (option_theme != NULL) {
- if ((length = snprintf(theme_fname, sizeof(theme_fname),
- "<NetSurf$Dir>.Themes.%s", option_theme)) >= 0
- && length < (int)sizeof(theme_fname)
- /* check if theme directory exists */
- && !is_dir(theme_fname)) {
- free(option_theme);
- option_theme = NULL;
- }
- }
- if (option_theme == NULL)
- strcpy(theme_fname, "<NetSurf$Dir>.Themes.Default");
- theme = ro_theme_load(theme_fname);
- if (theme == NULL)
- LOG(("Unable to load default theme"));
- ro_theme_apply(theme);
+ /* Load our chosen theme
+ */
+ ro_gui_theme_initialise();
+ descriptor = ro_gui_theme_find(option_theme);
+ if (!descriptor) descriptor = ro_gui_theme_find("Default");
+ ro_gui_theme_apply(descriptor);
+ /* Open the templates
+ */
if ((length = snprintf(path, sizeof(path),
"<NetSurf$Dir>.Resources.%s.Templates",
option_language)) < 0 || length >= (int)sizeof(path))
@@ -684,9 +673,7 @@ void ro_gui_redraw_window_request(wimp_draw *redraw)
osbool more;
os_error *error;
- if (redraw->w == dialog_config_th_pane)
- ro_gui_redraw_config_th_pane(redraw);
- else if (redraw->w == history_window)
+ if (redraw->w == history_window)
ro_gui_history_redraw(redraw);
else if (redraw->w == hotlist_window)
ro_gui_hotlist_redraw(redraw);
@@ -737,10 +724,8 @@ void ro_gui_open_window_request(wimp_open *open)
}
g = ro_gui_status_lookup(open->w);
- if (g && g->toolbar) {
- g->toolbar->resize_status = 1;
- ro_theme_resize_toolbar(g->toolbar, g->window);
- }
+ if (g && g->toolbar)
+ ro_gui_theme_resize_toolbar_status(g->toolbar);
}
}
diff --git a/riscos/gui.h b/riscos/gui.h
index 8a825257c..5c9c0c653 100644
--- a/riscos/gui.h
+++ b/riscos/gui.h
@@ -75,12 +75,9 @@ struct gui_window {
int old_width; /**< Width when last opened / os units. */
int old_height; /**< Height when last opened / os units. */
- char status[256]; /**< Buffer for status bar. */
char title[256]; /**< Buffer for window title. */
- char url[256]; /**< Buffer for url entry field. */
int throbber; /**< Current frame of throbber animation. */
- char throb_buf[12]; /**< Buffer for throbber sprite name. */
int throbtime; /**< Time of last throbber frame. */
/** Options. */
@@ -132,7 +129,6 @@ void ro_gui_dialog_click(wimp_pointer *pointer);
void ro_gui_save_options(void);
bool ro_gui_dialog_keypress(wimp_key *key);
void ro_gui_dialog_close(wimp_w close);
-void ro_gui_redraw_config_th_pane(wimp_draw *redraw);
void ro_gui_menu_prepare_hotlist(void);
void ro_gui_dialog_open_config(void);
void ro_gui_dialog_proxyauth_menu_selection(int item);
@@ -167,6 +163,8 @@ bool ro_gui_401login_keypress(wimp_key *key);
/* in window.c */
void ro_gui_window_quit(void);
void ro_gui_window_click(struct gui_window *g, wimp_pointer *mouse);
+void ro_gui_window_update_theme(void);
+void ro_gui_window_update_dimensions(struct gui_window *g, int yscroll);
void ro_gui_window_open(struct gui_window *g, wimp_open *open);
void ro_gui_window_redraw(struct gui_window *g, wimp_draw *redraw);
void ro_gui_window_mouse_at(struct gui_window *g, wimp_pointer *pointer);
@@ -281,8 +279,8 @@ bool ro_gui_print_keypress(wimp_key *key);
#define ICON_TOOLBAR_HOTLIST_LAST 6
/* icon numbers for toolbar status window */
-#define ICON_STATUS_TEXT 0
-#define ICON_STATUS_RESIZE 1
+#define ICON_STATUS_RESIZE 0
+#define ICON_STATUS_TEXT 1
#define ICON_CONFIG_SAVE 0
#define ICON_CONFIG_CANCEL 1
diff --git a/riscos/help.c b/riscos/help.c
index 6a7f7a696..22fc5b09b 100644
--- a/riscos/help.c
+++ b/riscos/help.c
@@ -18,7 +18,7 @@
#include "oslib/wimp.h"
#include "netsurf/riscos/gui.h"
#include "netsurf/riscos/help.h"
-#include "netsurf/riscos/toolbar.h"
+#include "netsurf/riscos/theme.h"
#include "netsurf/riscos/wimp.h"
#include "netsurf/utils/messages.h"
#include "netsurf/utils/log.h"
diff --git a/riscos/hotlist.c b/riscos/hotlist.c
index de91fbad7..fad751306 100644
--- a/riscos/hotlist.c
+++ b/riscos/hotlist.c
@@ -25,7 +25,6 @@
#include "netsurf/riscos/gui.h"
#include "netsurf/riscos/theme.h"
#include "netsurf/riscos/tinct.h"
-#include "netsurf/riscos/toolbar.h"
#include "netsurf/riscos/wimp.h"
#include "netsurf/utils/log.h"
#include "netsurf/utils/messages.h"
@@ -303,7 +302,8 @@ void ro_gui_hotlist_init(void) {
/* Create our toolbar
*/
- ro_theme_create_hotlist_toolbar();
+ hotlist_toolbar = ro_gui_theme_create_toolbar(NULL, THEME_HOTLIST_TOOLBAR);
+ ro_gui_theme_attach_toolbar(hotlist_toolbar, hotlist_window);
/* Update the extent
*/
diff --git a/riscos/htmlredraw.c b/riscos/htmlredraw.c
index b9e47cd00..2a29d8eca 100644
--- a/riscos/htmlredraw.c
+++ b/riscos/htmlredraw.c
@@ -28,7 +28,7 @@
#include "netsurf/riscos/gui.h"
#include "netsurf/riscos/image.h"
#include "netsurf/riscos/options.h"
-#include "netsurf/riscos/toolbar.h"
+#include "netsurf/riscos/theme.h"
#include "netsurf/riscos/ufont.h"
#include "netsurf/riscos/wimp.h"
#include "netsurf/utils/log.h"
diff --git a/riscos/menus.c b/riscos/menus.c
index 9505331e0..1a8005bf0 100644
--- a/riscos/menus.c
+++ b/riscos/menus.c
@@ -25,7 +25,6 @@
#include "netsurf/riscos/help.h"
#include "netsurf/riscos/options.h"
#include "netsurf/riscos/theme.h"
-#include "netsurf/riscos/toolbar.h"
#include "netsurf/riscos/wimp.h"
#include "netsurf/utils/log.h"
#include "netsurf/utils/messages.h"
@@ -657,6 +656,7 @@ void ro_gui_menu_selection(wimp_selection *selection)
wimp_pointer pointer;
wimp_window_state state;
os_error *error;
+ int height;
wimp_get_pointer_info(&pointer);
@@ -757,7 +757,7 @@ void ro_gui_menu_selection(wimp_selection *selection)
case 5: /* Print */
break;
case 6: /* New window */
- browser_window_create(current_gui->url, current_gui->bw);
+ browser_window_create(current_gui->bw->current_content->url, current_gui->bw);
break;
case 7: /* Page source */
ro_gui_view_source(c);
@@ -851,29 +851,27 @@ void ro_gui_menu_selection(wimp_selection *selection)
case 2: /* Toolbars -> */
switch (selection->items[2]) {
case 0:
- current_gui->toolbar->standard_buttons =
- !current_gui->toolbar->standard_buttons;
+ current_gui->toolbar->display_buttons =
+ !current_gui->toolbar->display_buttons;
break;
case 1:
- current_gui->toolbar->url_bar =
- !current_gui->toolbar->url_bar;
+ current_gui->toolbar->display_url =
+ !current_gui->toolbar->display_url;
break;
case 2:
- current_gui->toolbar->throbber =
- !current_gui->toolbar->throbber;
+ current_gui->toolbar->display_throbber =
+ !current_gui->toolbar->display_throbber;
break;
case 3:
- current_gui->toolbar->status_window =
- !current_gui->toolbar->status_window;
- }
- if (ro_theme_update_toolbar(current_gui->toolbar,
- current_gui->window) || true) {
- wimp_window_state state;
- state.w = current_gui->window;
- wimp_get_window_state(&state);
- current_gui->old_height = 0xffffffff;
- ro_gui_window_open(current_gui, (wimp_open *)&state);
+ current_gui->toolbar->display_status =
+ !current_gui->toolbar->display_status;
}
+ current_gui->toolbar->reformat_buttons = true;
+ height = current_gui->toolbar->height;
+ ro_gui_theme_process_toolbar(current_gui->toolbar, -1);
+ if (height != current_gui->toolbar->height)
+ ro_gui_window_update_dimensions(current_gui,
+ height - current_gui->toolbar->height);
ro_gui_menu_prepare_toolbars();
break;
case 3: /* Render -> */
@@ -1497,10 +1495,10 @@ static void ro_gui_menu_prepare_toolbars(void) {
browser_toolbar_menu->entries[index].icon_flags &= ~wimp_ICON_SHADED;
browser_toolbar_menu->entries[index].menu_flags &= ~wimp_MENU_TICKED;
}
- if (toolbar->standard_buttons) browser_toolbar_menu->entries[0].menu_flags |= wimp_MENU_TICKED;
- if (toolbar->url_bar) browser_toolbar_menu->entries[1].menu_flags |= wimp_MENU_TICKED;
- if (toolbar->throbber) browser_toolbar_menu->entries[2].menu_flags |= wimp_MENU_TICKED;
- if (toolbar->status_window) browser_toolbar_menu->entries[3].menu_flags |= wimp_MENU_TICKED;
+ if (toolbar->display_buttons) browser_toolbar_menu->entries[0].menu_flags |= wimp_MENU_TICKED;
+ if (toolbar->display_url) browser_toolbar_menu->entries[1].menu_flags |= wimp_MENU_TICKED;
+ if (toolbar->display_throbber) browser_toolbar_menu->entries[2].menu_flags |= wimp_MENU_TICKED;
+ if (toolbar->display_status) browser_toolbar_menu->entries[3].menu_flags |= wimp_MENU_TICKED;
} else {
for (index = 0; index < 4; index++) {
browser_toolbar_menu->entries[index].icon_flags |= wimp_ICON_SHADED;
diff --git a/riscos/options.h b/riscos/options.h
index 34e2b837a..7ea9c3560 100644
--- a/riscos/options.h
+++ b/riscos/options.h
@@ -60,7 +60,7 @@ bool option_thumbnail_32bpp = true;\
int option_thumbnail_oversampling = 0;\
bool option_history_tooltip = true; \
int option_scale = 100; \
-int option_toolbar_status_width = 640; \
+int option_toolbar_status_width = 5000; \
bool option_toolbar_show_status = true; \
bool option_toolbar_show_buttons = true; \
bool option_toolbar_show_address = true; \
@@ -95,7 +95,7 @@ bool option_plugins = false;
{ "history_tooltip", OPTION_BOOL, &option_history_tooltip }, \
{ "scale", OPTION_INTEGER, &option_scale }, \
{ "toolbar_show_status", OPTION_BOOL, &option_toolbar_show_status }, \
-{ "toolbar_status_width", OPTION_INTEGER, &option_toolbar_status_width }, \
+{ "toolbar_status_size", OPTION_INTEGER, &option_toolbar_status_width }, \
{ "toolbar_show_buttons", OPTION_BOOL, &option_toolbar_show_buttons }, \
{ "toolbar_show_address", OPTION_BOOL, &option_toolbar_show_address }, \
{ "toolbar_show_throbber", OPTION_BOOL, &option_toolbar_show_throbber }, \
diff --git a/riscos/theme.c b/riscos/theme.c
index 941bdbbbc..517bbe114 100644
--- a/riscos/theme.c
+++ b/riscos/theme.c
@@ -1,307 +1,823 @@
/*
* This file is part of NetSurf, http://netsurf.sourceforge.net/
* Licensed under the GNU General Public License,
- * http://www.opensource.org/licenses/gpl-license
- * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
- * Copyright 2003 James Bursa <bursa@users.sourceforge.net>
+ * http://www.opensource.org/licenses/gpl-license
* Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net>
- * Copyright 2004 Andrew Timmins <atimmins@blueyonder.co.uk>
*/
/** \file
- * Toolbar themes (implementation).
+ * Window themes and toolbars (implementation).
*/
#include <alloca.h>
#include <assert.h>
#include <stdio.h>
+#include <stdbool.h>
#include <string.h>
#include "oslib/os.h"
#include "oslib/osgbpb.h"
#include "oslib/osfile.h"
#include "oslib/osspriteop.h"
#include "oslib/wimp.h"
+#include "oslib/wimpextend.h"
#include "oslib/wimpspriteop.h"
#include "netsurf/riscos/gui.h"
#include "netsurf/riscos/theme.h"
-#include "netsurf/riscos/toolbar.h"
#include "netsurf/riscos/wimp.h"
-#include "netsurf/utils/utils.h"
#include "netsurf/utils/log.h"
+#include "netsurf/utils/utils.h"
+
+
+#define THEME_URL_MEMORY 256
+#define THEME_THROBBER_MEMORY 12
+#define THEME_STATUS_MEMORY 256
+
+
+static struct theme_descriptor *theme_current = NULL;
+static struct theme_descriptor *theme_descriptors = NULL;
+
+static void ro_gui_theme_free(struct theme_descriptor *descriptor, bool list);
+static void 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);
+
+
+/* A basic window for the toolbar and status
+*/
+static wimp_window theme_toolbar_window = {
+ {0, 0, 16384, 16384},
+ 0,
+ 0,
+ wimp_TOP,
+ wimp_WINDOW_NEW_FORMAT | wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW |
+ wimp_WINDOW_FURNITURE_WINDOW,
+ 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+ - greyed icons detected for interactive help */,
+ {0, 0, 16384, 16384},
+ 0,
+ 0,
+ wimpspriteop_AREA,
+ 12,
+ 1,
+ {""},
+ 0,
+ { }
+};
+
-/* Current theme
+/* Shared icon validation
*/
-static struct theme_entry *ro_theme_current = NULL;
+static char theme_url_validation[] = "Pptr_write\0";
+static char theme_resize_validation[] = "R1;Pptr_lr,8,6\0";
+static char theme_null_text_string[] = "\0";
/**
- * Apply the current theme
- *
- * /param theme the theme to apply
+ * Initialise the theme handler
*/
-void ro_theme_apply(struct theme_entry *theme) {
-#ifdef WITH_KIOSK_THEMES
- char *kioskfilename = alloca(strlen(THEMES_DIR) + strlen(theme->name) + 16);
-#endif
-
- /* Release any previous theme
+void ro_gui_theme_initialise(void) {
+ /* Get an initial theme list
*/
- if (ro_theme_current) ro_theme_free(ro_theme_current);
+ theme_descriptors = ro_gui_theme_get_available();
+}
- /* Set the current theme
+
+/**
+ * Finalise the theme handler
+ */
+void ro_gui_theme_finalise(void) {
+ /* Free all closed descriptors
*/
- ro_theme_current = theme;
+ ro_gui_theme_close(theme_current, false);
+ ro_gui_theme_free(theme_descriptors, true);
+}
- /* Load the window furniture if using Kiosk Themes
- *
- * Yes I know this is one serious hack!
- * I'll do something a little more "realistic" when I've
- * finished various other bits... Right now it works.
- */
-#ifdef WITH_KIOSK_THEMES
- sprintf(kioskfilename, "%s.%s.!SetTheme", THEMES_DIR, theme->name);
- xos_cli(kioskfilename);
-#endif
- /* todo: update all current windows */
+/**
+ * Finds a theme from the cached values.
+ *
+ * The returned theme is only guaranteed to be valid until the next call
+ * to ro_gui_theme_get_available() unless it has been opened using
+ * ro_gui_theme_open().
+ *
+ * \param filename the filename of the theme_descriptor to return
+ * \return the requested theme_descriptor, or NULL if not found
+ */
+struct theme_descriptor *ro_gui_theme_find(const char *filename) {
+ struct theme_descriptor *descriptor;
+
+ /* Check for bad filename
+ */
+ if (!filename) return NULL;
+
+ /* Work through until we find our required filename
+ */
+ descriptor = theme_descriptors;
+ while (descriptor) {
+ if (!strcmp(filename, descriptor->filename)) return descriptor;
+ descriptor = descriptor->next;
+ }
+ return NULL;
}
/**
- * Load a theme from a directory.
+ * Reads and caches the currently available themes.
*
- * Ideally, the directory should contain a Sprite file and a Text options file.
- * If the path is invalid, or neither of these are present then a default theme
- * is returned with no icons present.
+ * \return the requested theme_descriptor, or NULL if not found
*/
-
-struct theme_entry *ro_theme_load(char *pathname) {
- osbool mask;
- os_mode mode;
- os_coord dimensions;
- int size, i, n;
- char *filename = alloca(strlen(pathname) + 16);
- char *name;
+struct theme_descriptor *ro_gui_theme_get_available(void) {
+ struct theme_descriptor *current;
+ struct theme_descriptor *test;
+ char pathname[256];
+ int context = 0;
+ int read_count;
+ osgbpb_INFO(100) info;
fileswitch_object_type obj_type;
- struct theme_entry *theme;
os_error *error;
- /* Get some memory for the theme
- */
- theme = (struct theme_entry *)calloc(1, sizeof(struct theme_entry));
- if (!theme) {
- LOG(("Failed to claim memory to hold theme."));
- warn_user("NoMemory", 0);
- return NULL;
- }
- theme->default_settings = true;
-
- /* Load the sprites
+ /* Close any descriptors we've got so far
*/
- sprintf(filename, "%s.Sprites", pathname);
- xosfile_read_no_path(filename, &obj_type, 0, 0, &size, 0);
+ ro_gui_theme_free(theme_descriptors, true);
- /* Claim memory for a sprite file if we have one
+ /* Create a new set
*/
- if (obj_type & fileswitch_IS_FILE) theme->sprite_area = malloc(size + 16);
+ while (context != -1) {
+ /* Get the next entry
+ */
+ error = xosgbpb_dir_entries_info(THEMES_DIR,
+ (osgbpb_info_list *) &info, 1, context,
+ sizeof(info), 0, &read_count, &context);
+ if (error) {
+ LOG(("xosgbpb_dir_entries_info: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("MiscError", error->errmess);
+ break;
+ }
+
+ /* Check if we've read anything
+ */
+ if (read_count == 0)
+ continue;
+
+ /* Only process files
+ */
+ if ((info.obj_type == fileswitch_IS_DIR) && (!ro_gui_theme_find(info.name))) {
+ /* Get our full filename
+ */
+ snprintf(pathname, sizeof pathname, "%s.%s.Sprites",
+ THEMES_DIR, info.name);
+ pathname[sizeof pathname - 1] = 0;
+
+ /* Check for sprites file
+ */
+ error = xosfile_read_stamped_no_path(pathname,
+ &obj_type, (bits *)0, (bits *)0, (int *)0,
+ (fileswitch_attr *)0, (bits *)0);
+ if (error) {
+ LOG(("xosfile_read_stamped_no_path: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("MiscError", error->errmess);
+ } else if (obj_type == fileswitch_IS_FILE) {
- /* Load the sprite file if we have any memory
+ /* Create a new theme descriptor
+ */
+ current = (struct theme_descriptor *)calloc(1,
+ sizeof(struct theme_descriptor));
+ if (!current) {
+ LOG(("calloc failed"));
+ warn_user("NoMemory", 0);
+ return theme_descriptors;
+ }
+ current->filename = malloc(strlen(info.name) + 1);
+ if (!current->filename) {
+ LOG(("malloc failed"));
+ warn_user("NoMemory", 0);
+ free(current);
+ return theme_descriptors;
+ }
+ strcpy(current->filename, info.name);
+
+ /* Link in our new descriptor alphabetically
+ */
+ if (theme_descriptors) {
+ current->next = theme_descriptors;
+ theme_descriptors->previous = current;
+ }
+ theme_descriptors = current;
+ }
+ }
+ }
+
+ /* Sort alphabetically in a very rubbish way
*/
- if (theme->sprite_area) {
+ if (theme_descriptors->next) {
+ current = theme_descriptors;
+ while ((test = current->next)) {
+ if (strcmp(current->filename, test->filename) > 0) {
+ current->next->previous = current->previous;
+ if (current->previous)
+ current->previous->next = current->next;
+ current->next = test->next;
+ test->next = current;
+ current->previous = test;
+ if (current->next)
+ current->next->previous = current;
- /* Initialise then load
- */
- theme->sprite_area->size = size + 16;
- theme->sprite_area->sprite_count = 0;
- theme->sprite_area->first = 16;
- theme->sprite_area->used = 16;
- xosspriteop_clear_sprites(osspriteop_USER_AREA, theme->sprite_area);
- error = xosspriteop_load_sprite_file(osspriteop_USER_AREA, theme->sprite_area,
- filename);
- if (error) {
- free(theme->sprite_area);
- theme->sprite_area = NULL;
+ current = test->previous;
+ if (!current) current = test;
+ } else {
+ current = current->next;
+ }
}
+ while (theme_descriptors->previous)
+ theme_descriptors = theme_descriptors->previous;
}
+ return theme_descriptors;
+}
- /* Get the throbber details
+
+/**
+ * Opens a theme ready for use.
+ *
+ * \param descriptor the theme_descriptor to open
+ * \param list whether to open all themes in the list
+ * \return whether the operation was successful
+ */
+bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list) {
+ os_coord dimensions;
+ os_mode mode;
+ char pathname[256];
+ bool result = true;
+ int i, n;
+
+ /* If we are freeing the whole of the list then we need to
+ start at the first descriptor.
*/
- if (theme->sprite_area) {
- /* We aren't default
- */
- theme->default_settings = false;
+ if (list) {
+ while (descriptor->previous) descriptor = descriptor->previous;
+ }
- /* Find the highest sprite called 'throbber%i', and get the maximum
- dimensions for all 'thobber%i' icons. We use the filename buffer
- as the temporary spritename buffer as it is guaranteed to be at
- least 12 bytes (max sprite name size).
+ /* Open the themes
+ */
+ while (descriptor) {
+ /* If we are already loaded, increase the usage count
*/
- for (i = 1; i <= theme->sprite_area->sprite_count; i++) {
- osspriteop_return_name(osspriteop_USER_AREA,
- theme->sprite_area, filename, 12, i);
- if (strncmp(filename, "throbber", 8) == 0) {
- /* Get the max sprite width/height
- */
- xosspriteop_read_sprite_info(osspriteop_USER_AREA,
- theme->sprite_area, (osspriteop_id)filename,
- &dimensions.x, &dimensions.y, &mask, &mode);
- ro_convert_pixels_to_os_units(&dimensions, mode);
- if (dimensions.x > theme->throbber_width)
- theme->throbber_width = dimensions.x;
- if (dimensions.y > theme->throbber_height)
- theme->throbber_height = dimensions.y;
-
- /* Get the throbber number
- */
- n = atoi(filename + 8);
- if (theme->throbber_frames < n) theme->throbber_frames = n;
+ if (descriptor->theme) {
+ descriptor->theme->users = descriptor->theme->users + 1;
+ } else {
+ /* Create a new theme
+ */
+ descriptor->theme = (struct theme *)calloc(1, sizeof(struct theme));
+ if (!descriptor->theme) {
+ LOG(("calloc failed"));
+ warn_user("NoMemory", 0);
+ return false;
+ }
+ descriptor->theme->users = 1;
+
+ /* Get our full filename
+ */
+ snprintf(pathname, sizeof pathname, "%s.%s.Sprites",
+ THEMES_DIR, descriptor->filename);
+ pathname[sizeof pathname - 1] = 0;
+
+ /* Load the sprites
+ */
+ descriptor->theme->sprite_area = ro_gui_load_sprite_file(pathname);
+ if (!descriptor->theme->sprite_area) {
+ result = false;
+ free(descriptor->theme);
+ descriptor->theme = NULL;
+ continue;
}
+
+ /* Find the highest sprite called 'throbber%i', and get the maximum
+ dimensions for all 'thobber%i' icons.
+ */
+ for (i = 1; i <= descriptor->theme->sprite_area->sprite_count; i++) {
+ osspriteop_return_name(osspriteop_USER_AREA,
+ descriptor->theme->sprite_area, pathname, 12, i);
+ if (strncmp(pathname, "throbber", 8) == 0) {
+ /* Get the max sprite width/height
+ */
+ xosspriteop_read_sprite_info(osspriteop_USER_AREA,
+ descriptor->theme->sprite_area,
+ (osspriteop_id)pathname,
+ &dimensions.x, &dimensions.y,
+ (osbool *)0, &mode);
+ ro_convert_pixels_to_os_units(&dimensions, mode);
+ if (dimensions.x > descriptor->theme->throbber_width)
+ descriptor->theme->throbber_width = dimensions.x;
+ if (dimensions.y > descriptor->theme->throbber_height)
+ descriptor->theme->throbber_height = dimensions.y;
+
+ /* Get the throbber number
+ */
+ n = atoi(pathname + 8);
+ if (descriptor->theme->throbber_frames < n)
+ descriptor->theme->throbber_frames = n;
+ }
+ }
+
+ /* Load the options
+ */
+ descriptor->theme->throbber_right = true;
+ descriptor->theme->browser_background = wimp_COLOUR_VERY_LIGHT_GREY;
+ descriptor->theme->hotlist_background = wimp_COLOUR_VERY_LIGHT_GREY;
+ descriptor->theme->status_background = wimp_COLOUR_VERY_LIGHT_GREY;
+ descriptor->theme->status_foreground = wimp_COLOUR_BLACK;
+// FINISH ME - NEEDS FINAL FILE FORMAT DECIDING
}
+
+ /* Loop or return depending on whether the entire list
+ is to be processed.
+ */
+ if (list) {
+ descriptor = descriptor->next;
+ } else {
+ return result;
+ }
}
+ return result;
+}
+
+
+/**
+ * Applies the theme to all current windows and subsequent ones.
+ *
+ * \param descriptor the theme_descriptor to open
+ * \return whether the operation was successful
+ */
+bool ro_gui_theme_apply(struct theme_descriptor *descriptor) {
+ struct theme_descriptor *theme_previous;
- /* Copy name.
+ /* Check if the theme is already applied
*/
- name = strrchr(pathname, '.');
- if (name) {
- theme->name = strdup(name+1);
- if (!theme->name) {
- warn_user("NoMemory", 0);
- ro_theme_free(theme);
- return NULL;
- }
- }
- else {
- LOG(("failed to extract theme name from pathname"));
- warn_user("MiscError", "Unable to acquire theme name");
- ro_theme_free(theme);
- return NULL;
+ if (descriptor == theme_current) return true;
+
+ /* Re-open the new-theme and release the current theme
+ */
+ if (!ro_gui_theme_open(descriptor, false)) {
+ /* The error has already been reported
+ */
+ return false;
}
-
- /* Load the options
+ theme_previous = theme_current;
+ theme_current = descriptor;
+
+ /* Apply the theme to all the current windows
*/
- theme->browser_background = wimp_COLOUR_VERY_LIGHT_GREY;
- theme->hotlist_background = wimp_COLOUR_VERY_LIGHT_GREY;
- theme->status_background = wimp_COLOUR_VERY_LIGHT_GREY;
- theme->status_foreground = wimp_COLOUR_BLACK;
- /* todo: impement option loading */
-
- /* Return our new theme
+ ro_gui_window_update_theme();
+
+ /* Release the previous theme
*/
- return theme;
+ ro_gui_theme_close(theme_previous, false);
+ return true;
}
/**
- * Create a toolbar from the current theme for a browser window.
+ * Closes a theme after use.
*
- * The buffers url_buffer and status_buffer must be at least 256 bytes each,
- * throbber_buffer at least 12 bytes;
+ * \param descriptor the theme_descriptor to close
+ * \param list whether to open all themes in the list
+ * \return whether the operation was successful
*/
-void ro_theme_create_browser_toolbar(struct gui_window *g) {
- struct toolbar *toolbar;
+void ro_gui_theme_close(struct theme_descriptor *descriptor, bool list) {
- /* Destroy any previous toolbar (paranoia)
+ /* We might not have created any descriptors yet to close.
*/
- if (g->toolbar) {
- ro_toolbar_destroy(g->toolbar);
- g->toolbar = NULL;
+ if (!descriptor) return;
+
+ /* If we are freeing the whole of the list then we need to
+ start at the first descriptor.
+ */
+ if (list) {
+ while (descriptor->previous) descriptor = descriptor->previous;
+ }
+
+ /* Close the themes
+ */
+ while (descriptor) {
+ /* Lower the theme usage count
+ */
+ if (descriptor->theme) {
+ descriptor->theme->users = descriptor->theme->users - 1;
+ if (descriptor->theme->users <= 0) {
+ free(descriptor->theme->sprite_area);
+ free(descriptor->theme->author);
+ free(descriptor->theme->details);
+ free(descriptor->theme);
+ descriptor->theme = NULL;
+ }
+ }
+
+ /* Loop or return depending on whether the entire list
+ is to be processed.
+ */
+ if (list) {
+ descriptor = descriptor->next;
+ } else {
+ return;
+ }
}
- /* Create a toolbar
- */
- toolbar = ro_toolbar_create(ro_theme_current, g->url, g->status,
- g->throb_buf, TOOLBAR_BROWSER);
- if (toolbar == NULL) return;
+}
+
- /* Set up the default status width
- */
- toolbar->status_width = 640;
+/**
+ * Frees any unused theme descriptors.
+ *
+ * \param descriptor the theme_descriptor to free
+ * \param list whether to open all themes in the list
+ * \return whether the operation was successful
+ */
+void ro_gui_theme_free(struct theme_descriptor *descriptor, bool list) {
+ struct theme_descriptor *next_descriptor;
+
+ /* We might not have created any descriptors yet to close.
+ */
+ if (!descriptor) return;
+
+ /* If we are freeing the whole of the list then we need to
+ start at the first descriptor.
+ */
+ if (list) {
+ while (descriptor->previous) descriptor = descriptor->previous;
+ }
- /* Store our toolbar
- */
- g->toolbar = toolbar;
+ /* Close the themes
+ */
+ while (descriptor) {
+ /* Remember where we are going next
+ */
+ next_descriptor = descriptor->next;
+
+ /* If we have no loaded theme then we can kill the descriptor
+ */
+ if (!descriptor->theme) {
+ /* De-link the descriptor
+ */
+ if (descriptor->previous)
+ descriptor->previous->next = descriptor->next;
+ if (descriptor->next)
+ descriptor->next->previous = descriptor->previous;
+
+ /* Keep the cached list in sync
+ */
+ if (theme_descriptors == descriptor)
+ theme_descriptors = next_descriptor;
+ /* Release any memory
+ */
+ free(descriptor->filename);
+ free(descriptor);
+ }
- /* Update the toolbar
- */
- ro_theme_update_toolbar(toolbar, g->window);
+ /* Loop or return depending on whether the entire list
+ is to be processed.
+ */
+ if (list) {
+ descriptor = next_descriptor;
+ } else {
+ return;
+ }
+ }
}
/**
- * Create a toolbar from the current theme for a hotlist window.
+ * Creates a toolbar.
*
- * The buffers url_buffer and status_buffer must be at least 256 bytes each,
- * throbber_buffer at least 12 bytes;
+ * \param descriptor the theme to use, or NULL for current
+ * \param type the toolbar type
+ * \return a new toolbar, or NULL for failure
*/
-void ro_theme_create_hotlist_toolbar(void) {
- struct toolbar *toolbar;
+struct toolbar *ro_gui_theme_create_toolbar(struct theme_descriptor *descriptor, toolbar_type type) {
+ struct toolbar *toolbar;
- /* Destroy any previous toolbar (paranoia)
+ /* Create a new toolbar
*/
- if (hotlist_toolbar) {
- ro_toolbar_destroy(hotlist_toolbar);
- hotlist_toolbar = NULL;
+ 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;
+ if (descriptor) toolbar->theme = descriptor->theme;
- /* Create a toolbar
- */
- toolbar = ro_toolbar_create(ro_theme_current, NULL, NULL,
- NULL, TOOLBAR_HOTLIST);
- if (toolbar == NULL) return;
-
- /* Store our toolbar
- */
- hotlist_toolbar = toolbar;
+ /* 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;
+ toolbar->display_status = true;
+ ro_gui_theme_add_toolbar_icon(toolbar, "back", ICON_TOOLBAR_BACK);
+ ro_gui_theme_add_toolbar_icon(toolbar, "forward", ICON_TOOLBAR_FORWARD);
+ ro_gui_theme_add_toolbar_icon(toolbar, "stop", ICON_TOOLBAR_STOP);
+ ro_gui_theme_add_toolbar_icon(toolbar, "reload", ICON_TOOLBAR_RELOAD);
+ ro_gui_theme_add_toolbar_icon(toolbar, "home", ICON_TOOLBAR_HOME);
+ ro_gui_theme_add_toolbar_icon(toolbar, NULL, -1);
+ ro_gui_theme_add_toolbar_icon(toolbar, "search", ICON_TOOLBAR_SEARCH);
+ ro_gui_theme_add_toolbar_icon(toolbar, "history", ICON_TOOLBAR_HISTORY);
+ ro_gui_theme_add_toolbar_icon(toolbar, "scale", ICON_TOOLBAR_SCALE);
+ ro_gui_theme_add_toolbar_icon(toolbar, NULL, -1);
+ ro_gui_theme_add_toolbar_icon(toolbar, "mark", ICON_TOOLBAR_BOOKMARK);
+ ro_gui_theme_add_toolbar_icon(toolbar, "save", ICON_TOOLBAR_SAVE);
+ ro_gui_theme_add_toolbar_icon(toolbar, "print", ICON_TOOLBAR_PRINT);
+ break;
+ case THEME_HOTLIST_TOOLBAR:
+ ro_gui_theme_add_toolbar_icon(toolbar, "create", ICON_TOOLBAR_CREATE);
+ ro_gui_theme_add_toolbar_icon(toolbar, "delete", ICON_TOOLBAR_DELETE);
+ ro_gui_theme_add_toolbar_icon(toolbar, "launch", ICON_TOOLBAR_LAUNCH);
+ ro_gui_theme_add_toolbar_icon(toolbar, NULL, -1);
+ ro_gui_theme_add_toolbar_icon(toolbar, "open", ICON_TOOLBAR_OPEN);
+ ro_gui_theme_add_toolbar_icon(toolbar, "expand", ICON_TOOLBAR_EXPAND);
+ break;
+ }
+
+ /* Claim the memory for our Wimp indirection
+ */
+ if (type == THEME_BROWSER_TOOLBAR) {
+ toolbar->url_buffer = calloc(1, THEME_URL_MEMORY + THEME_THROBBER_MEMORY +
+ THEME_STATUS_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;
+ toolbar->status_buffer = toolbar->throbber_buffer + THEME_THROBBER_MEMORY;
+ sprintf(toolbar->throbber_buffer, "throbber0");
+ }
- /* Update the toolbar
- */
- ro_theme_update_toolbar(toolbar, hotlist_window);
+ /* Apply the desired theme to the toolbar
+ */
+ if (!ro_gui_theme_update_toolbar(descriptor, toolbar)) {
+ ro_gui_theme_destroy_toolbar(toolbar);
+ return NULL;
+ }
+ return toolbar;
}
-
/**
- * Updates any toolbar flags (eg closes windows, hides icons etc)
+ * Updates a toolbar to use a particular theme.
+ * The toolbar may be unstable on failure and should be destroyed.
*
- * \return non-zero if the toolbar height has changed
+ * \param descriptor the theme to use, or NULL for current
+ * \param toolbar the toolbar to update
+ * \return whether the operation was successful
*/
-int ro_theme_update_toolbar(struct toolbar *toolbar, wimp_w window) {
- wimp_outline outline;
- wimp_window_state state;
- int return_value = 0;
-
- /* Set an update as pending
+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;
+ if (!toolbar) return false;
+
+ /* Set the theme and window sprite area
+ */
+ if (!descriptor) descriptor = theme_current;
+ if (descriptor) {
+ toolbar->theme = descriptor->theme;
+ } else {
+ toolbar->theme = NULL;
+ }
+ if (toolbar->theme) {
+ sprite_area = toolbar->theme->sprite_area;
+ } else {
+ sprite_area = (osspriteop_area *)1;
+ }
+ theme_toolbar_window.sprite_area = sprite_area;
+
+ /* Update the icon sizes
+ */
+ toolbar_icon = toolbar->icon;
+ while (toolbar_icon) {
+ ro_gui_theme_update_toolbar_icon(toolbar, toolbar_icon);
+ toolbar_icon = toolbar_icon->next;
+ }
+
+ /* Recreate the toolbar window
*/
- toolbar->update_pending = true;
+ if (toolbar->theme) {
+ if (toolbar->type == THEME_BROWSER_TOOLBAR) {
+ theme_toolbar_window.work_bg = toolbar->theme->browser_background;
+ } else {
+ theme_toolbar_window.work_bg = toolbar->theme->hotlist_background;
+ }
+ } else {
+ theme_toolbar_window.work_bg = wimp_COLOUR_VERY_LIGHT_GREY;
+ }
+ theme_toolbar_window.flags |= wimp_WINDOW_NO_BOUNDS;
+ theme_toolbar_window.xmin = 1;
+ theme_toolbar_window.ymin = 1;
+ theme_toolbar_window.extent.x1 = 16384;
+ theme_toolbar_window.extent.y1 = 16384;
+ if (toolbar->toolbar_handle) {
+ xwimp_delete_window(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;
+ }
+
+ /* Create the basic icons
+ */
+ int max_icon = ICON_TOOLBAR_URL;
+ if (toolbar->type == THEME_HOTLIST_TOOLBAR) max_icon = ICON_TOOLBAR_HOTLIST_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 |
+ (wimp_BUTTON_CLICK << wimp_ICON_BUTTON_TYPE_SHIFT);
+ if (toolbar->theme) {
+ new_icon.icon.flags |= (toolbar->theme->browser_background
+ << wimp_ICON_BG_COLOUR_SHIFT);
+ } else {
+ new_icon.icon.flags |= (wimp_COLOUR_VERY_LIGHT_GREY
+ << wimp_ICON_BG_COLOUR_SHIFT);
+ }
+ for (int i = 0; i < max_icon; i++) {
+ new_icon.icon.data.indirected_text.text = 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) {
+ new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED | wimp_ICON_VCENTRED |
+ wimp_ICON_BORDER | 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;
+ }
- /* Close the status window if we should, or resize it
- */
- if (toolbar->status_window) {
+ /* 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);
+ }
+
+ /* Recreate the status window
+ */
+ if (toolbar->type == THEME_BROWSER_TOOLBAR) {
+ /* Delete the old window and create a new one
+ */
+ if (toolbar->status_handle) {
+ xwimp_delete_window(toolbar->status_handle);
+ toolbar->status_handle = NULL;
+ }
+ if (toolbar->theme) {
+ theme_toolbar_window.work_bg = toolbar->theme->status_background;
+ } else {
+ theme_toolbar_window.work_bg = wimp_COLOUR_VERY_LIGHT_GREY;
+ }
+ theme_toolbar_window.flags &= ~wimp_WINDOW_NO_BOUNDS;
+ theme_toolbar_window.xmin = 12;
+ theme_toolbar_window.ymin = ro_get_hscroll_height((wimp_w)0) - 4;
+ theme_toolbar_window.extent.y1 = theme_toolbar_window.ymin;
+ error = xwimp_create_window(&theme_toolbar_window, &toolbar->status_handle);
+ if (error) {
+ LOG(("xwimp_create_window: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ return false;
+ }
+
+ /* Create the status resize icon
+ */
+ new_icon.w = toolbar->status_handle;
+ new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED |
+ wimp_ICON_BORDER | wimp_ICON_FILLED |
+ (wimp_COLOUR_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT) |
+ (wimp_BUTTON_CLICK_DRAG << wimp_ICON_BUTTON_TYPE_SHIFT);
+ new_icon.icon.data.indirected_text.text = theme_null_text_string;
+ new_icon.icon.data.indirected_text.validation = theme_resize_validation;
+ 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;
+ }
- /* Update the status height
- */
- ro_toolbar_resize_status(toolbar, ro_get_hscroll_height(window) - 2);
- } else {
- xwimp_close_window(toolbar->status_handle);
- }
+ /* And finally our status display icon
+ */
+ new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED | wimp_ICON_VCENTRED;
+ if (toolbar->theme) {
+ new_icon.icon.flags |=
+ (toolbar->theme->status_foreground << wimp_ICON_FG_COLOUR_SHIFT) |
+ (toolbar->theme->status_background << wimp_ICON_BG_COLOUR_SHIFT);
+ } else {
+ new_icon.icon.flags |=
+ (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) |
+ (wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT);
+ }
+ new_icon.icon.data.indirected_text.text = toolbar->status_buffer;
+ new_icon.icon.data.indirected_text.validation = theme_null_text_string;
+ new_icon.icon.data.indirected_text.size = THEME_STATUS_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;
+ }
- /* Update the toolbar height
+ }
+
+ /* Force a re-processing of the toolbar
*/
- return_value = ro_theme_resize_toolbar(toolbar, window);
+ toolbar->reformat_buttons = true;
+ toolbar->status_current = -1;
+ ro_gui_theme_process_toolbar(toolbar, toolbar->toolbar_current);
+ return true;
+}
- /* Open/close the toolbar
+
+/**
+ * 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;
+ if (!toolbar) return false;
+
+ /* Attach/close the window
*/
+ toolbar->parent_handle = parent;
if (toolbar->height > 0) {
- outline.w = window;
+ outline.w = parent;
xwimp_get_window_outline(&outline);
- state.w = window;
+ 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 - toolbar->height + 2;
state.xscroll = 0;
state.yscroll = 0;
- state.next = wimp_TOP;
- xwimp_open_window_nested((wimp_open *)&state, window,
+ xwimp_open_window_nested((wimp_open *)&state, parent,
wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
<< wimp_CHILD_XORIGIN_SHIFT |
wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
@@ -315,172 +831,451 @@ int ro_theme_update_toolbar(struct toolbar *toolbar, wimp_w window) {
wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
<< wimp_CHILD_TS_EDGE_SHIFT);
} else {
- xwimp_close_window(toolbar->toolbar_handle);
+ xwimp_close_window(toolbar->toolbar_handle);
}
-
- /* Return
- */
- return return_value;
+ return true;
}
/**
- * Resize the status and toolbar windows.
+ * Updates the toolbars status bar settings to reflect the current size
*
- * \return non-zero if the toolbar height has changed
+ * \param toolbar the toolbar to update
*/
-int ro_theme_resize_toolbar(struct toolbar *toolbar, wimp_w window) {
- os_box extent = { 0, 0, 0, 0 };
+void ro_gui_theme_resize_toolbar_status(struct toolbar *toolbar) {
+ os_error *error;
wimp_outline outline;
- wimp_outline status_outline;
wimp_window_state state;
- int width, status_width;
- int return_value = 0;
-
- /* Paranoia
- */
- if (toolbar == NULL) return 0;
-
- /* Get the toolbar width
- */
- outline.w = window;
- if (xwimp_get_window_outline(&outline)) return 0;
- width = outline.outline.x1 - outline.outline.x0 - 2;
-
- /* Reformat if we should
- */
- if ((toolbar->width != width) || (toolbar->resize_status) || (toolbar->update_pending)) {
- if ((toolbar->resize_status) && (toolbar->status_handle)) {
- status_outline.w = toolbar->status_handle;
- if (xwimp_get_window_outline(&status_outline)) return 0;
- toolbar->status_width = width -
- (status_outline.outline.x1 - status_outline.outline.x0 - 4);
- toolbar->resize_status = 0;
- } else if (toolbar->status_handle) {
- /* Update the extent of the status window
- */
- state.w = window;
- if (xwimp_get_window_state(&state)) return 0;
- extent.x1 = state.visible.x1 - state.visible.x0;
- extent.y1 = toolbar->status_height - 2;
- xwimp_set_extent(toolbar->status_handle, &extent);
-
- /* Re-open the status window as we can't use the nested
- wimp to manage everything as it would keep extending
- the size incorrectly.
- */
- status_width = width - toolbar->status_width;
- if (status_width < 12) status_width = 12;
- if (toolbar->status_window) {
- state.w = toolbar->status_handle;
- state.xscroll = 0;
- state.yscroll = 0;
- state.next = wimp_TOP;
- state.visible.x0 = outline.outline.x0;
- state.visible.x1 = outline.outline.x0 + status_width;
- state.visible.y0 = outline.outline.y0 - toolbar->status_height;
- state.visible.y1 = outline.outline.y0 - 2;
- xwimp_open_window_nested((wimp_open *) &state, window,
- wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
- << wimp_CHILD_XORIGIN_SHIFT |
- wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
- << wimp_CHILD_YORIGIN_SHIFT |
- wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
- << wimp_CHILD_LS_EDGE_SHIFT |
- wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
- << wimp_CHILD_BS_EDGE_SHIFT |
- wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
- << wimp_CHILD_RS_EDGE_SHIFT |
- wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
- << wimp_CHILD_TS_EDGE_SHIFT);
- } else {
- if (toolbar->update_pending) {
- xwimp_close_window(toolbar->status_handle);
- }
- }
- }
+ wimp_w parent = NULL;
+ int parent_size, status_size;
+ if ((!toolbar) || (!toolbar->parent_handle)) return;
+
+ /* Get the width to scale to
+ */
+ parent = toolbar->parent_handle;
+ 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;
+ }
+ parent_size = outline.outline.x1 - outline.outline.x0 - ro_get_vscroll_width(parent) - 2;
- /* Resize the toolbar
- */
- return ro_toolbar_reformat(toolbar, width);
+ /* Get the current size
+ */
+ state.w = toolbar->status_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;
}
- return return_value;
+ status_size = state.visible.x1 - state.visible.x0;
+
+ /* Store the new size
+ */
+ toolbar->status_width = (10000 * status_size) / parent_size;
+ if (toolbar->status_width > 10000) toolbar->status_width = 10000;
+ ro_gui_theme_process_toolbar(toolbar, -1);
}
/**
- * Make a list of available themes.
+ * Updates the toolbar to reflect changes to the icon flags and any reformatting
+ * required due to the change in parent window size.
*
- * \return a forwardly link list of available themes
+ * \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
*/
-
-struct theme_entry *ro_theme_list(unsigned int *entries) {
- char pathname[256];
- int context = 0;
- int read_count;
- struct theme_entry *first = NULL;
- struct theme_entry *last = NULL;
- struct theme_entry *theme = NULL;
- osgbpb_INFO(100) info;
+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_w parent = NULL;
+ wimp_outline outline;
+ wimp_window_state state;
+ int throbber_x = -1;
+ int status_max;
+ int left_edge, right_edge, bottom_edge;
+ int status_size = 0;
+ int status_height = 0;
+ if (!toolbar) return false;
+ int old_height = toolbar->height;
+ int old_width = toolbar->toolbar_current;
+ struct toolbar_icon *toolbar_icon;
+ bool visible_icon = false;
+
+ /* Find the parent window handle if we need to process the status window,
+ or the caller has requested we calculate the width ourself.
+ */
+ if ((width == -1) || ((toolbar->status_handle) && (toolbar->display_status))) {
+ parent = toolbar->parent_handle;
+
+ /* Get the window outline width
+ */
+ if (width == -1) {
+ if (!parent) return false;
+ 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;
+ }
+ width = outline.outline.x1 - outline.outline.x0 - 2;
+ }
+ }
+
+ /* 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->theme) && (toolbar->type == THEME_BROWSER_TOOLBAR) &&
+ (toolbar->display_throbber)) {
+ if (!toolbar->theme->throbber_right) {
+ throbber_x = left_edge;
+ left_edge += toolbar->theme->throbber_width + 8;
+ }
+ toolbar->height = toolbar->theme->throbber_height + 8;
+ }
+ if ((toolbar->type == THEME_BROWSER_TOOLBAR) && (toolbar->display_url)) {
+ if (toolbar->height < 52 + 8) toolbar->height = 52 + 8;
+ }
- *entries = 0;
- while (context != -1) {
- error = xosgbpb_dir_entries_info(THEMES_DIR,
- (osgbpb_info_list *) &info, 1, context,
- sizeof(info), 0, &read_count, &context);
- if (error) {
- LOG(("xosgbpb_dir_entries_info: 0x%x: %s",
- error->errnum, error->errmess));
- warn_user("MiscError", error->errmess);
- ro_theme_free(first);
- *entries = 0;
- return NULL;
+ /* Get the minimum height of the icons
+ */
+ if (toolbar->display_buttons) {
+ toolbar_icon = toolbar->icon;
+ while (toolbar_icon) {
+ if (toolbar_icon->display) {
+ if (!toolbar->reformat_buttons) {
+ left_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) left_edge += 8;
+ }
+
+ /* Check for minimum widths
+ */
+ if (toolbar->type == THEME_BROWSER_TOOLBAR) {
+ bottom_edge = left_edge;
+ if (toolbar->display_url) bottom_edge += 32;
+ if (bottom_edge > right_edge) right_edge = bottom_edge;
+ if ((toolbar->theme) && (toolbar->display_throbber) &&
+ (toolbar->theme->throbber_right)) {
+ bottom_edge += toolbar->theme->throbber_width;
+ if (bottom_edge > right_edge) right_edge = bottom_edge;
+ throbber_x = right_edge - toolbar->theme->throbber_width;
+ right_edge -= toolbar->theme->throbber_width + 8;
+ }
}
- if (read_count == 0)
- continue;
+ if (toolbar->reformat_buttons) {
+ /* Hide the URL bar if we should
+ */
+ if (!toolbar->display_url) {
+ if (!xwimp_get_caret_position(&caret)) {
+ if ((caret.w == toolbar->toolbar_handle) &&
+ (caret.i == ICON_TOOLBAR_URL))
+ xwimp_set_caret_position((wimp_w)-1, 0, 0, 0, 0, 0);
+ }
+ xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_URL,
+ 0, -16384, 0, -16384);
+ }
+ 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_icon->display)
+ && (toolbar_icon->width > 0)) {
+ visible_icon = true;
+ bottom_edge = (toolbar->height -
+ toolbar_icon->height) / 2;
+ 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;
+ }
- /* Get our directory name
- */
- snprintf(pathname, sizeof pathname, "%s.%s",
- THEMES_DIR, info.name);
- pathname[sizeof pathname - 1] = 0;
- /* Load the theme and link it in
- */
- theme = ro_theme_load(pathname);
- if (theme && !(theme->default_settings)) {
- if (first) {
- last->next = theme;
+ if (toolbar->height != 0) toolbar->height += 2;
+ if (toolbar->type == THEME_BROWSER_TOOLBAR) {
+ /* Move the URL bar
+ */
+ if (toolbar->display_url) {
+ xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_URL,
+ left_edge, (toolbar->height / 2) - 26,
+ right_edge, (toolbar->height / 2) + 26);
+ xwimp_force_redraw(toolbar->toolbar_handle,
+ right_edge, 0, 16384, 16384);
+ 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->theme) && (throbber_x >= 0) && (toolbar->display_throbber)) {
+ xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_THROBBER,
+ throbber_x, 0,
+ throbber_x + toolbar->theme->throbber_width, toolbar->height);
+ if (toolbar->theme->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 {
- first = theme;
+ xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_THROBBER,
+ 0, -16384, 0, -16384);
}
- last = theme;
- *entries = *entries + 1;
+ }
+
+ /* Re-attach to the parent
+ */
+ toolbar->toolbar_current = width;
+ if ((toolbar->reformat_buttons) && (parent) && (old_height != toolbar->height)) {
+ ro_gui_theme_attach_toolbar(toolbar, parent);
+ }
+ toolbar->reformat_buttons = false;
+ }
+
+ /* Reformat the status bar
+ */
+ if ((toolbar->status_handle) && (parent)) {
+ /* Get the current state
+ */
+ state.w = toolbar->status_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;
+ }
+
+ /* Open or close the window
+ */
+ if (!toolbar->display_status) {
+ if (state.flags & wimp_WINDOW_OPEN)
+ xwimp_close_window(toolbar->status_handle);
} else {
- if (theme) ro_theme_free(theme);
+ /* Get the status bar height/width
+ */
+ status_max = width - ro_get_vscroll_width(parent);
+ status_size = (status_max * toolbar->status_width) / 10000;
+ if (status_size < 12) status_size = 12;
+ status_height = ro_get_hscroll_height(parent) - 2;
+
+ /* Update the extent
+ */
+ extent.x1 = status_max;
+ extent.y1 = status_height - 2;
+ xwimp_set_extent(toolbar->status_handle, &extent);
+
+ /* Re-open the window
+ */
+ state.w = toolbar->status_handle;
+ state.xscroll = 0;
+ state.yscroll = 0;
+ state.next = wimp_TOP;
+ state.visible.x0 = outline.outline.x0;
+ state.visible.x1 = outline.outline.x0 + status_size;
+ state.visible.y0 = outline.outline.y0 - status_height;
+ state.visible.y1 = outline.outline.y0 - 2;
+ xwimp_open_window_nested((wimp_open *)&state, parent,
+ wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
+ << wimp_CHILD_XORIGIN_SHIFT |
+ wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
+ << wimp_CHILD_YORIGIN_SHIFT |
+ wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
+ << wimp_CHILD_LS_EDGE_SHIFT |
+ wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
+ << wimp_CHILD_BS_EDGE_SHIFT |
+ wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
+ << wimp_CHILD_RS_EDGE_SHIFT |
+ wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
+ << wimp_CHILD_TS_EDGE_SHIFT);
+
+ /* Resize and redraw the icons
+ */
+ status_size = state.visible.x1 - state.visible.x0;
+ if (status_size != toolbar->status_current) {
+ xwimp_resize_icon(toolbar->status_handle, ICON_STATUS_TEXT,
+ 0, 0,
+ status_size - 12, status_height - 2);
+ xwimp_resize_icon(toolbar->status_handle, ICON_STATUS_RESIZE,
+ status_size - 12, 0,
+ status_size, status_height - 2);
+ xwimp_force_redraw(toolbar->status_handle,
+ toolbar->status_current - 12, 0,
+ status_size - 12, status_height - 2);
+ xwimp_force_redraw(toolbar->status_handle,
+ status_size - 12, 0,
+ status_size, status_height - 2);
+ toolbar->status_current = status_size;
+ }
}
}
- return first;
+ return true;
}
/**
- * Free a linked list of themes.
+ * Destroys a toolbar and frees any associated memory.
*
- * \param theme the list of themes to free
+ * \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;
+
+ /* Delete our windows
+ */
+ if (toolbar->toolbar_handle)
+ xwimp_delete_window(toolbar->toolbar_handle);
+ if (toolbar->status_handle)
+ xwimp_delete_window(toolbar->status_handle);
-void ro_theme_free(struct theme_entry *theme) {
- struct theme_entry *next;
- while (theme) {
- free(theme->name);
- free(theme->author);
- free(theme->sprite_area);
- next = theme->next;
- free(theme);
- theme = next;
+ /* 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);
+ }
+ free(toolbar);
+}
+
+void ro_gui_theme_add_toolbar_icon(struct toolbar *toolbar, const char *name, int icon_number) {
+ if (!toolbar) return;
+ struct toolbar_icon *toolbar_icon;
+ struct toolbar_icon *link_icon;
+
+ /* Separators are really a sprite called "separator"
+ */
+ if (name == NULL) name = "separator";
+
+ /* 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;
+ }
+
+ /* 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->icon) {
+ toolbar->icon = toolbar_icon;
+ } else {
+ link_icon = toolbar->icon;
+ while (link_icon->next) link_icon = link_icon->next;
+ link_icon->next = 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;
+ os_mode mode;
+ os_error *error;
+ int default_width = 0;
+
+ /* 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->theme) || (!toolbar->theme->sprite_area)) {
+ icon->width = default_width;
+ icon->height = 0;
+ return;
+ }
+
+ /* Get the sprite details
+ */
+ error = xosspriteop_read_sprite_info(osspriteop_USER_AREA,
+ toolbar->theme->sprite_area, (osspriteop_id)icon->name,
+ &dimensions.x, &dimensions.y, 0, &mode);
+ 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);
+}
diff --git a/riscos/theme.h b/riscos/theme.h
index 8c06be5fb..c0c2394dc 100644
--- a/riscos/theme.h
+++ b/riscos/theme.h
@@ -2,49 +2,93 @@
* This file is part of NetSurf, http://netsurf.sourceforge.net/
* Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-license
- * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
- * Copyright 2003 James Bursa <bursa@users.sourceforge.net>
* Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net>
*/
/** \file
- * Toolbar themes (interface).
- *
- * A theme consists of a simple sprite file. There is one current theme, which
- * is changed by ro_theme_load(). A toolbar can then be created and manipulated.
+ * Window themes and toolbars (interface).
*/
+#include <stdbool.h>
+
#ifndef _NETSURF_RISCOS_THEME_H_
#define _NETSURF_RISCOS_THEME_H_
-#include "oslib/osspriteop.h"
-#include "netsurf/desktop/gui.h"
-
-struct toolbar;
-
-struct theme_entry {
- char *name; /**< theme name */
- char *author; /**< theme author */
- osspriteop_area *sprite_area; /**< sprite area for theme */
- int throbber_width; /**< width of the throbber */
- int throbber_height; /**< height of the throbber */
- int throbber_frames; /**< frames of animation for the throbber */
- int browser_background; /**< background colour of browser toolbar */
- int hotlist_background; /**< background colour of hotlist toolbar */
- int status_background; /**< background colour of status window */
- int status_foreground; /**< colour of status window text */
- bool default_settings; /**< no theme was loaded, defaults used */
- struct theme_entry *next; /**< next entry in theme list */
+typedef enum {
+ THEME_BROWSER_TOOLBAR,
+ THEME_HOTLIST_TOOLBAR
+} toolbar_type;
+
+
+struct toolbar_icon {
+ int icon_number; /**< wimp icon number */
+ bool display; /**< whether to display the icon */
+ 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 toolbar {
+ int status_width; /**< status width percentage * 100 */
+ bool display_buttons; /**< display standard buttons */
+ bool display_url; /**< display URL bar (if applicable) */
+ bool display_throbber; /**< display throbber (if applicable) */
+ bool display_status; /**< display status bar (if applicable) */
+ int status_current; /**< the size of the status window in OS units */
+ int toolbar_current; /**< the size of the toolbar window in OS units */
+ int height; /**< vertical extent of the toolbar (read only) */
+ wimp_w toolbar_handle; /**< toolbar window handle */
+ wimp_w status_handle; /**< status window handle (if applicable) */
+ 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) */
+ char *status_buffer; /**< buffer for status text (read only) */
+ struct toolbar_icon *icon; /**< first toolbar icon (read only) */
+ struct theme *theme; /**< themem or NULL for no theme (read only) */
+ toolbar_type type; /**< toolbar type (read only) */
+};
+
+
+struct theme {
+ char *details; /**< theme details */
+ char *author; /**< theme author */
+ osspriteop_area *sprite_area; /**< sprite area for theme */
+ bool throbber_right; /**< throbber is on the right (left otherwise) */
+ int throbber_width; /**< width of the throbber */
+ int throbber_height; /**< height of the throbber */
+ int throbber_frames; /**< frames of animation for the throbber */
+ int browser_background; /**< background colour of browser toolbar */
+ int hotlist_background; /**< background colour of hotlist toolbar */
+ int status_background; /**< background colour of status window */
+ int status_foreground; /**< colour of status window text */
+ int users; /**< number of users for the theme */
+};
+struct theme_descriptor {
+ char *filename; /**< theme filename */
+ struct theme *theme; /**< corresponding theme (must be opened) */
+ struct theme_descriptor *previous; /**< previous descriptor in the list */
+ struct theme_descriptor *next; /**< next descriptor in the list */
};
-void ro_theme_apply(struct theme_entry *theme);
-struct theme_entry *ro_theme_load(char *pathname);
-void ro_theme_create_browser_toolbar(struct gui_window *g);
-void ro_theme_create_hotlist_toolbar(void);
-int ro_theme_update_toolbar(struct toolbar *toolbar, wimp_w window);
-int ro_theme_resize_toolbar(struct toolbar *toolbar, wimp_w window);
-struct theme_entry *ro_theme_list(unsigned int *entries);
-void ro_theme_free(struct theme_entry *theme);
+void ro_gui_theme_initialise(void);
+void ro_gui_theme_finalise(void);
+struct theme_descriptor *ro_gui_theme_find(const char *filename);
+struct theme_descriptor *ro_gui_theme_get_available(void);
+
+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);
+void ro_gui_theme_resize_toolbar_status(struct toolbar *toolbar);
+bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width);
+void ro_gui_theme_destroy_toolbar(struct toolbar *toolbar);
+
#endif
diff --git a/riscos/wimp.c b/riscos/wimp.c
index 4c8981ac5..b178b848d 100644
--- a/riscos/wimp.c
+++ b/riscos/wimp.c
@@ -39,6 +39,7 @@ int ro_get_hscroll_height(wimp_w w) {
/* Read the hscroll height
*/
+ if (!w) w = dialog_debug;
furniture_sizes.w = w;
furniture_sizes.border_widths.y0 = 38;
xwimpextend_get_furniture_sizes(&furniture_sizes);
@@ -66,6 +67,7 @@ int ro_get_vscroll_width(wimp_w w) {
/* Read the hscroll height
*/
+ if (!w) w = dialog_debug;
furniture_sizes.w = w;
furniture_sizes.border_widths.x1 = 38;
xwimpextend_get_furniture_sizes(&furniture_sizes);
@@ -214,7 +216,8 @@ void ro_gui_set_icon_integer(wimp_w w, wimp_i i, int value) {
* \param i icon handle
* \param state selected state
*/
-#define ro_gui_set_icon_selected_state(w, i, state) xwimp_set_icon_state(w, i, (state ? wimp_ICON_SELECTED : 0), wimp_ICON_SELECTED)
+#define ro_gui_set_icon_selected_state(w, i, state) \
+ xwimp_set_icon_state(w, i, (state ? wimp_ICON_SELECTED : 0), wimp_ICON_SELECTED)
/**
@@ -239,7 +242,8 @@ bool ro_gui_get_icon_selected_state(wimp_w w, wimp_i i) {
* \param i icon handle
* \param state selected state
*/
-#define ro_gui_set_icon_shaded_state(w, i, state) xwimp_set_icon_state(w, i, (state ? wimp_ICON_SHADED : 0), wimp_ICON_SHADED)
+#define ro_gui_set_icon_shaded_state(w, i, state) \
+ xwimp_set_icon_state(w, i, (state ? wimp_ICON_SHADED : 0), wimp_ICON_SHADED)
/**
@@ -331,7 +335,13 @@ void ro_gui_set_caret_first(wimp_w w) {
button = (state.icon.flags >> wimp_ICON_BUTTON_TYPE_SHIFT) & 0xf;
if ((button == wimp_BUTTON_WRITE_CLICK_DRAG) ||
(button == wimp_BUTTON_WRITABLE)) {
- xwimp_set_caret_position(w, icon, 0, 0, -1, strlen(state.icon.data.indirected_text.text));
+ error = xwimp_set_caret_position(w, icon, 0, 0, -1,
+ strlen(state.icon.data.indirected_text.text));
+ if (error) {
+ LOG(("xwimp_set_caret_position: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
return;
}
}
@@ -475,7 +485,7 @@ bool ro_gui_wimp_sprite_exists(const char *sprite)
*
* \param parent parent window
* \param pane pane to open in parent window
- * \param offset offset of top-left of pane from top-left of parent
+ * \param offset inset of pane from parent
*/
void ro_gui_open_pane(wimp_w parent, wimp_w pane, int offset)
@@ -493,6 +503,8 @@ void ro_gui_open_pane(wimp_w parent, wimp_w pane, int offset)
}
state.w = pane;
state.visible.x0 += offset;
+ state.visible.x1 -= offset;
+ state.visible.y0 += offset;
state.visible.y1 -= offset;
state.xscroll = 0;
state.yscroll = 0;
@@ -503,7 +515,7 @@ void ro_gui_open_pane(wimp_w parent, wimp_w pane, int offset)
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_LS_EDGE_SHIFT |
wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
<< wimp_CHILD_BS_EDGE_SHIFT |
wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
diff --git a/riscos/wimp.h b/riscos/wimp.h
index d26fccdfe..53848064d 100644
--- a/riscos/wimp.h
+++ b/riscos/wimp.h
@@ -49,4 +49,8 @@ osspriteop_area *ro_gui_load_sprite_file(const char *pathname);
bool ro_gui_wimp_sprite_exists(const char *sprite);
void ro_gui_open_pane(wimp_w parent, wimp_w pane, int offset);
+
+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,
+ wimp_colour foreground, wimp_colour background);
#endif
diff --git a/riscos/window.c b/riscos/window.c
index aec6bd8da..f6dce705d 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -30,7 +30,6 @@
#include "netsurf/riscos/options.h"
#include "netsurf/riscos/theme.h"
#include "netsurf/riscos/thumbnail.h"
-#include "netsurf/riscos/toolbar.h"
#include "netsurf/riscos/wimp.h"
#include "netsurf/utils/log.h"
#include "netsurf/utils/url.h"
@@ -79,11 +78,8 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
g->reformat_pending = false;
g->old_width = 0;
g->old_height = 0;
- strcpy(g->status, "");
strcpy(g->title, "NetSurf");
- strcpy(g->url, "");
g->throbber = 0;
- strcpy(g->throb_buf, "throbber0");
g->throbtime = 0;
/* Set the window position
@@ -202,6 +198,10 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
window.title_data.indirected_text.validation = (char *) -1;
window.title_data.indirected_text.size = 255;
window.icon_count = 0;
+ if (open_centred) {
+ scroll_width = ro_get_vscroll_width(g->window);
+ window.visible.x0 -= scroll_width;
+ }
error = xwimp_create_window(&window, &g->window);
if (error) {
@@ -212,8 +212,6 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
return 0;
}
- ro_theme_create_browser_toolbar(g);
-
g->prev = 0;
g->next = window_list;
if (window_list)
@@ -221,10 +219,16 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
window_list = g;
window_count++;
+ /* Add in a toolbar
+ */
+ g->toolbar = ro_gui_theme_create_toolbar(NULL, THEME_BROWSER_TOOLBAR);
+ ro_gui_theme_attach_toolbar(g->toolbar, g->window);
+
/* Set the window options
*/
bw->window = g;
ro_gui_window_clone_options(bw, clone);
+ ro_gui_prepare_navigate(g);
/* Open the window
*/
@@ -237,22 +241,15 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
return g;
}
- /* Only fix the centralisation if we've opened the window centred
- */
- if (open_centred) {
- scroll_width = ro_get_vscroll_width(g->window);
- state.visible.x0 -= scroll_width;
- }
-
/* Open the window at the top of the stack
*/
state.next = wimp_TOP;
ro_gui_window_open(g, (wimp_open*)&state);
- ro_gui_prepare_navigate(g);
+
/* Set the caret position to the URL bar
*/
- if (g->toolbar && g->toolbar->url_bar)
+ if (g->toolbar && g->toolbar->display_url)
error = xwimp_set_caret_position(
g->toolbar->toolbar_handle,
ICON_TOOLBAR_URL, -1, -1, -1, 0);
@@ -291,7 +288,7 @@ void gui_window_destroy(struct gui_window *g)
if (g->next)
g->next->prev = g->prev;
- ro_toolbar_destroy(g->toolbar);
+ ro_gui_theme_destroy_toolbar(g->toolbar);
/* delete window */
error = xwimp_delete_window(g->window);
@@ -715,9 +712,8 @@ void gui_window_set_extent(struct gui_window *g, int width, int height)
void gui_window_set_status(struct gui_window *g, const char *text)
{
- if (!g->toolbar)
+ if ((!g->toolbar) || (!g->toolbar->status_handle))
return;
-
ro_gui_set_icon_string(g->toolbar->status_handle,
ICON_STATUS_TEXT, text);
}
@@ -734,6 +730,7 @@ void gui_window_set_url(struct gui_window *g, const char *url)
{
wimp_caret caret;
os_error *error;
+ char *toolbar_url;
if (!g->toolbar)
return;
@@ -754,8 +751,10 @@ void gui_window_set_url(struct gui_window *g, const char *url)
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(g->url));
+ ICON_TOOLBAR_URL, 0, 0, -1, (int)strlen(toolbar_url));
if (error) {
LOG(("xwimp_set_caret_position: 0x%x: %s",
error->errnum, error->errmess));
@@ -765,6 +764,65 @@ void gui_window_set_url(struct gui_window *g, const char *url)
/**
+ * Forces all windows to be set to the current theme
+ *
+ * /param g the gui window to update
+ */
+void ro_gui_window_update_theme(void) {
+ int height;
+ struct gui_window *g;
+ for (g = window_list; g; g = g->next) {
+ if (g->toolbar) {
+ height = g->toolbar->height;
+ if (!ro_gui_theme_update_toolbar(NULL, g->toolbar)) {
+ ro_gui_theme_destroy_toolbar(g->toolbar);
+ g->toolbar = NULL;
+ if (height != 0)
+ ro_gui_window_update_dimensions(g, height);
+ } else {
+ if (height != g->toolbar->height)
+ ro_gui_window_update_dimensions(g, height -
+ g->toolbar->height);
+ }
+ ro_gui_prepare_navigate(g);
+ }
+ }
+ if (hotlist_toolbar) {
+ if (!ro_gui_theme_update_toolbar(NULL, hotlist_toolbar)) {
+ ro_gui_theme_destroy_toolbar(hotlist_toolbar);
+ hotlist_toolbar = NULL;
+ }
+ xwimp_force_redraw(hotlist_window, 0, -16384, 16384, 16384);
+ }
+
+}
+
+
+/**
+ * Forces the windows extent to be updated
+ *
+ * /param g the gui window to update
+ * /param yscroll an amount to scroll the vertical scroll bar by
+ */
+void ro_gui_window_update_dimensions(struct gui_window *g, int yscroll) {
+ os_error *error;
+ wimp_window_state state;
+ if (!g) return;
+ 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;
+ }
+ state.yscroll -= yscroll;
+ g->old_height = -1;
+ ro_gui_window_open(g, (wimp_open *)&state);
+/* gui_window_redraw_window(g); */
+}
+
+/**
* Open a window using the given wimp_open, handling toolbars and resizing.
*/
@@ -866,7 +924,7 @@ void ro_gui_window_open(struct gui_window *g, wimp_open *open)
}
if (g->toolbar)
- ro_theme_resize_toolbar(g->toolbar, g->window);
+ ro_gui_theme_process_toolbar(g->toolbar, -1);
}
@@ -878,21 +936,21 @@ void ro_gui_throb(void)
{
os_t t;
struct gui_window *g;
+ char throb_buf[12];
xos_read_monotonic_time(&t);
for (g = window_list; g; g = g->next) {
- if (!g->bw->throbbing || !g->toolbar || (g->toolbar->throbber_frames == 0))
- continue;
- if (t < g->throbtime + 10)
+ if (!g->bw->throbbing || !g->toolbar || !g->toolbar->display_throbber ||
+ !g->toolbar->theme || (t < g->throbtime + 10))
continue;
g->throbtime = t;
g->throbber++;
- if (g->toolbar->throbber_frames < g->throbber)
- g->throbber = 0;
- sprintf(g->throb_buf, "throbber%i", g->throbber);
- ro_gui_redraw_icon(g->toolbar->toolbar_handle,
- ICON_TOOLBAR_THROBBER);
+ if (g->toolbar->theme->throbber_frames < g->throbber)
+ g->throbber = 1;
+ sprintf(throb_buf, "throbber%i", g->throbber);
+ ro_gui_set_icon_string(g->toolbar->toolbar_handle,
+ ICON_TOOLBAR_THROBBER, throb_buf);
}
}
@@ -1174,10 +1232,14 @@ 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;
- strcpy(g->throb_buf, "throbber0");
- ro_gui_redraw_icon(g->toolbar->toolbar_handle, ICON_TOOLBAR_THROBBER);
+ if (g->toolbar) {
+ strcpy(throb_buf, "throbber0");
+ ro_gui_set_icon_string(g->toolbar->toolbar_handle,
+ ICON_TOOLBAR_THROBBER, throb_buf);
+ }
}
@@ -1240,6 +1302,7 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar)
wimp_window_state state;
int y;
char *url;
+ char *toolbar_url;
os_error *error;
wimp_pointer pointer;
url_func_result res;
@@ -1369,7 +1432,9 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar)
case wimp_KEY_RETURN:
if (!toolbar)
break;
- res = url_normalize(g->url, &url);
+ toolbar_url = ro_gui_get_icon_string(g->toolbar->toolbar_handle,
+ ICON_TOOLBAR_URL);
+ res = url_normalize(toolbar_url, &url);
if (res == URL_FUNC_OK) {
gui_window_set_url(g, url);
browser_window_go(g->bw, url);
@@ -1383,7 +1448,8 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar)
case 14: /* CTRL+N */
current_gui = g;
- browser_window_create(g->url, g->bw);
+ browser_window_create(current_gui->bw->current_content->url,
+ current_gui->bw);
return true;
case 18: /* CTRL+R */
browser_window_reload(g->bw, false);
@@ -1680,18 +1746,19 @@ void ro_gui_window_clone_options(struct browser_window *new_bw,
if (new_gui->toolbar) {
if ((old_gui) && (old_gui->toolbar)) {
new_gui->toolbar->status_width = old_gui->toolbar->status_width;
- new_gui->toolbar->status_window = old_gui->toolbar->status_window;
- new_gui->toolbar->standard_buttons = old_gui->toolbar->standard_buttons;
- new_gui->toolbar->url_bar = old_gui->toolbar->url_bar;
- new_gui->toolbar->throbber = old_gui->toolbar->throbber;
+ new_gui->toolbar->display_status = old_gui->toolbar->display_status;
+ 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;
} else {
new_gui->toolbar->status_width = option_toolbar_status_width;
- new_gui->toolbar->status_window = option_toolbar_show_status;
- new_gui->toolbar->standard_buttons = option_toolbar_show_buttons;
- new_gui->toolbar->url_bar = option_toolbar_show_address;
- new_gui->toolbar->throbber = option_toolbar_show_throbber;
+ new_gui->toolbar->display_status = option_toolbar_show_status;
+ 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_theme_update_toolbar(new_gui->toolbar, new_gui->window);
+ new_gui->toolbar->reformat_buttons = true;
+ ro_gui_theme_process_toolbar(new_gui->toolbar, -1);
}
}
@@ -1726,10 +1793,10 @@ void ro_gui_window_default_options(struct browser_window *bw) {
*/
if (gui->toolbar) {
option_toolbar_status_width = gui->toolbar->status_width;
- option_toolbar_show_status = gui->toolbar->status_window;
- option_toolbar_show_buttons = gui->toolbar->standard_buttons;
- option_toolbar_show_address = gui->toolbar->url_bar;
- option_toolbar_show_throbber = gui->toolbar->throbber;
+ option_toolbar_show_status = gui->toolbar->display_status;
+ option_toolbar_show_buttons = gui->toolbar->display_buttons;
+ option_toolbar_show_address = gui->toolbar->display_url;
+ option_toolbar_show_throbber = gui->toolbar->display_throbber;
}
}