[project @ 2004-07-04 18:44:51 by rjw]

Loading/saving of hotlists. Initial work for hotlist menu.

svn path=/import/netsurf/; revision=1046
This commit is contained in:
Richard Wilson 2004-07-04 18:44:51 +00:00
parent a2960c79f2
commit 5db1eae529
5 changed files with 396 additions and 102 deletions

View File

@ -71,13 +71,14 @@ static clock_t gui_last_poll; /**< Time of last wimp_poll. */
osspriteop_area *gui_sprites; /**< Sprite area containing pointer and hotlist sprites */
/** Accepted wimp user messages. */
static wimp_MESSAGE_LIST(28) task_messages = { {
static wimp_MESSAGE_LIST(29) task_messages = { {
message_HELP_REQUEST,
message_DATA_SAVE,
message_DATA_SAVE_ACK,
message_DATA_LOAD,
message_DATA_OPEN,
message_MENU_WARNING,
message_MENUS_DELETED,
#ifdef WITH_URI
message_URI_PROCESS,
message_URI_RETURN_RESULT,
@ -386,6 +387,7 @@ void ro_gui_check_resolvers(void)
void gui_quit(void)
{
ro_gui_hotlist_save();
ro_gui_history_quit();
free(gui_sprites);
wimp_close_down(task_handle);
@ -834,6 +836,11 @@ void ro_gui_user_message(wimp_event_no event, wimp_message *message)
ro_gui_menu_warning((wimp_message_menu_warning *)
&message->data);
break;
case message_MENUS_DELETED:
if (current_menu == hotlist_menu) {
ro_gui_hotlist_menu_closed();
}
break;
#ifdef WITH_URI
case message_URI_PROCESS:

View File

@ -27,7 +27,7 @@ extern wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br,
dialog_debug;
extern wimp_w history_window;
extern wimp_w hotlist_window;
extern wimp_menu *iconbar_menu, *browser_menu, *combo_menu;
extern wimp_menu *iconbar_menu, *browser_menu, *combo_menu, *hotlist_menu;
extern int iconbar_menu_height;
extern struct form_control *current_gadget;
extern gui_window *window_list;
@ -177,6 +177,7 @@ void ro_gui_history_mouse_at(wimp_pointer *pointer);
/* in hotlist.c */
void ro_gui_hotlist_init(void);
void ro_gui_hotlist_save(void);
void ro_gui_hotlist_show(void);
void ro_gui_hotlist_add(char *title, struct content *content);
void ro_gui_hotlist_redraw(wimp_draw *redraw);
@ -184,6 +185,7 @@ void ro_gui_hotlist_click(wimp_pointer *pointer);
void ro_gui_hotlist_selection_drag_end(wimp_dragged *drag);
void ro_gui_hotlist_move_drag_end(wimp_dragged *drag);
bool ro_gui_hotlist_keypress(int key);
void ro_gui_hotlist_menu_closed(void);
/* in save.c */
void ro_gui_save_click(wimp_pointer *pointer);

View File

@ -33,6 +33,13 @@
#define HOTLIST_TEXT_BUFFER 256
#define HOTLIST_LEAF_INSET 32
#define HOTLIST_ICON_WIDTH 36
#define HOTLIST_LINE_HEIGHT 44
#define HOTLIST_TEXT_PADDING 16
#define HOTLIST_LOAD_BUFFER 1024
struct hotlist_entry {
/** The next hotlist entry at this level, or NULL for no more
@ -120,7 +127,7 @@ static wimp_window hotlist_window_definition = {
1,
1,
{"Hotlist"},
0,
0
};
/* An icon to plot text with
@ -165,11 +172,17 @@ static osspriteop_trans_tab *pixel_table;
*/
wimp_mouse_state drag_buttons;
/* Whether the current selection was from a menu click
*/
bool menu_selection = false;
/* Hotlist loading buffer
*/
char *load_buf;
static bool ro_gui_hotlist_load(void);
static void ro_gui_hotlist_save(void);
static bool ro_gui_hotlist_save_entry(FILE *fp, struct hotlist_entry entry);
static bool ro_gui_hotlist_load_entry(FILE *fp, struct hotlist_entry entry);
static bool ro_gui_hotlist_save_entry(FILE *fp, struct hotlist_entry *entry);
static bool ro_gui_hotlist_load_entry(FILE *fp, struct hotlist_entry *entry);
static void ro_gui_hotlist_link_entry(struct hotlist_entry *parent, struct hotlist_entry *entry);
static void ro_gui_hotlist_visited_update(struct content *content, struct hotlist_entry *entry);
static int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, int y0);
@ -184,18 +197,14 @@ static void ro_gui_hotlist_selection_drag(struct hotlist_entry *entry,
bool toggle, bool redraw);
static int ro_gui_hotlist_selection_count(struct hotlist_entry *entry);
static void ro_gui_hotlist_update_expansion(struct hotlist_entry *entry, bool only_selected,
bool expand, bool contract);
bool folders, bool links, bool expand, bool contract);
static void ro_gui_hotlist_launch_selection(struct hotlist_entry *entry);
static char *last_visit_to_string(time_t last_visit);
void ro_gui_hotlist_init(void) {
os_error *error;
/* Ensure we have a directory to save to later.
*/
xosfile_create_dir("<Choices$Write>.WWW", 0);
xosfile_create_dir("<Choices$Write>.WWW.NetSurf", 0);
/* Set the initial root options
*/
root.next_entry = NULL;
@ -206,7 +215,7 @@ void ro_gui_hotlist_init(void) {
/* Load the hotlist
*/
if (!ro_gui_hotlist_load()) {
return;
// return;
}
/* Get our sprite ids for faster plotting. This could be done in a
@ -291,7 +300,7 @@ void ro_gui_hotlist_show(void) {
if (!(state.flags & wimp_WINDOW_OPEN)) {
/* Clear the selection/expansion states
*/
ro_gui_hotlist_update_expansion(root.child_entry, false, false, true);
ro_gui_hotlist_update_expansion(root.child_entry, false, true, true, false, true);
ro_gui_hotlist_selection_state(root.child_entry, false, false);
/* Get the current screen size
@ -324,7 +333,8 @@ bool ro_gui_hotlist_load(void) {
fileswitch_object_type obj_type = 0;
struct hotlist_entry *netsurf;
struct hotlist_entry *entry;
bool success;
bool success = true;
bool found = false;
/* Check if we have an initial hotlist. OS_File does funny things relating to errors,
so we use the object type to determine success
@ -340,9 +350,34 @@ bool ro_gui_hotlist_load(void) {
return false;
}
/* Get some memory to work with
*/
load_buf = malloc(HOTLIST_LOAD_BUFFER);
if (!load_buf) {
warn_user("HotlistLoadError", 0);
fclose(fp);
return false;
}
/* Check for the opening <HTML> to vaguely validate our file
*/
if ((fgets(load_buf, HOTLIST_LOAD_BUFFER, fp) == NULL) ||
(strncmp("<html>", load_buf, 6) != 0)) {
warn_user("HotlistLoadError", 0);
free(load_buf);
fclose(fp);
return false;
}
/* Keep reading until we get to a <ul>
*/
while (!found && (fgets(load_buf, HOTLIST_LOAD_BUFFER, fp))) {
if (strncmp("<ul>", load_buf, 4) == 0) found = true;
}
/* Start our recursive load
*/
success = ro_gui_hotlist_load_entry(fp, root);
if (found) success = ro_gui_hotlist_load_entry(fp, &root);
/* Tell the user if we had any problems
*/
@ -352,6 +387,7 @@ bool ro_gui_hotlist_load(void) {
/* Close our file and return
*/
free(load_buf);
fclose(fp);
return success;
} else {
@ -377,6 +413,15 @@ bool ro_gui_hotlist_load(void) {
void ro_gui_hotlist_save(void) {
FILE *fp;
/* Don't save if we didn't load
*/
if (!hotlist_window) return;
/* Ensure we have a directory to save to later.
*/
xosfile_create_dir("<Choices$Write>.WWW", 0);
xosfile_create_dir("<Choices$Write>.WWW.NetSurf", 0);
/* Open our file
*/
fp = fopen("<Choices$Write>.WWW.NetSurf.Hotlist", "w");
@ -385,23 +430,158 @@ void ro_gui_hotlist_save(void) {
return;
}
/* HTML header
*/
fprintf(fp, "<html>\n<head>\n<title>Hotlist</title>\n<body>\n");
/* Start our recursive save
*/
if (!ro_gui_hotlist_save_entry(fp, root)) {
if (!ro_gui_hotlist_save_entry(fp, root.child_entry)) {
warn_user("HotlistSaveError", 0);
}
/* HTML footer
*/
fprintf(fp, "</body>\n</html>\n");
/* Close our file
*/
fclose(fp);
/* Set the filetype to HTML
*/
xosfile_set_type("<Choices$Write>.WWW.NetSurf.Hotlist", 0xfaf);
}
bool ro_gui_hotlist_save_entry(FILE *fp, struct hotlist_entry entry) {
return false;
bool ro_gui_hotlist_save_entry(FILE *fp, struct hotlist_entry *entry) {
if (!entry) return true;
/* We're starting a new child
*/
fprintf(fp, "<ul>\n");
/* Work through the entries
*/
while (entry) {
/* Save this entry
*/
if (entry->url) {
fprintf(fp, "<li><a href=\"%s\">%s</a>\n", entry->url, entry->title);
} else {
fprintf(fp, "<li>%s\n", entry->title);
}
fprintf(fp, "<!-- Title:%s -->\n", entry->title);
if (entry->url) {
fprintf(fp, "<!-- URL:%s -->\n", entry->url);
fprintf(fp, "<!-- Type:%i -->\n", entry->filetype);
}
if (entry->add_date != -1) fprintf(fp, "<!-- Added:%i -->\n", (int)entry->add_date);
if (entry->last_date != -1) fprintf(fp, "<!-- LastVisit:%i -->\n", (int)entry->last_date);
if (entry->visits != 0) fprintf(fp, "<!-- Visits:%i -->\n", entry->visits);
/* Continue onwards
*/
if (entry->child_entry) {
ro_gui_hotlist_save_entry(fp, entry->child_entry);
}
entry = entry->next_entry;
}
/* We're starting a new child
*/
fprintf(fp, "</ul>\n");
return true;
}
bool ro_gui_hotlist_load_entry(FILE *fp, struct hotlist_entry entry) {
return false;
bool ro_gui_hotlist_load_entry(FILE *fp, struct hotlist_entry *entry) {
struct hotlist_entry *last_entry = NULL;
char *title = NULL;
char *url = NULL;
int add_date = -1;
int last_date = -1;
int visits = 0;
int filetype = 0;
int val_length;
/* Check we can add to something
*/
if (entry == NULL) return false;
/* Keep reading until we get to a <ul>
*/
while (fgets(load_buf, HOTLIST_LOAD_BUFFER, fp)) {
/* Check if we should commit what we have
*/
if ((strncmp("<li>", load_buf, 4) == 0) ||
(strncmp("</ul>", load_buf, 5) == 0) ||
(strncmp("<ul>", load_buf, 4) == 0)) {
if (title != NULL) {
/* Add the entry
*/
last_entry = ro_gui_hotlist_create(title, url, filetype, entry);
last_entry->add_date = add_date;
if (last_entry->url) {
last_entry->last_date = last_date;
last_entry->visits = visits;
last_entry->filetype = filetype;
}
/* Reset for the next entry
*/
free(title);
title = NULL;
if (url) {
free(url);
url = NULL;
}
add_date = -1;
last_date = -1;
visits = 0;
filetype = 0;
}
}
/* Check if we've reached the end of our run
*/
if (strncmp("</ul>", load_buf, 5) == 0) return true;
/* Check for some data
*/
if (strncmp("<!-- ", load_buf, 5) == 0) {
val_length = strlen(load_buf) - 5 - 4;
load_buf[val_length + 5] = '\0';
if (strncmp("Title:", load_buf + 5, 6) == 0) {
if (title) free(title);
title = malloc(val_length);
if (!title) return false;
strcpy(title, load_buf + 5 + 6);
} else if (strncmp("URL:", load_buf + 5, 4) == 0) {
if (url) free(url);
url = malloc(val_length);
if (!url) return false;
strcpy(url, load_buf + 5 + 4);
} else if (strncmp("Added:", load_buf + 5, 6) == 0) {
add_date = atoi(load_buf + 5 + 6);
} else if (strncmp("LastVisit:", load_buf + 5, 10) == 0) {
last_date = atoi(load_buf + 5 + 10);
} else if (strncmp("Visits:", load_buf + 5, 7) == 0) {
visits = atoi(load_buf + 5 + 7);
} else if (strncmp("Type:", load_buf + 5, 5) == 0) {
filetype = atoi(load_buf + 5 + 5);
}
}
/* Check if we are starting a child
*/
if (strncmp("<ul>", load_buf, 4) == 0) {
if (!ro_gui_hotlist_load_entry(fp, last_entry)) {
return false;
}
}
}
return true;
}
/**
@ -674,8 +854,8 @@ void ro_gui_hotlist_update_entry_size(struct hotlist_entry *entry) {
/* Increase the text width by the borders
*/
entry->expanded_width = max_width + 32 + 36 + 16;
entry->collapsed_width += 32 + 36 + 16;
entry->expanded_width = max_width + HOTLIST_LEAF_INSET + HOTLIST_ICON_WIDTH + HOTLIST_TEXT_PADDING;
entry->collapsed_width += HOTLIST_LEAF_INSET + HOTLIST_ICON_WIDTH + HOTLIST_TEXT_PADDING;
reformat_pending = true;
}
@ -773,7 +953,7 @@ int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, i
/* Redraw the item
*/
height = ro_gui_hotlist_redraw_item(entry, level, x0 + 32, y0);
height = ro_gui_hotlist_redraw_item(entry, level, x0 + HOTLIST_LEAF_INSET, y0);
box_y0 = y0;
cumulative += height;
@ -782,7 +962,7 @@ int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, i
if (entry->children == -1) {
entry->height = height;
} else {
entry->height = 44;
entry->height = HOTLIST_LINE_HEIGHT;
}
entry->x0 = x0 - origin_x;
entry->y0 = y0 - origin_y - entry->height;
@ -807,11 +987,11 @@ int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, i
if (first && (level == 0)) {
xosspriteop_put_sprite_scaled(osspriteop_PTR,
gui_sprites, sprite[HOTLIST_BLINE],
x0 + 8, y0 - 44,
x0 + 8, y0 - HOTLIST_LINE_HEIGHT,
osspriteop_USE_MASK | osspriteop_USE_PALETTE,
0, pixel_table);
y0 -= 44;
height -= 44;
y0 -= HOTLIST_LINE_HEIGHT;
height -= HOTLIST_LINE_HEIGHT;
}
/* Draw the rest of the lines
@ -819,11 +999,11 @@ int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, i
while (height > 0) {
xosspriteop_put_sprite_scaled(osspriteop_PTR,
gui_sprites, sprite[HOTLIST_LINE],
x0 + 8, y0 - 44,
x0 + 8, y0 - HOTLIST_LINE_HEIGHT,
osspriteop_USE_MASK | osspriteop_USE_PALETTE,
0, pixel_table);
y0 -= 44;
height -= 44;
y0 -= HOTLIST_LINE_HEIGHT;
height -= HOTLIST_LINE_HEIGHT;
}
} else {
@ -835,8 +1015,8 @@ int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, i
x0 + 8, y0 - 22,
osspriteop_USE_MASK | osspriteop_USE_PALETTE,
0, pixel_table);
height -= 44;
y0 -= 44;
height -= HOTLIST_LINE_HEIGHT;
y0 -= HOTLIST_LINE_HEIGHT;
}
}
@ -889,17 +1069,17 @@ int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, i
* \return the height of the entry
*/
int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, int y0) {
int height = 44;
int height = HOTLIST_LINE_HEIGHT;
int line_y0;
int line_height;
/* Set the correct height
*/
if ((entry->children == -1) && (entry->expanded)) {
if (entry->url) height += 44;
if (entry->visits > 0) height += 44;
if (entry->add_date != -1) height += 44;
if (entry->last_date != -1) height += 44;
if (entry->url) height += HOTLIST_LINE_HEIGHT;
if (entry->visits > 0) height += HOTLIST_LINE_HEIGHT;
if (entry->add_date != -1) height += HOTLIST_LINE_HEIGHT;
if (entry->last_date != -1) height += HOTLIST_LINE_HEIGHT;
}
/* Check whether we need to redraw
@ -922,8 +1102,8 @@ int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, i
/* Draw our icon type
*/
sprite_icon.extent.x0 = x0 - origin_x;
sprite_icon.extent.x1 = x0 - origin_x + 36;
sprite_icon.extent.y0 = y0 - origin_y - 44;
sprite_icon.extent.x1 = x0 - origin_x + HOTLIST_ICON_WIDTH;
sprite_icon.extent.y0 = y0 - origin_y - HOTLIST_LINE_HEIGHT;
sprite_icon.extent.y1 = y0 - origin_y;
sprite_icon.data.indirected_sprite.id = (osspriteop_id)icon_name;
if (entry->children != -1) {
@ -954,9 +1134,9 @@ int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, i
/* Draw our textual information
*/
text_icon.data.indirected_text.text = entry->title;
text_icon.extent.x0 = x0 - origin_x + 36;
text_icon.extent.x1 = x0 - origin_x + entry->collapsed_width - 32;
text_icon.extent.y0 = y0 - origin_y - 42;
text_icon.extent.x0 = x0 - origin_x + HOTLIST_ICON_WIDTH;
text_icon.extent.x1 = x0 - origin_x + entry->collapsed_width - HOTLIST_LEAF_INSET;
text_icon.extent.y0 = y0 - origin_y - HOTLIST_LINE_HEIGHT + 2;
text_icon.extent.y1 = y0 - origin_y - 2;
xwimp_plot_icon(&text_icon);
@ -968,19 +1148,19 @@ int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, i
/* Draw our further information if expanded
*/
if ((entry->children == -1) && (entry->expanded) && (height > 44)) {
if ((entry->children == -1) && (entry->expanded) && (height > HOTLIST_LINE_HEIGHT)) {
text_icon.flags = wimp_ICON_TEXT | (wimp_COLOUR_DARK_GREY << wimp_ICON_FG_COLOUR_SHIFT) |
wimp_ICON_INDIRECTED | wimp_ICON_VCENTRED;
text_icon.extent.y0 = y0 - origin_y - 44;
text_icon.extent.y0 = y0 - origin_y - HOTLIST_LINE_HEIGHT;
text_icon.extent.y1 = y0 - origin_y;
/* Draw the lines
*/
y0 -= 44;
y0 -= HOTLIST_LINE_HEIGHT;
line_y0 = y0;
line_height = height - 44;
line_height = height - HOTLIST_LINE_HEIGHT;
while (line_height > 0) {
if (line_height == 44) {
if (line_height == HOTLIST_LINE_HEIGHT) {
xosspriteop_put_sprite_scaled(osspriteop_PTR,
gui_sprites, sprite[HOTLIST_TLINE],
x0 + 16, line_y0 - 22,
@ -989,7 +1169,7 @@ int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, i
} else {
xosspriteop_put_sprite_scaled(osspriteop_PTR,
gui_sprites, sprite[HOTLIST_LINE],
x0 + 16, line_y0 - 44,
x0 + 16, line_y0 - HOTLIST_LINE_HEIGHT,
osspriteop_USE_MASK | osspriteop_USE_PALETTE,
0, pixel_table);
@ -999,8 +1179,8 @@ int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, i
x0 + 8, line_y0 - 29,
osspriteop_USE_MASK | osspriteop_USE_PALETTE,
0, pixel_table);
line_height -= 44;
line_y0 -= 44;
line_height -= HOTLIST_LINE_HEIGHT;
line_y0 -= HOTLIST_LINE_HEIGHT;
}
/* Set the right extent of the icon to be big enough for anything
@ -1019,8 +1199,8 @@ int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, i
extended_text[254] = '.';
extended_text[255] = '\0';
}
text_icon.extent.y0 -= 44;
text_icon.extent.y1 -= 44;
text_icon.extent.y0 -= HOTLIST_LINE_HEIGHT;
text_icon.extent.y1 -= HOTLIST_LINE_HEIGHT;
xwimp_plot_icon(&text_icon);
}
@ -1029,8 +1209,8 @@ int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, i
if (entry->add_date != -1) {
snprintf(extended_text, HOTLIST_TEXT_BUFFER,
messages_get("HotlistAdd"), ctime(&entry->add_date));
text_icon.extent.y0 -= 44;
text_icon.extent.y1 -= 44;
text_icon.extent.y0 -= HOTLIST_LINE_HEIGHT;
text_icon.extent.y1 -= HOTLIST_LINE_HEIGHT;
xwimp_plot_icon(&text_icon);
}
@ -1039,8 +1219,8 @@ int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, i
if (entry->last_date != -1) {
snprintf(extended_text, HOTLIST_TEXT_BUFFER,
messages_get("HotlistLast"), ctime(&entry->last_date));
text_icon.extent.y0 -= 44;
text_icon.extent.y1 -= 44;
text_icon.extent.y0 -= HOTLIST_LINE_HEIGHT;
text_icon.extent.y1 -= HOTLIST_LINE_HEIGHT;
xwimp_plot_icon(&text_icon);
}
@ -1049,8 +1229,8 @@ int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, i
if (entry->visits > 0) {
snprintf(extended_text, HOTLIST_TEXT_BUFFER,
messages_get("HotlistVisits"), entry->visits);
text_icon.extent.y0 -= 44;
text_icon.extent.y1 -= 44;
text_icon.extent.y0 -= HOTLIST_LINE_HEIGHT;
text_icon.extent.y1 -= HOTLIST_LINE_HEIGHT;
xwimp_plot_icon(&text_icon);
}
}
@ -1060,7 +1240,7 @@ int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, i
*/
if ((entry->child_entry) && (entry->expanded)) {
height += ro_gui_hotlist_redraw_tree(entry->child_entry, level + 1,
x0 + 8, y0 - 44);
x0 + 8, y0 - HOTLIST_LINE_HEIGHT);
}
return height;
}
@ -1109,7 +1289,7 @@ void ro_gui_hotlist_click(wimp_pointer *pointer) {
(pointer->buttons == (wimp_CLICK_ADJUST << 8))) &&
(caret.w != state.w)) {
error = xwimp_set_caret_position(state.w, -1, -100,
-100, 32, -1);
-100, HOTLIST_LEAF_INSET, -1);
if (error) {
LOG(("xwimp_set_caret_position: 0x%x: %s",
error->errnum, error->errmess));
@ -1124,23 +1304,25 @@ void ro_gui_hotlist_click(wimp_pointer *pointer) {
*/
x_offset = x - entry->x0;
y_offset = y - (entry->y0 + entry->height);
if (((x_offset < 32) && (y_offset > -44)) || ((entry->children != -1) &&
if (((x_offset < HOTLIST_LEAF_INSET) && (y_offset > -HOTLIST_LINE_HEIGHT)) ||
((entry->children != -1) &&
((buttons == wimp_DOUBLE_SELECT) || (buttons == wimp_DOUBLE_ADJUST)))) {
ro_gui_hotlist_update_expansion(entry->child_entry, false, false, true);
ro_gui_hotlist_update_expansion(entry->child_entry, false, true, true, false, true);
ro_gui_hotlist_selection_state(entry->child_entry,
false, false);
entry->expanded = !entry->expanded;
if (x_offset >= 32) entry->selected = false;
if (x_offset >= HOTLIST_LEAF_INSET) entry->selected = false;
reformat_pending = true;
xwimp_force_redraw(hotlist_window,
0, -16384, 16384,
entry->y0 + entry->height);
} else if (x_offset >= 32) {
} else if (x_offset >= HOTLIST_LEAF_INSET) {
/* We treat a menu click as a Select click if we have no selections
*/
if (buttons == wimp_CLICK_MENU) {
if (ro_gui_hotlist_selection_count(root.child_entry) == 0) {
menu_selection = true;
buttons = (wimp_CLICK_SELECT << 8);
}
}
@ -1153,14 +1335,14 @@ void ro_gui_hotlist_click(wimp_pointer *pointer) {
false, true);
entry->selected = true;
xwimp_force_redraw(hotlist_window,
entry->x0, entry->y0 + entry->height - 44,
entry->x0, entry->y0 + entry->height - HOTLIST_LINE_HEIGHT,
entry->x0 + entry->width,
entry->y0 + entry->height);
}
} else if (buttons == (wimp_CLICK_ADJUST << 8)) {
entry->selected = !entry->selected;
xwimp_force_redraw(hotlist_window,
entry->x0, entry->y0 + entry->height - 44,
entry->x0, entry->y0 + entry->height - HOTLIST_LINE_HEIGHT,
entry->x0 + entry->width,
entry->y0 + entry->height);
@ -1192,9 +1374,10 @@ void ro_gui_hotlist_click(wimp_pointer *pointer) {
/* Create a menu if we should
*/
if (buttons == (wimp_CLICK_MENU << 8)) {
/* todo: menu */
return;
if (buttons == wimp_CLICK_MENU) {
/* ro_gui_create_menu(hotlist_menu, pointer->pos.x - 64,
pointer->pos.y, NULL);
*/ return;
}
/* Handle a click without an entry
@ -1266,20 +1449,20 @@ struct hotlist_entry *ro_gui_hotlist_find_entry(int x, int y, struct hotlist_ent
/* The top line extends all the way left
*/
if (y - (entry->y0 + entry->height) > -44) {
if (y - (entry->y0 + entry->height) > -HOTLIST_LINE_HEIGHT) {
if (x < (entry->x0 + entry->collapsed_width)) return entry;
return NULL;
}
/* No other entry can occupy the left edge
*/
inset_x = x - entry->x0 - 32 - 36;
inset_x = x - entry->x0 - HOTLIST_LEAF_INSET - HOTLIST_ICON_WIDTH;
if (inset_x < 0) return NULL;
/* Check the right edge against our various widths
*/
inset_y = -((y - entry->y0 - entry->height) / 44);
if (inset_x < (entry->widths[inset_y - 1] + 16)) return entry;
inset_y = -((y - entry->y0 - entry->height) / HOTLIST_LINE_HEIGHT);
if (inset_x < (entry->widths[inset_y - 1] + HOTLIST_TEXT_PADDING)) return entry;
return NULL;
}
@ -1325,7 +1508,7 @@ int ro_gui_hotlist_selection_state(struct hotlist_entry *entry, bool selected, b
*/
if (redraw) {
xwimp_force_redraw(hotlist_window,
entry->x0, entry->y0 + entry->height - 44,
entry->x0, entry->y0 + entry->height - HOTLIST_LINE_HEIGHT,
entry->x0 + entry->width,
entry->y0 + entry->height);
}
@ -1348,6 +1531,7 @@ int ro_gui_hotlist_selection_count(struct hotlist_entry *entry) {
/* Check we have an entry (only applies if we have an empty hotlist)
*/
if (!entry) return 0;
/* Get the first child entry
*/
while (entry) {
@ -1365,6 +1549,30 @@ int ro_gui_hotlist_selection_count(struct hotlist_entry *entry) {
return count;
}
void ro_gui_hotlist_launch_selection(struct hotlist_entry *entry) {
/* Check we have an entry (only applies if we have an empty hotlist)
*/
if (!entry) return;
/* Get the first child entry
*/
while (entry) {
/* Check this entry
*/
if ((entry->selected) && (entry->url)) {
browser_window_create(entry->url, NULL);
}
/* Continue onwards
*/
if (entry->child_entry) {
ro_gui_hotlist_launch_selection(entry->child_entry);
}
entry = entry->next_entry;
}
}
/**
* Toggles the expanded state for selected icons
@ -1372,11 +1580,13 @@ int ro_gui_hotlist_selection_count(struct hotlist_entry *entry) {
*
* \param entry the entry to update all siblings and descendants of
* \param only_selected whether to only update selected icons
* \param folders whether to update folders
* \param links whether to update links
* \param expand force all entries to be expanded (dominant)
* \param contract force all entries to be contracted (recessive)
*/
void ro_gui_hotlist_update_expansion(struct hotlist_entry *entry, bool only_selected,
bool expand, bool contract) {
bool folders, bool links, bool expand, bool contract) {
bool current;
/* Check we have an entry (only applies if we have an empty hotlist)
*/
@ -1389,20 +1599,25 @@ void ro_gui_hotlist_update_expansion(struct hotlist_entry *entry, bool only_sele
*/
if ((entry->selected) || (!only_selected)) {
current = entry->expanded;
/* Update the selection state
/* Only update what we should
*/
if (expand) {
entry->expanded = true;
} else if (contract) {
entry->expanded = false;
} else {
entry->expanded = !entry->expanded;
if (((links) && (entry->children != -1)) || ((folders) && (entry->children > 0))) {
/* Update the expansion state
*/
if (expand) {
entry->expanded = true;
} else if (contract) {
entry->expanded = false;
} else {
entry->expanded = !entry->expanded;
}
}
/* If we have contracted then we de-select and collapse any children
*/
if (entry->child_entry && !entry->expanded) {
ro_gui_hotlist_update_expansion(entry->child_entry, false, false, true);
ro_gui_hotlist_update_expansion(entry->child_entry, false, true, true, false, true);
ro_gui_hotlist_selection_state(entry->child_entry, false, false);
}
@ -1420,7 +1635,7 @@ void ro_gui_hotlist_update_expansion(struct hotlist_entry *entry, bool only_sele
*/
if (entry->child_entry && entry->expanded) {
ro_gui_hotlist_update_expansion(entry->child_entry,
only_selected, expand, contract);
only_selected, folders, links, expand, contract);
}
entry = entry->next_entry;
}
@ -1454,13 +1669,15 @@ void ro_gui_hotlist_selection_drag(struct hotlist_entry *entry,
while (entry) {
/* Check if this entry could possibly match
*/
if ((x1 > (entry->x0 + 32)) && (y0 > entry->y0) && (x0 < (entry->x0 + entry->width)) &&
if ((x1 > (entry->x0 + HOTLIST_LEAF_INSET)) && (y0 > entry->y0) &&
(x0 < (entry->x0 + entry->width)) &&
(y1 < (entry->y0 + entry->height))) {
do_update = false;
/* Check the exact area of the title line
*/
if ((x1 > (entry->x0 + 32)) && (y0 > entry->y0 + entry->height - 44) &&
if ((x1 > (entry->x0 + HOTLIST_LEAF_INSET)) &&
(y0 > entry->y0 + entry->height - HOTLIST_LINE_HEIGHT) &&
(x0 < (entry->x0 + entry->collapsed_width)) &&
(y1 < (entry->y0 + entry->height))) {
do_update = true;
@ -1469,19 +1686,22 @@ void ro_gui_hotlist_selection_drag(struct hotlist_entry *entry,
/* Check the other lines
*/
line = 1;
test_y = entry->y0 + entry->height - 44;
while (((line * 44) < entry->height) && (!do_update)) {
test_y = entry->y0 + entry->height - HOTLIST_LINE_HEIGHT;
while (((line * HOTLIST_LINE_HEIGHT) < entry->height) && (!do_update)) {
/* Check this line
*/
if ((x1 > (entry->x0 + 32 + 36)) && (y1 < test_y) && (y0 > test_y - 44) &&
(x0 < (entry->x0 + entry->widths[line - 1] + 32 + 36 + 16))) {
if ((x1 > (entry->x0 + HOTLIST_LEAF_INSET + HOTLIST_ICON_WIDTH)) &&
(y1 < test_y) && (y0 > test_y - HOTLIST_LINE_HEIGHT) &&
(x0 < (entry->x0 + entry->widths[line - 1] +
HOTLIST_LEAF_INSET + HOTLIST_ICON_WIDTH +
HOTLIST_TEXT_PADDING))) {
do_update = true;
}
/* Move to the next line
*/
line++;
test_y -= 44;
test_y -= HOTLIST_LINE_HEIGHT;
}
/* Redraw the entrys first line
@ -1494,7 +1714,8 @@ void ro_gui_hotlist_selection_drag(struct hotlist_entry *entry,
}
if (redraw) {
xwimp_force_redraw(hotlist_window,
entry->x0, entry->y0 + entry->height - 44,
entry->x0,
entry->y0 + entry->height - HOTLIST_LINE_HEIGHT,
entry->x0 + entry->width,
entry->y0 + entry->height);
}
@ -1567,6 +1788,16 @@ void ro_gui_hotlist_move_drag_end(wimp_dragged *drag) {
}
/**
* Handle a menu being closed
*/
void ro_gui_hotlist_menu_closed(void) {
if (menu_selection) {
ro_gui_hotlist_selection_state(root.child_entry, false, true);
menu_selection = false;
}
}
/**
* Handle a keypress
*
@ -1587,9 +1818,11 @@ bool ro_gui_hotlist_keypress(int key) {
ro_gui_hotlist_selection_state(root.child_entry, false, true);
return true;
case 32: /* SPACE */
ro_gui_hotlist_update_expansion(root.child_entry, true, false, false);
ro_gui_hotlist_update_expansion(root.child_entry, true, true, true, false, false);
return true;
case wimp_KEY_RETURN:
ro_gui_hotlist_launch_selection(root.child_entry);
return true;
case wimp_KEY_UP:
case wimp_KEY_DOWN:
case wimp_KEY_PAGE_UP:
@ -1606,13 +1839,13 @@ bool ro_gui_hotlist_keypress(int key) {
*/
state.w = hotlist_window;
wimp_get_window_state(&state);
y = state.visible.y1 - state.visible.y0 - 32;
y = state.visible.y1 - state.visible.y0 - HOTLIST_LEAF_INSET;
switch (key) {
case wimp_KEY_UP:
state.yscroll += 32;
state.yscroll += HOTLIST_LEAF_INSET;
break;
case wimp_KEY_DOWN:
state.yscroll -= 32;
state.yscroll -= HOTLIST_LEAF_INSET;
break;
case wimp_KEY_PAGE_UP:
state.yscroll += y;

View File

@ -220,7 +220,7 @@ static wimp_MENU(5) view_menu = {
/* Hotlist submenu
*/
static wimp_MENU(2) hotlist_menu = {
static wimp_MENU(2) hotlist_util_menu = {
{ "Hotlist" }, 7,2,7,0, 300, 44, 0,
{
{ 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HotlistAdd" } },
@ -234,7 +234,7 @@ static wimp_MENU(2) hotlist_menu = {
static wimp_MENU(4) utilities_menu = {
{ "Utilities" }, 7,2,7,0, 300, 44, 0,
{
{ wimp_MENU_LAST, (wimp_menu *)&hotlist_menu, DEFAULT_FLAGS, { "Hotlist" } },
{ wimp_MENU_LAST, (wimp_menu *)&hotlist_util_menu, DEFAULT_FLAGS, { "Hotlist" } },
/* { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "FindText" } },
{ 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HistLocal" } },
{ wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HistGlobal" } }
@ -273,6 +273,47 @@ static wimp_MENU(6) menu = {
wimp_menu *browser_menu = (wimp_menu *) &menu;
/* Hotlist file submenu
*/
static wimp_MENU(6) hotlist_file = {
{ "Hotlist" }, 7,2,7,0, 300, 44, 0,
{
{ 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Save" } },
{ wimp_MENU_SEPARATE, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Export" } },
{ 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "OpenDir" } },
{ 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "CloseDir" } },
{ 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "OpenLinks" } },
{ wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "CloseLinks" } }
}
};
/* Hotlist file submenu
*/
static wimp_MENU(3) hotlist_select = {
{ "Selection" }, 7,2,7,0, 300, 44, 0,
{
{ 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Save" } },
{ wimp_MENU_SEPARATE, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Launch" } },
{ wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Delete" } },
}
};
/* Hotlist menu
*/
static wimp_MENU(2) hotlist_root = {
{ "Hotlist" }, 7,2,7,0, 200, 44, 0,
{
{ 0, (wimp_menu *)&hotlist_file, DEFAULT_FLAGS, { "Hotlist" } },
{ wimp_MENU_LAST, (wimp_menu *)&hotlist_select, DEFAULT_FLAGS, { "Selection" } },
}
};
wimp_menu *hotlist_menu = (wimp_menu *)&hotlist_root;
static wimp_menu *browser_page_menu = (wimp_menu *)&page_menu;
static wimp_menu *browser_export_menu = (wimp_menu *)&export_menu;
static wimp_menu *browser_object_menu = (wimp_menu *)&object_menu;
@ -285,8 +326,10 @@ static wimp_menu *browser_image_menu = (wimp_menu *)&image_menu;
static wimp_menu *browser_toolbar_menu = (wimp_menu *)&toolbar_menu;
static wimp_menu *browser_window_menu = (wimp_menu *)&window_menu;
static wimp_menu *browser_utilities_menu = (wimp_menu *)&utilities_menu;
static wimp_menu *browser_hotlist_menu = (wimp_menu *)&hotlist_menu;
static wimp_menu *browser_hotlist_menu = (wimp_menu *)&hotlist_util_menu;
static wimp_menu *browser_help_menu = (wimp_menu *)&help_menu;
static wimp_menu *hotlist_file_menu = (wimp_menu *)&hotlist_file;
static wimp_menu *hotlist_select_menu = (wimp_menu *)&hotlist_select;
/**
@ -297,6 +340,7 @@ void ro_gui_menus_init(void)
{
translate_menu(iconbar_menu);
translate_menu(browser_menu);
translate_menu(hotlist_menu);
translate_menu(browser_page_menu);
translate_menu(browser_export_menu);
translate_menu(browser_object_menu);
@ -311,6 +355,8 @@ void ro_gui_menus_init(void)
translate_menu(browser_utilities_menu);
translate_menu(browser_hotlist_menu);
translate_menu(browser_help_menu);
translate_menu(hotlist_file_menu);
translate_menu(hotlist_select_menu);
iconbar_menu->entries[0].sub_menu = (wimp_menu *) dialog_info;
browser_page_menu->entries[0].sub_menu = (wimp_menu*) dialog_pageinfo;
@ -651,6 +697,10 @@ void ro_gui_menu_selection(wimp_selection *selection)
gui_gadget_combo(current_gui->data.browser.bw, current_gadget, (unsigned int)current_menu_x, (unsigned int)current_menu_y);
else
ro_gui_create_menu(current_menu, current_menu_x, current_menu_y, current_gui);
} else {
if (current_menu == hotlist_menu) {
ro_gui_hotlist_menu_closed();
}
}
}

View File

@ -128,7 +128,9 @@ struct toolbar *ro_toolbar_create(osspriteop_area *sprite_area, char *url_buffer
ro_toolbar_add_icon(toolbar, ro_toolbar_initialise_icon(sprite_area, "history", ICON_TOOLBAR_HISTORY));
ro_toolbar_add_icon(toolbar, ro_toolbar_initialise_icon(sprite_area, "scale", ICON_TOOLBAR_SCALE));
ro_toolbar_add_icon(toolbar, ro_toolbar_create_separator());
ro_toolbar_add_icon(toolbar, ro_toolbar_initialise_icon(sprite_area, "mark", ICON_TOOLBAR_BOOKMARK));
if (hotlist_window) {
ro_toolbar_add_icon(toolbar, ro_toolbar_initialise_icon(sprite_area, "mark", ICON_TOOLBAR_BOOKMARK));
}
ro_toolbar_add_icon(toolbar, ro_toolbar_initialise_icon(sprite_area, "save", ICON_TOOLBAR_SAVE));
/* ro_toolbar_add_icon(toolbar, ro_toolbar_initialise_icon(sprite_area, "print", ICON_TOOLBAR_PRINT)); */
}