NetSurf
con_theme.c
Go to the documentation of this file.
1/*
2 * Copyright 2006 Richard Wilson <info@tinct.net>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <assert.h>
20#include <stdlib.h>
21#include <string.h>
22#include <oslib/osspriteop.h>
23#include <oslib/wimp.h>
24#include <oslib/wimpspriteop.h>
25
26#include "utils/config.h"
27#include "utils/nsoption.h"
28#include "utils/log.h"
29#include "utils/messages.h"
30
31#include "riscos/gui.h"
33#include "riscos/configure.h"
34#include "riscos/dialog.h"
35#include "riscos/menus.h"
36#include "riscos/theme.h"
37#include "riscos/toolbar.h"
38#include "riscos/url_complete.h"
39#include "riscos/wimp.h"
40#include "riscos/wimp_event.h"
41#include "riscos/wimputils.h"
42
43
44#define THEME_PANE_AREA 0
45#define THEME_DEFAULT_BUTTON 2
46#define THEME_CANCEL_BUTTON 3
47#define THEME_OK_BUTTON 4
48
54};
55
56static wimp_window theme_pane_definition = {
57 {0, 0, 16, 16},
58 0,
59 0,
60 wimp_TOP,
61 wimp_WINDOW_NEW_FORMAT | wimp_WINDOW_VSCROLL | wimp_WINDOW_AUTO_REDRAW,
62 wimp_COLOUR_BLACK,
63 wimp_COLOUR_LIGHT_GREY,
64 wimp_COLOUR_LIGHT_GREY,
65 wimp_COLOUR_VERY_LIGHT_GREY,
66 wimp_COLOUR_DARK_GREY,
67 wimp_COLOUR_MID_LIGHT_GREY,
68 wimp_COLOUR_CREAM,
69 0,
70 {0, -16384, 16384, 0},
71 wimp_ICON_TEXT | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED,
72 wimp_BUTTON_CLICK << wimp_ICON_BUTTON_TYPE_SHIFT,
73 wimpspriteop_AREA,
74 1,
75 1,
76 {""},
77 0,
78 {}
79};
80
81
82static wimp_w theme_pane;
83static struct theme_descriptor *theme_list = NULL;
84static struct toolbar_display *toolbars = NULL;
85static char theme_radio_validation[] = "Sradiooff,radioon";
86static char theme_null_validation[] = "";
87static char theme_line_validation[] = "R2";
88
89static bool ro_gui_options_theme_ok(wimp_w w);
90static bool ro_gui_options_theme_click(wimp_pointer *pointer);
91static void ro_gui_options_theme_load(void);
92static void ro_gui_options_theme_free(void);
93
95{
96 wimp_window_state state;
97 wimp_icon_state icon_state;
98 os_error *error;
99 struct theme_descriptor *theme_choice;
100 struct toolbar_display *toolbar;
101
102 /* only allow one instance for now*/
103 if (theme_pane)
104 return false;
105 error = xwimp_create_window(&theme_pane_definition, &theme_pane);
106 if (error) {
107 NSLOG(netsurf, INFO, "xwimp_create_window: 0x%x: %s",
108 error->errnum, error->errmess);
109 return false;
110 }
111 state.w = w;
112 error = xwimp_get_window_state(&state);
113 if (error) {
114 NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
115 error->errnum, error->errmess);
116 return false;
117 }
118 icon_state.w = w;
119 icon_state.i = THEME_PANE_AREA;
120 error = xwimp_get_icon_state(&icon_state);
121 if (error) {
122 NSLOG(netsurf, INFO, "xwimp_get_icon_state: 0x%x: %s",
123 error->errnum, error->errmess);
124 return false;
125 }
126 state.w = theme_pane;
127 state.visible.x1 = state.visible.x0 + icon_state.icon.extent.x1 - 16 -
129 state.visible.x0 += icon_state.icon.extent.x0 + 16;
130 state.visible.y0 = state.visible.y1 + icon_state.icon.extent.y0 + 16;
131 state.visible.y1 += icon_state.icon.extent.y1 - 28;
132 NSLOG(netsurf, INFO, "Y0 = %i, y1 = %i", icon_state.icon.extent.y0,
133 icon_state.icon.extent.y1);
134 error = xwimp_open_window_nested(PTR_WIMP_OPEN(&state), w,
135 wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
136 << wimp_CHILD_XORIGIN_SHIFT |
137 wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
138 << wimp_CHILD_YORIGIN_SHIFT |
139 wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
140 << wimp_CHILD_LS_EDGE_SHIFT |
141 wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
142 << wimp_CHILD_BS_EDGE_SHIFT |
143 wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
144 << wimp_CHILD_RS_EDGE_SHIFT |
145 wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
146 << wimp_CHILD_TS_EDGE_SHIFT);
147 if (error) {
148 NSLOG(netsurf, INFO, "xwimp_open_window_nested: 0x%x: %s",
149 error->errnum, error->errmess);
150 return false;
151 }
152
153 /* load themes */
155
156 /* set the current selection */
157 theme_choice = ro_gui_theme_find(nsoption_charp(theme));
158 if (!theme_choice)
159 theme_choice = ro_gui_theme_find("Aletheia");
162 (toolbar->descriptor == theme_choice));
165
170 ro_gui_wimp_event_set_help_prefix(w, "HelpThemeConfig");
172
173 return true;
174}
175
177{
179 if (theme_pane) {
180 os_error *error;
182 error = xwimp_delete_window(theme_pane);
183 if (error) {
184 NSLOG(netsurf, INFO, "xwimp_delete_window: 0x%x: %s",
185 error->errnum, error->errmess);
186 ro_warn_user("WimpError", error->errmess);
187 }
188 theme_pane = 0;
189 }
191}
192
194{
195 struct toolbar_display *toolbar;
196 struct theme_descriptor *theme_new = NULL;
197
198 /* find the current selection */
201 theme_new = toolbar->descriptor;
202 break;
203 }
204 }
205
206 /* set the options */
207 if (theme_new) {
208 nsoption_set_charp(theme, strdup(theme_new->leafname));
209 ro_gui_theme_apply(theme_new);
210 } else {
212 }
214
215 /* store the pane status */
217 return true;
218}
219
220bool ro_gui_options_theme_click(wimp_pointer *pointer)
221{
222 struct theme_descriptor *theme_default;
223 struct toolbar_display *toolbar;
224
225 switch (pointer->i) {
227 theme_default = ro_gui_theme_find("Aletheia");
230 toolbar->icon_number,
231 (toolbar->descriptor == theme_default));
232 break;
235 break;
236 case THEME_OK_BUTTON:
238 break;
239 }
240 return false;
241}
242
244{
245 os_error *error;
246 os_box extent = { 0, 0, 0, 0 };
247 struct theme_descriptor *descriptor;
248 struct toolbar_display *link;
250 struct toolbar *toolbar;
251 wimp_icon_create new_icon;
252 wimp_window_state state;
253 int parent_width, nested_y, min_extent, base_extent;
254 int *radio_icons, *radio_set;
255 int theme_count;
256
257 /* delete our old list and get/open a new one */
261
262 /* create toolbars for each theme */
263 theme_count = 0;
264 descriptor = theme_list;
265 while (descriptor != NULL) {
266 /* try to create a toolbar */
267 toolbar = ro_toolbar_create(descriptor, NULL,
269 TOOLBAR_FLAGS_DISPLAY, NULL, NULL, NULL);
270 if (toolbar != NULL) {
272 nsoption_charp(toolbar_browser));
276 toolbar_display = calloc(sizeof(struct toolbar_display), 1);
277 if (!toolbar_display) {
278 NSLOG(netsurf, INFO, "No memory for calloc()");
279 ro_warn_user("NoMemory", 0);
280 return;
281 }
283 toolbar_display->descriptor = descriptor;
284 if (!toolbars) {
286 } else {
287 link = toolbars;
288 while (link->next) link = link->next;
289 link->next = toolbar_display;
290 }
291 theme_count++;
292 }
293 descriptor = descriptor->next;
294 }
295
296 /* nest the toolbars */
297 state.w = theme_pane;
298 error = xwimp_get_window_state(&state);
299 if (error) {
300 NSLOG(netsurf, INFO, "xwimp_get_window_state: 0x%x: %s",
301 error->errnum, error->errmess);
302 ro_warn_user("WimpError", error->errmess);
303 return;
304 }
305
306 parent_width = state.visible.x1 - state.visible.x0;
307 min_extent = state.visible.y0 - state.visible.y1;
308 nested_y = 0;
309 base_extent = state.visible.y1 - state.yscroll;
310 extent.x1 = parent_width;
311 link = toolbars;
312 new_icon.w = theme_pane;
313 new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED |
314 wimp_ICON_VCENTRED |
315 (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) |
316 (wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT);
317 while (link) {
318 /* update the toolbar */
319 int item_height = 44 + 44 + 16;
320 if (link->next) item_height += 16;
321 ro_toolbar_process(link->toolbar, parent_width, false);
322 extent.y0 = nested_y -
324 item_height;
325 if (link->next) extent.y0 -= 16;
326 if (extent.y0 > min_extent) extent.y0 = min_extent;
327 xwimp_set_extent(theme_pane, &extent);
328
329 /* create the descriptor icons and separator line */
330 new_icon.icon.extent.x0 = 8;
331 new_icon.icon.extent.x1 = parent_width - 8;
332 new_icon.icon.flags &= ~wimp_ICON_BORDER;
333 new_icon.icon.flags |= wimp_ICON_SPRITE;
334 new_icon.icon.extent.y1 = nested_y -
335 ro_toolbar_height(link->toolbar) - 8;
336 new_icon.icon.extent.y0 = nested_y -
337 ro_toolbar_height(link->toolbar) - 52;
338 new_icon.icon.data.indirected_text_and_sprite.text =
339 (char *)&link->descriptor->name;
340 new_icon.icon.data.indirected_text_and_sprite.size =
341 strlen(link->descriptor->name) + 1;
342 new_icon.icon.data.indirected_text_and_sprite.validation =
344 new_icon.icon.flags |= (wimp_BUTTON_RADIO <<
345 wimp_ICON_BUTTON_TYPE_SHIFT);
346 xwimp_create_icon(&new_icon, &link->icon_number);
347 new_icon.icon.flags &= ~wimp_ICON_SPRITE;
348 new_icon.icon.extent.x0 = 52;
349 new_icon.icon.extent.y1 -= 44;
350 new_icon.icon.extent.y0 -= 44;
351 new_icon.icon.data.indirected_text.text =
352 (char *)&link->descriptor->author;
353 new_icon.icon.data.indirected_text.size =
354 strlen(link->descriptor->author) + 1;
355 new_icon.icon.data.indirected_text.validation =
357 new_icon.icon.flags &= ~(wimp_BUTTON_RADIO <<
358 wimp_ICON_BUTTON_TYPE_SHIFT);
359 xwimp_create_icon(&new_icon, 0);
360 if (link->next) {
361 new_icon.icon.flags |= wimp_ICON_BORDER;
362 new_icon.icon.extent.x0 = -8;
363 new_icon.icon.extent.x1 = parent_width + 8;
364 new_icon.icon.extent.y1 -= 52;
365 new_icon.icon.extent.y0 = new_icon.icon.extent.y1 - 8;
366 new_icon.icon.data.indirected_text.text =
368 new_icon.icon.data.indirected_text.validation =
370 new_icon.icon.data.indirected_text.size = 1;
371 xwimp_create_icon(&new_icon, 0);
372 }
373
374 /* nest the toolbar window */
375 state.w = ro_toolbar_get_window(link->toolbar);
376 state.yscroll = 0;
377 state.visible.y1 = nested_y + base_extent;
378 state.visible.y0 = state.visible.y1 -
379 ro_toolbar_height(link->toolbar) + 2;
380 xwimp_open_window_nested(PTR_WIMP_OPEN(&state), theme_pane,
381 wimp_CHILD_LINKS_PARENT_WORK_AREA
382 << wimp_CHILD_BS_EDGE_SHIFT |
383 wimp_CHILD_LINKS_PARENT_WORK_AREA
384 << wimp_CHILD_TS_EDGE_SHIFT);
385
386 /* continue processing */
387 nested_y -= ro_toolbar_height(link->toolbar) +
388 item_height;
389 link = link->next;
390 }
391
392 /* set the icons as radios */
393 radio_icons = (int *)calloc(theme_count + 1, sizeof(int));
394 radio_set = radio_icons;
395 for (link = toolbars; link; link = link->next)
396 *radio_set++ = link->icon_number;
397 *radio_set = -1;
399
400 /* update our display */
401 xwimp_force_redraw(theme_pane, 0, -16384, 16384, 16384);
402}
403
405{
406 struct toolbar_display *toolbar;
407 struct toolbar_display *next_toolbar;
408
409 /* free all our toolbars */
410 next_toolbar = toolbars;
411 while ((toolbar = next_toolbar) != NULL) {
412 next_toolbar = toolbar->next;
413 xwimp_delete_icon(theme_pane, toolbar->icon_number);
414 xwimp_delete_icon(theme_pane, toolbar->icon_number + 1);
415 if (next_toolbar)
416 xwimp_delete_icon(theme_pane,
417 toolbar->icon_number + 2);
418 ro_toolbar_destroy(toolbar->toolbar);
419 free(toolbar);
420 }
421 toolbars = NULL;
422
423 /* close all our themes */
424 if (theme_list)
426 theme_list = NULL;
427}
static const struct button_bar_buttons brower_toolbar_buttons[]
Definition: button_bar.h:82
static bool ro_gui_options_theme_click(wimp_pointer *pointer)
Definition: con_theme.c:220
static wimp_window theme_pane_definition
Definition: con_theme.c:56
static wimp_w theme_pane
Definition: con_theme.c:82
bool ro_gui_options_theme_initialise(wimp_w w)
Definition: con_theme.c:94
static char theme_radio_validation[]
Definition: con_theme.c:85
#define THEME_DEFAULT_BUTTON
Definition: con_theme.c:45
static bool ro_gui_options_theme_ok(wimp_w w)
Definition: con_theme.c:193
void ro_gui_options_theme_finalise(wimp_w w)
Definition: con_theme.c:176
#define THEME_PANE_AREA
Definition: con_theme.c:44
#define THEME_OK_BUTTON
Definition: con_theme.c:47
static struct toolbar_display * toolbars
Definition: con_theme.c:84
static void ro_gui_options_theme_load(void)
Definition: con_theme.c:243
#define THEME_CANCEL_BUTTON
Definition: con_theme.c:46
static struct theme_descriptor * theme_list
Definition: con_theme.c:83
static char theme_line_validation[]
Definition: con_theme.c:87
static void ro_gui_options_theme_free(void)
Definition: con_theme.c:404
static char theme_null_validation[]
Definition: con_theme.c:86
Automated RISC OS WIMP event handling (interface).
RISC OS option setting (interface).
void ro_gui_save_options(void)
Save the current options.
Definition: dialog.c:670
Window themes(interface).
@ THEME_STYLE_BROWSER_TOOLBAR
Definition: theme.h:33
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
Localised message support (interface).
nserror ro_warn_user(const char *warning, const char *detail)
Display a warning for a serious problem (eg memory exhaustion).
Definition: gui.c:2217
bool ro_gui_theme_open(struct theme_descriptor *descriptor, bool list)
Opens a theme ready for use.
Definition: theme.c:488
void ro_gui_theme_close(struct theme_descriptor *descriptor, bool list)
Closes a theme after use.
Definition: theme.c:695
struct theme_descriptor * ro_gui_theme_get_available(void)
Reads and caches the currently available themes.
Definition: theme.c:125
struct theme_descriptor * ro_gui_theme_find(const char *leafname)
Finds a theme from the cached values.
Definition: theme.c:100
bool ro_gui_theme_apply(struct theme_descriptor *descriptor)
Applies the theme to all current windows and subsequent ones.
Definition: theme.c:666
wimp_w ro_toolbar_get_window(struct toolbar *toolbar)
Return the RO window handle of a toolbar.
Definition: toolbar.c:1511
bool ro_toolbar_add_buttons(struct toolbar *toolbar, const struct button_bar_buttons buttons[], char *button_order)
Add a button bar to a toolbar, and configure the buttons.
Definition: toolbar.c:273
int ro_toolbar_height(struct toolbar *toolbar)
Return the current height of a toolbar, allowing for available window space.
Definition: toolbar.c:1519
void ro_toolbar_destroy(struct toolbar *toolbar)
Destroy a toolbar after use.
Definition: toolbar.c:947
bool ro_toolbar_process(struct toolbar *toolbar, int width, bool reformat)
Process a toolbar, updating its contents for a size or content change.
Definition: toolbar.c:588
bool ro_toolbar_add_throbber(struct toolbar *toolbar)
Add a throbber to a toolbar.
Definition: toolbar.c:308
bool ro_toolbar_rebuild(struct toolbar *toolbar)
(Re-)build a toolbar to use the specified (or current) theme.
Definition: toolbar.c:346
struct toolbar * ro_toolbar_create(struct theme_descriptor *descriptor, wimp_w parent, theme_style style, toolbar_flags bar_flags, const struct toolbar_callbacks *callbacks, void *client_data, const char *help)
Create a new toolbar, ready to have widgets added and to be attached to a window.
Definition: toolbar.c:219
bool ro_toolbar_add_url(struct toolbar *toolbar)
Add a URL bar to a toolbar.
Definition: toolbar.c:327
Window toolbars (interface).
@ TOOLBAR_FLAGS_DISPLAY
Definition: toolbar.h:35
Interface to utility string handling.
char * leafname
theme leafname
Definition: theme.h:73
char name[32]
theme name
Definition: theme.h:75
struct theme_descriptor * next
next descriptor in the list
Definition: theme.h:87
char author[64]
theme author
Definition: theme.h:76
Definition: theme.h:64
struct toolbar * toolbar
Definition: con_theme.c:50
struct theme_descriptor * descriptor
Definition: con_theme.c:51
struct toolbar_display * next
Definition: con_theme.c:53
struct toolbar * next
The next bar in the toolbar list.
Definition: toolbar.c:127
Central repository for URL data (interface).
Option reading and saving interface.
#define nsoption_charp(OPTION)
Get the value of a string option.
Definition: nsoption.h:297
#define nsoption_set_charp(OPTION, VALUE)
set string option in default table
Definition: nsoption.h:338
void ro_gui_set_icon_selected_state(wimp_w w, wimp_i i, bool state)
Set the selected state of an icon.
Definition: wimp.c:444
bool ro_gui_get_icon_selected_state(wimp_w w, wimp_i i)
Gets the selected state of an icon.
Definition: wimp.c:463
int ro_get_vscroll_width(wimp_w w)
Gets the vertical scrollbar width.
Definition: wimp.c:70
General RISC OS WIMP/OS library functions (interface).
bool ro_gui_wimp_event_set_help_prefix(wimp_w w, const char *help_prefix)
Set the associated help prefix for a given window.
Definition: wimp_event.c:390
void ro_gui_wimp_event_finalise(wimp_w w)
Free any resources associated with a window.
Definition: wimp_event.c:296
bool ro_gui_wimp_event_register_cancel(wimp_w w, wimp_i i)
Register a function to be called for the Cancel action on a window.
Definition: wimp_event.c:1403
bool ro_gui_wimp_event_memorise(wimp_w w)
Memorises the current state of any registered components in a window.
Definition: wimp_event.c:139
bool ro_gui_wimp_event_register_mouse_click(wimp_w w, bool(*callback)(wimp_pointer *pointer))
Register a function to be called for all mouse-clicks to icons in a window that don't have registered...
Definition: wimp_event.c:1439
bool ro_gui_wimp_event_restore(wimp_w w)
Restore the state of any registered components in a window to their memorised state.
Definition: wimp_event.c:186
bool ro_gui_wimp_event_register_ok(wimp_w w, wimp_i i, bool(*callback)(wimp_w w))
Register a function to be called for the OK action on a window.
Definition: wimp_event.c:1417
bool ro_gui_wimp_event_register_radio(wimp_w w, wimp_i *i)
Register a group of radio icons to be automatically handled.
Definition: wimp_event.c:1363
Automated RISC OS WIMP event handling (interface).
A collection of grubby utilities for working with OSLib's wimp API.
#define PTR_WIMP_OPEN(pstate)
Definition: wimputils.h:39