diff options
author | Richard Wilson <rjw@netsurf-browser.org> | 2004-07-04 18:44:51 +0000 |
---|---|---|
committer | Richard Wilson <rjw@netsurf-browser.org> | 2004-07-04 18:44:51 +0000 |
commit | 5db1eae529dca654aa4591371918a07954824edb (patch) | |
tree | 14bb1326616c9209b76c8d2997fdc786d8f176f6 /riscos/hotlist.c | |
parent | a2960c79f23c51f0829457177f5d8eba9fa141c9 (diff) | |
download | netsurf-5db1eae529dca654aa4591371918a07954824edb.tar.gz netsurf-5db1eae529dca654aa4591371918a07954824edb.tar.bz2 |
[project @ 2004-07-04 18:44:51 by rjw]
Loading/saving of hotlists. Initial work for hotlist menu.
svn path=/import/netsurf/; revision=1046
Diffstat (limited to 'riscos/hotlist.c')
-rw-r--r-- | riscos/hotlist.c | 425 |
1 files changed, 329 insertions, 96 deletions
diff --git a/riscos/hotlist.c b/riscos/hotlist.c index f791d24aa..96297a62e 100644 --- a/riscos/hotlist.c +++ b/riscos/hotlist.c @@ -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); } @@ -1568,6 +1789,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 * * \param key the key pressed @@ -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; |