From cde05b7d9f828ffb3869130ec250ad528894195d Mon Sep 17 00:00:00 2001 From: Chris Young Date: Sat, 18 Oct 2008 13:56:12 +0000 Subject: [PATCH] Basic theme support. NetSurf will use the theme pointed to by the Options file "theme:". Default is Resources/Themes/Default This directory must contain a file called Theme which indicates which files should be used for which images. The number of frames in the Throbber must also be specified here. See Resources/Themes/Default/Theme for an example. svn path=/trunk/netsurf/; revision=5592 --- amiga/dist/NetSurf.guide | 4 +- amiga/gui.c | 79 +++++----- amiga/options.h | 144 +++++++++--------- .../Themes/AISS/NetSurf.info} | Bin amiga/resources/Themes/AISS/Theme | 21 +++ amiga/resources/Themes/AISS/Throbber | Bin 0 -> 5443 bytes amiga/resources/Themes/Default/Theme | 36 +++++ amiga/resources/{ => Themes/Default}/Throbber | Bin 8 files changed, 171 insertions(+), 113 deletions(-) rename amiga/{dist/NetSurf_alt.info => resources/Themes/AISS/NetSurf.info} (100%) create mode 100755 amiga/resources/Themes/AISS/Theme create mode 100644 amiga/resources/Themes/AISS/Throbber create mode 100755 amiga/resources/Themes/Default/Theme rename amiga/resources/{ => Themes/Default}/Throbber (100%) diff --git a/amiga/dist/NetSurf.guide b/amiga/dist/NetSurf.guide index b341a6ba9..8f88477d0 100755 --- a/amiga/dist/NetSurf.guide +++ b/amiga/dist/NetSurf.guide @@ -27,10 +27,10 @@ The options file is stored in Resources/Options by default. The following optio @{b}hotlist_file@{ub} Path to Hotlist file @{b}use_workbench@{ub} Open NetSurf in a window on Workbench screen (default is to open a custom screen) @{b}screen_modeid@{ub} Mode ID for NetSurf's custom screen -@{b}toolbar_images@{ub} Path to toolbar images (default is TBImages:, which is AISS - see http://www.masonicons.de) +@{b}theme@{ub} Path to theme (default is Resources/Themes/Default - an alternative included theme is Resources/Themes/AISS) @{b}no_iframes@{ub} Disable IFrames @{b}clipboard_write_utf8@{ub} Write UTF-8 strings to the clipboard along with a charset identifier (when this option is 0, NetSurf will convert copied strings to local charset) -@{b}throbber_frames@{ub} Number of frames in Resources/Throbber file (must be a flat image file with first image inactive) +@{b}throbber_frames@{ub} Not used (now in theme description file) @{b}truecolour_mouse_pointers@{ub} Use 32-bit mouse pointers, when disabled NetSurf will use old-style 4 colour images (see Resources/Pointers) @{b}os_mouse_pointers@{ub} Don't override default and busy mouse pointers @{b}always_open_tabs@{ub} Force opening tabs instead of windows (actually swaps the functions so ctrl-click now opens windows and middle mouse button opens tabs) diff --git a/amiga/gui.c b/amiga/gui.c index b4d734021..686526eaa 100755 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -106,7 +106,7 @@ struct Library *PopupMenuBase = NULL; struct PopupMenuIFace *IPopupMenu = NULL; struct BitMap *throbber = NULL; -ULONG throbber_width,throbber_height; +ULONG throbber_width,throbber_height,throbber_frames; static struct RastPort dummyrp; struct IFFHandle *iffh = NULL; @@ -151,7 +151,7 @@ static void *myrealloc(void *ptr, size_t len, void *pw); void gui_init(int argc, char** argv) { struct Locale *locale; - char lang[100]; + char lang[100],throbberfile[100]; bool found=FALSE; int i; BPTR lock=0,amiupdatefh; @@ -288,8 +288,8 @@ void gui_init(int argc, char** argv) if((!option_font_fantasy) || (option_font_fantasy[0] == '\0')) option_font_fantasy = (char *)strdup("DejaVu Serif"); - if((!option_toolbar_images) || (option_toolbar_images[0] == '\0')) - option_toolbar_images = (char *)strdup("TBImages:"); + if((!option_theme) || (option_theme[0] == '\0')) + option_theme = (char *)strdup("Resources/Themes/Default"); if(!option_window_width) option_window_width = 800; if(!option_window_height) option_window_height = 600; @@ -336,7 +336,14 @@ void gui_init(int argc, char** argv) ami_global_history_initialise(); ami_cookies_initialise(); - if(dto = NewDTObject("Resources/Throbber", + strcpy(&throbberfile,option_theme); + AddPart(&throbberfile,"Theme",100); + messages_load(throbberfile); + + ami_get_theme_filename(&throbberfile,"theme_throbber"); + throbber_frames=atoi(messages_get("theme_throbber_frames")); + + if(dto = NewDTObject(throbberfile, DTA_GroupID,GID_PICTURE, PDTA_DestMode,PMODE_V43, TAG_DONE)) @@ -346,7 +353,7 @@ void gui_init(int argc, char** argv) if(GetDTAttrs(dto,PDTA_BitMapHeader,&throbber_bmh,TAG_DONE)) { - throbber_width = throbber_bmh->bmh_Width / option_throbber_frames; + throbber_width = throbber_bmh->bmh_Width / throbber_frames; throbber_height = throbber_bmh->bmh_Height; InitRastPort(&throbber_rp); @@ -1096,6 +1103,16 @@ void ami_update_buttons(struct gui_window_2 *gwin) } } +void ami_get_theme_filename(char *filename,char *themestring) +{ + if(messages_get(themestring)[0] == '*') strncpy(filename,messages_get(themestring)+1,100); + else + { + strcpy(filename,option_theme); + AddPart(filename,messages_get(themestring),100); + } +} + struct gui_window *gui_create_browser_window(struct browser_window *bw, struct browser_window *clone, bool new_tab) { @@ -1269,38 +1286,22 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, gwin->shared->tabs=1; gwin->shared->next_tab=1; - strcpy(nav_west,option_toolbar_images); - strcpy(nav_west_s,option_toolbar_images); - strcpy(nav_west_g,option_toolbar_images); - strcpy(nav_east,option_toolbar_images); - strcpy(nav_east_s,option_toolbar_images); - strcpy(nav_east_g,option_toolbar_images); - strcpy(stop,option_toolbar_images); - strcpy(stop_s,option_toolbar_images); - strcpy(stop_g,option_toolbar_images); - strcpy(reload,option_toolbar_images); - strcpy(reload_s,option_toolbar_images); - strcpy(reload_g,option_toolbar_images); - strcpy(home,option_toolbar_images); - strcpy(home_s,option_toolbar_images); - strcpy(home_g,option_toolbar_images); - strcpy(closetab,option_toolbar_images); - AddPart(nav_west,"nav_west",100); - AddPart(nav_west_s,"nav_west_s",100); - AddPart(nav_west_g,"nav_west_g",100); - AddPart(nav_east,"nav_east",100); - AddPart(nav_east_s,"nav_east_s",100); - AddPart(nav_east_g,"nav_east_g",100); - AddPart(stop,"stop",100); - AddPart(stop_s,"stop_s",100); - AddPart(stop_g,"stop_g",100); - AddPart(reload,"reload",100); - AddPart(reload_s,"reload_s",100); - AddPart(reload_g,"reload_g",100); - AddPart(home,"home",100); - AddPart(home_s,"home_s",100); - AddPart(home_g,"home_g",100); - AddPart(closetab,"list_cancel",100); + ami_get_theme_filename(nav_west,"theme_nav_west"); + ami_get_theme_filename(nav_west_s,"theme_nav_west_s"); + ami_get_theme_filename(nav_west_g,"theme_nav_west_g"); + ami_get_theme_filename(nav_east,"theme_nav_east"); + ami_get_theme_filename(nav_east_s,"theme_nav_east_s"); + ami_get_theme_filename(nav_east_g,"theme_nav_east_g"); + ami_get_theme_filename(stop,"theme_stop"); + ami_get_theme_filename(stop_s,"theme_stop_s"); + ami_get_theme_filename(stop_g,"theme_stop_g"); + ami_get_theme_filename(reload,"theme_reload"); + ami_get_theme_filename(reload_s,"theme_reload_s"); + ami_get_theme_filename(reload_g,"theme_reload_g"); + ami_get_theme_filename(home,"theme_home"); + ami_get_theme_filename(home_s,"theme_home_s"); + ami_get_theme_filename(home_g,"theme_home_g"); + ami_get_theme_filename(closetab,"theme_closetab"); gwin->shared->objects[OID_MAIN] = WindowObject, WA_ScreenTitle,nsscreentitle, @@ -2180,7 +2181,7 @@ void ami_update_throbber(struct gui_window_2 *g) GetAttr(SPACE_AreaBox,g->gadgets[GID_THROBBER],(ULONG *)&bbox); g->throbber_frame++; - if(g->throbber_frame > (option_throbber_frames-1)) + if(g->throbber_frame > (throbber_frames-1)) g->throbber_frame=1; BltBitMapRastPort(throbber,throbber_width*g->throbber_frame,0,g->win->RPort,bbox->Left,bbox->Top,throbber_width,throbber_height,0x0C0); diff --git a/amiga/options.h b/amiga/options.h index 406a97b45..7a74c2b68 100644 --- a/amiga/options.h +++ b/amiga/options.h @@ -1,72 +1,72 @@ -/* - * Copyright 2008 Chris Young - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef AMIGA_OPTIONS_H -#define AMIGA_OPTIONS_H -#include "desktop/options.h" - -extern bool option_verbose_log; -extern char *option_url_file; -extern char *option_hotlist_file; -extern bool option_use_wb; -extern int option_modeid; -extern char *option_toolbar_images; -extern bool option_no_iframes; -extern bool option_utf8_clipboard; -extern int option_throbber_frames; -extern bool option_truecolour_mouse_pointers; -extern bool option_use_os_pointers; -extern bool option_force_tabs; -extern bool option_new_tab_active; -extern bool option_kiosk_mode; -extern char *option_recent_file; - -#define EXTRA_OPTION_DEFINE \ -bool option_verbose_log = false; \ -char *option_url_file = 0; \ -char *option_hotlist_file = 0; \ -bool option_use_wb = false; \ -int option_modeid = 0; \ -char *option_toolbar_images = 0; \ -bool option_no_iframes = false; \ -bool option_utf8_clipboard = false; \ -int option_throbber_frames = 1; \ -bool option_truecolour_mouse_pointers = true; \ -bool option_use_os_pointers = false; \ -bool option_force_tabs = false; \ -bool option_new_tab_active = false; \ -bool option_kiosk_mode = false; \ -char *option_recent_file = 0; \ - -#define EXTRA_OPTION_TABLE \ -{ "verbose_log", OPTION_BOOL, &option_verbose_log}, \ -{ "url_file", OPTION_STRING, &option_url_file }, \ -{ "hotlist_file", OPTION_STRING, &option_hotlist_file }, \ -{ "use_workbench", OPTION_BOOL, &option_use_wb}, \ -{ "screen_modeid", OPTION_INTEGER, &option_modeid}, \ -{ "toolbar_images", OPTION_STRING, &option_toolbar_images }, \ -{ "no_iframes", OPTION_BOOL, &option_no_iframes}, \ -{ "clipboard_write_utf8", OPTION_BOOL, &option_utf8_clipboard}, \ -{ "throbber_frames", OPTION_INTEGER, &option_throbber_frames}, \ -{ "truecolour_mouse_pointers", OPTION_BOOL, &option_truecolour_mouse_pointers}, \ -{ "os_mouse_pointers", OPTION_BOOL, &option_use_os_pointers}, \ -{ "always_open_tabs", OPTION_BOOL, &option_force_tabs}, \ -{ "new_tab_is_active", OPTION_BOOL, &option_new_tab_active}, \ -{ "kiosk_mode", OPTION_BOOL, &option_kiosk_mode}, \ -{ "recent_file", OPTION_STRING, &option_recent_file }, -#endif +/* + * Copyright 2008 Chris Young + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef AMIGA_OPTIONS_H +#define AMIGA_OPTIONS_H +#include "desktop/options.h" + +extern bool option_verbose_log; +extern char *option_url_file; +extern char *option_hotlist_file; +extern bool option_use_wb; +extern int option_modeid; +extern char *option_theme; +extern bool option_no_iframes; +extern bool option_utf8_clipboard; +extern int option_throbber_frames; // unused +extern bool option_truecolour_mouse_pointers; +extern bool option_use_os_pointers; +extern bool option_force_tabs; +extern bool option_new_tab_active; +extern bool option_kiosk_mode; +extern char *option_recent_file; + +#define EXTRA_OPTION_DEFINE \ +bool option_verbose_log = false; \ +char *option_url_file = 0; \ +char *option_hotlist_file = 0; \ +bool option_use_wb = false; \ +int option_modeid = 0; \ +char *option_theme = 0; \ +bool option_no_iframes = false; \ +bool option_utf8_clipboard = false; \ +int option_throbber_frames = 1; \ +bool option_truecolour_mouse_pointers = true; \ +bool option_use_os_pointers = false; \ +bool option_force_tabs = false; \ +bool option_new_tab_active = false; \ +bool option_kiosk_mode = false; \ +char *option_recent_file = 0; \ + +#define EXTRA_OPTION_TABLE \ +{ "verbose_log", OPTION_BOOL, &option_verbose_log}, \ +{ "url_file", OPTION_STRING, &option_url_file }, \ +{ "hotlist_file", OPTION_STRING, &option_hotlist_file }, \ +{ "use_workbench", OPTION_BOOL, &option_use_wb}, \ +{ "screen_modeid", OPTION_INTEGER, &option_modeid}, \ +{ "theme", OPTION_STRING, &option_theme}, \ +{ "no_iframes", OPTION_BOOL, &option_no_iframes}, \ +{ "clipboard_write_utf8", OPTION_BOOL, &option_utf8_clipboard}, \ +{ "throbber_frames", OPTION_INTEGER, &option_throbber_frames}, \ +{ "truecolour_mouse_pointers", OPTION_BOOL, &option_truecolour_mouse_pointers}, \ +{ "os_mouse_pointers", OPTION_BOOL, &option_use_os_pointers}, \ +{ "always_open_tabs", OPTION_BOOL, &option_force_tabs}, \ +{ "new_tab_is_active", OPTION_BOOL, &option_new_tab_active}, \ +{ "kiosk_mode", OPTION_BOOL, &option_kiosk_mode}, \ +{ "recent_file", OPTION_STRING, &option_recent_file }, +#endif diff --git a/amiga/dist/NetSurf_alt.info b/amiga/resources/Themes/AISS/NetSurf.info similarity index 100% rename from amiga/dist/NetSurf_alt.info rename to amiga/resources/Themes/AISS/NetSurf.info diff --git a/amiga/resources/Themes/AISS/Theme b/amiga/resources/Themes/AISS/Theme new file mode 100755 index 000000000..2e9cf28b6 --- /dev/null +++ b/amiga/resources/Themes/AISS/Theme @@ -0,0 +1,21 @@ +# AISS theme. Requires AISS to be installed (see http://www.masonicons.de) +# Throbber animation by Martin Merz +# +theme_nav_west:*TBImages:nav_west +theme_nav_west_s:*TBImages:nav_west_s +theme_nav_west_g:*TBImages:nav_west_g +theme_nav_east:*TBImages:nav_east +theme_nav_east_s:*TBImages:nav_east_s +theme_nav_east_g:*TBImages:nav_east_g +theme_stop:*TBImages:stop +theme_stop_s:*TBImages:stop_s +theme_stop_g:*TBImages:stop_g +theme_reload:*TBImages:reload +theme_reload_s:*TBImages:reload_s +theme_reload_g:*TBImages:reload_g +theme_home:*TBImages:home +theme_home_s:*TBImages:home_s +theme_home_g:*TBImages:home_g +theme_closetab:*TBImages:list_cancel +theme_throbber:Throbber +theme_throbber_frames:13 diff --git a/amiga/resources/Themes/AISS/Throbber b/amiga/resources/Themes/AISS/Throbber new file mode 100644 index 0000000000000000000000000000000000000000..a8c38d153f4334f688a5b9bf61c65caf299c5781 GIT binary patch literal 5443 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