summaryrefslogtreecommitdiff
path: root/riscos
diff options
context:
space:
mode:
authorRichard Wilson <rjw@netsurf-browser.org>2004-07-03 17:30:28 +0000
committerRichard Wilson <rjw@netsurf-browser.org>2004-07-03 17:30:28 +0000
commitc499ad907dc2d77bf9cf40fd099b2025766b6bc6 (patch)
tree2fb9651eecc9643c67ccf49ea136d39a1626d87c /riscos
parent7212736a622bb32d213261470e2286400f1fa6af (diff)
downloadnetsurf-c499ad907dc2d77bf9cf40fd099b2025766b6bc6.tar.gz
netsurf-c499ad907dc2d77bf9cf40fd099b2025766b6bc6.tar.bz2
[project @ 2004-07-03 17:30:27 by rjw]
Further development of the selection and display code. svn path=/import/netsurf/; revision=1042
Diffstat (limited to 'riscos')
-rw-r--r--riscos/gui.c9
-rw-r--r--riscos/gui.h6
-rw-r--r--riscos/hotlist.c650
-rw-r--r--riscos/window.c1
4 files changed, 499 insertions, 167 deletions
diff --git a/riscos/gui.c b/riscos/gui.c
index d1c3ee24e..fcc3d2f26 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -751,7 +751,14 @@ void ro_gui_drag_end(wimp_dragged *drag)
break;
case GUI_DRAG_STATUS_RESIZE:
-// ro_gui_save_drag_end(drag);
+ break;
+
+ case GUI_DRAG_HOTLIST_SELECT:
+ ro_gui_hotlist_selection_drag_end(drag);
+ break;
+
+ case GUI_DRAG_HOTLIST_MOVE:
+ ro_gui_hotlist_move_drag_end(drag);
break;
}
}
diff --git a/riscos/gui.h b/riscos/gui.h
index 09f7e3c55..cf27ffdb1 100644
--- a/riscos/gui.h
+++ b/riscos/gui.h
@@ -46,7 +46,8 @@ typedef enum { GUI_SAVE_SOURCE, GUI_SAVE_DRAW, GUI_SAVE_TEXT,
GUI_SAVE_LINK_TEXT } gui_save_type;
extern gui_save_type gui_current_save_type;
typedef enum { GUI_DRAG_SELECTION, GUI_DRAG_DOWNLOAD_SAVE,
- GUI_DRAG_SAVE, GUI_DRAG_STATUS_RESIZE } gui_drag_type;
+ GUI_DRAG_SAVE, GUI_DRAG_STATUS_RESIZE,
+ GUI_DRAG_HOTLIST_SELECT, GUI_DRAG_HOTLIST_MOVE } gui_drag_type;
extern gui_drag_type gui_current_drag_type;
struct gui_window {
@@ -178,9 +179,10 @@ void ro_gui_history_mouse_at(wimp_pointer *pointer);
void ro_gui_hotlist_init(void);
void ro_gui_hotlist_show(void);
void ro_gui_hotlist_add(char *title, struct content *content);
-void ro_gui_hotlist_visited(struct content *content);
void ro_gui_hotlist_redraw(wimp_draw *redraw);
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);
/* in save.c */
void ro_gui_save_click(wimp_pointer *pointer);
diff --git a/riscos/hotlist.c b/riscos/hotlist.c
index aaacc4448..de89766fa 100644
--- a/riscos/hotlist.c
+++ b/riscos/hotlist.c
@@ -14,13 +14,13 @@
#include <stdlib.h>
#include <time.h>
#include "oslib/colourtrans.h"
-#include "oslib/osword.h"
#include "oslib/wimp.h"
#include "oslib/wimpspriteop.h"
#include "netsurf/content/content.h"
#include "netsurf/riscos/gui.h"
#include "netsurf/riscos/wimp.h"
#include "netsurf/utils/log.h"
+#include "netsurf/utils/messages.h"
#include "netsurf/utils/utils.h"
#define HOTLIST_EXPAND 0
@@ -30,61 +30,67 @@
#define HOTLIST_TLINE 4
#define HOTLIST_BLINE 5
-struct hotlist_entry {
+#define HOTLIST_TEXT_BUFFER 256
+struct hotlist_entry {
+
/** The next hotlist entry at this level, or NULL for no more
*/
struct hotlist_entry *next_entry;
-
+
/** The child hotlist entry (NULL for no children).
The children value must be set for this value to take effect.
*/
struct hotlist_entry *child_entry;
-
+
/** The number of children (-1 for non-folders, >=0 for folders)
*/
int children;
-
+
/** The title of the hotlist entry/folder
*/
char *title;
-
+
/** The URL of the hotlist entry (NULL for folders)
*/
char *url;
-
+
/** Whether this entry is expanded
*/
bool expanded;
-
+
/** Whether this entry is selected
*/
bool selected;
-
+
/** The content filetype (not for folders)
*/
int filetype;
-
+
/** The number of visits
*/
int visits;
-
- /** Add/last visit dates (-1 if invalid)
+
+ /** Add/last visit dates
*/
time_t add_date;
time_t last_date;
-
+
/** Position on last reformat (relative to window origin)
*/
int x0;
int y0;
int width;
int height;
-
+
/** Cached values
*/
int collapsed_width;
int expanded_width;
+
+ /** The width of the various lines sub-text
+ */
+ int widths[4];
};
@@ -126,6 +132,7 @@ static char null_text_string[] = "\0";
/* Temporary workspace for plotting
*/
static char icon_name[12];
+static char extended_text[HOTLIST_TEXT_BUFFER];
/* Whether a reformat is pending
*/
@@ -154,6 +161,10 @@ static osspriteop_id sprite[6];
*/
static osspriteop_trans_tab *pixel_table;
+/* The drag buttons
+*/
+wimp_mouse_state drag_buttons;
+
static void ro_gui_hotlist_load(void);
static void ro_gui_hotlist_save(void);
@@ -166,11 +177,14 @@ static struct hotlist_entry *ro_gui_hotlist_create(const char *title, const char
static void ro_gui_hotlist_update_entry_size(struct hotlist_entry *entry);
static struct hotlist_entry *ro_gui_hotlist_find_entry(int x, int y, struct hotlist_entry *entry);
static int ro_gui_hotlist_selection_state(struct hotlist_entry *entry, bool selected, bool redraw);
+static void ro_gui_hotlist_selection_drag(struct hotlist_entry *entry,
+ int x0, int y0, int x1, int y1,
+ bool toggle, bool redraw);
static char *last_visit_to_string(time_t last_visit);
void ro_gui_hotlist_init(void) {
os_error *error;
-
+
/* Get our sprite ids for faster plotting. This could be done in a
far more elegant manner, but it's late and my girlfriend will
kill me if I don't go to bed soon. Sorry.
@@ -202,7 +216,7 @@ void ro_gui_hotlist_init(void) {
warn_user("MiscError", error->errmess);
return;
}
-
+
/* Update our text icon
*/
text_icon.data.indirected_text.validation = null_text_string;
@@ -213,7 +227,7 @@ void ro_gui_hotlist_init(void) {
(wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT);
sprite_icon.data.indirected_sprite.area = wimpspriteop_AREA;
sprite_icon.data.indirected_text.size = 12;
-
+
/* Create our window
*/
error = xwimp_create_window(&hotlist_window_definition, &hotlist_window);
@@ -221,14 +235,14 @@ void ro_gui_hotlist_init(void) {
warn_user("WimpError", error->errmess);
return;
}
-
+
/* Set the root options
*/
root.next_entry = NULL;
root.child_entry = NULL;
root.children = 0;
root.expanded = true;
-
+
/* Load the hotlist
*/
ro_gui_hotlist_load();
@@ -237,7 +251,7 @@ void ro_gui_hotlist_init(void) {
/**
* Shows the hotlist window.
- */
+ */
void ro_gui_hotlist_show(void) {
os_error *error;
int screen_width, screen_height;
@@ -262,14 +276,14 @@ void ro_gui_hotlist_show(void) {
open in the centre of the screen.
*/
if (!(state.flags & wimp_WINDOW_OPEN)) {
- /* Clear the selection state
- */
- ro_gui_hotlist_selection_state(root.child_entry, false, false);
+ /* Clear the selection state
+ */
+ ro_gui_hotlist_selection_state(root.child_entry, false, false);
/* Get the current screen size
*/
ro_gui_screen_size(&screen_width, &screen_height);
-
+
/* Move to the centre
*/
dimension = state.visible.x1 - state.visible.x0;
@@ -294,32 +308,32 @@ void ro_gui_hotlist_show(void) {
void ro_gui_hotlist_load(void) {
struct hotlist_entry *netsurf;
struct hotlist_entry *entry;
-
+
/* Create a folder
*/
netsurf = ro_gui_hotlist_create("NetSurf", NULL, 0, &root);
netsurf->expanded = true;
-
+
/* Add some content
*/
entry = ro_gui_hotlist_create("NetSurf homepage", "http://netsurf.sf.net",
0xfaf, netsurf);
- entry->add_date = -1;
+ entry->add_date = (time_t)-1;
entry = ro_gui_hotlist_create("NetSurf test builds", "http://netsurf.strcprstskrzkrk.co.uk",
0xfaf, netsurf);
- entry->add_date = -1;
+ entry->add_date = (time_t)-1;
}
-void ro_gui_hotlist_save(void) {
+void ro_gui_hotlist_save(void) {
}
/**
* Adds a hotlist entry to the root of the tree.
*
- * \param title the entry title
+ * \param title the entry title
* \param content the content to add
- */
+ */
void ro_gui_hotlist_add(char *title, struct content *content) {
ro_gui_hotlist_create(title, content->url, ro_content_filetype(content), &root);
}
@@ -330,9 +344,9 @@ void ro_gui_hotlist_add(char *title, struct content *content) {
*
* \param content the content visited
*/
-void ro_gui_hotlist_visited(struct content *content) {
+void hotlist_visited(struct content *content) {
if ((!content) || (!content->url)) return;
- ro_gui_hotlist_visited_update(content, root.child_entry);
+ ro_gui_hotlist_visited_update(content, root.child_entry);
}
@@ -340,35 +354,49 @@ void ro_gui_hotlist_visited(struct content *content) {
* Informs the hotlist that some content has been visited (internal)
*
* \param content the content visited
- * \param entry the entry to check siblings and children of
+ * \param entry the entry to check siblings and children of
*/
void ro_gui_hotlist_visited_update(struct content *content, struct hotlist_entry *entry) {
char *url;
-
+ bool full = false;
+
/* Update the hotlist
*/
url = content->url;
while (entry) {
if (entry->url) {
if (strcmp(url, entry->url) == 0) {
- char *temp = last_visit_to_string(entry->last_date);
- if (temp != NULL) {
- LOG(("previous visit to '%s': '%s'", url, temp));
- free(temp);
- }
+ /* Check if we're going to need a full redraw downwards
+ */
+ full = ((entry->visits == 0) || (entry->last_date == -1));
+
+ /* Update our values
+ */
entry->visits++;
entry->last_date = time(NULL);
+
+ /* Update the entry width (extreme case - never likely to happen)
+ */
ro_gui_hotlist_update_entry_size(entry);
+
+ /* Redraw the least we can get away with
+ */
if (entry->expanded) {
- xwimp_force_redraw(hotlist_window,
- entry->x0, entry->y0,
- entry->x0 + entry->width,
- entry->y0 + entry->height);
+ if (full) {
+ xwimp_force_redraw(hotlist_window,
+ 0, -16384, 16384,
+ entry->y0 + entry->height);
+ } else {
+ xwimp_force_redraw(hotlist_window,
+ entry->x0, entry->y0,
+ entry->x0 + entry->width,
+ entry->y0 + entry->height);
+ }
}
}
}
if (entry->child_entry) {
- ro_gui_hotlist_visited_update(content, entry->child_entry);
+ ro_gui_hotlist_visited_update(content, entry->child_entry);
}
entry = entry->next_entry;
}
@@ -381,11 +409,11 @@ void ro_gui_hotlist_visited_update(struct content *content, struct hotlist_entry
* \param title the entry title
* \param url the entry url (NULL to create a folder)
* \param folder the folder to add the entry into
- */
+ */
struct hotlist_entry *ro_gui_hotlist_create(const char *title, const char *url,
int filetype, struct hotlist_entry *folder) {
struct hotlist_entry *entry;
-
+
/* Check we have a title or a URL
*/
if (!title && !url) return NULL;
@@ -397,7 +425,7 @@ struct hotlist_entry *ro_gui_hotlist_create(const char *title, const char *url,
warn_user("NoMemory", 0);
return NULL;
}
-
+
/* And enough for the url/title
*/
if (url) {
@@ -405,7 +433,7 @@ struct hotlist_entry *ro_gui_hotlist_create(const char *title, const char *url,
if (!entry->url) {
warn_user("NoMemory", 0);
free(entry);
- return NULL;
+ return NULL;
}
strcpy(entry->url, url);
}
@@ -418,43 +446,43 @@ struct hotlist_entry *ro_gui_hotlist_create(const char *title, const char *url,
warn_user("NoMemory", 0);
free(entry->url);
free(entry);
- return NULL;
+ return NULL;
}
strcpy(entry->title, title);
} else {
- entry->title = entry->url;
+ entry->title = entry->url;
}
-
+
/* Set the children count
*/
if (url) {
- entry->children = -1;
+ entry->children = -1;
} else {
entry->children = 0;
}
-
+
/* Set the filetype
*/
entry->filetype = filetype;
-
+
/* Set the default values
*/
entry->visits = 0;
-
+
/* Get our dates
*/
entry->add_date = time(NULL);
- entry->last_date = -1;
-
+ entry->last_date = (time_t)-1;
+
/* Set the expanded/selected state
*/
entry->expanded = false;
entry->selected = false;
-
+
/* Set the width
*/
ro_gui_hotlist_update_entry_size(entry);
-
+
/* Link in as the last entry in root
*/
ro_gui_hotlist_link_entry(folder, entry);
@@ -467,16 +495,16 @@ struct hotlist_entry *ro_gui_hotlist_create(const char *title, const char *url,
*
* \param parent the parent entry to link under
* \param entry the entry to link
- */
+ */
void ro_gui_hotlist_link_entry(struct hotlist_entry *parent, struct hotlist_entry *entry) {
struct hotlist_entry *link_entry;
if (!parent || !entry) return;
-
+
/* Ensure the parent is a folder
*/
if (parent->children == -1) return;
-
+
/* Get the first child entry
*/
link_entry = parent->child_entry;
@@ -486,7 +514,7 @@ void ro_gui_hotlist_link_entry(struct hotlist_entry *parent, struct hotlist_entr
while (link_entry->next_entry) link_entry = link_entry->next_entry;
link_entry->next_entry = entry;
}
-
+
/* Increment the number of children
*/
parent->children += 1;
@@ -503,32 +531,82 @@ void ro_gui_hotlist_link_entry(struct hotlist_entry *parent, struct hotlist_entr
*/
void ro_gui_hotlist_update_entry_size(struct hotlist_entry *entry) {
int width;
-
+ int max_width;
+ int line_number = 0;
+
/* Get the width of the title
- */
+ */
xwimptextop_string_width(entry->title,
strlen(entry->title) > 256 ? 256 : strlen(entry->title),
&width);
- entry->collapsed_width = width + 32 + 36 + 16;
-
+ entry->collapsed_width = width;
+ max_width = width;
+
/* Get the width of the URL
*/
if (entry->url) {
- xwimptextop_string_width(entry->url,
- strlen(entry->url) > 256 ? 256 : strlen(entry->url),
+ snprintf(extended_text, HOTLIST_TEXT_BUFFER,
+ messages_get("HotlistURL"), entry->url);
+ if (strlen(extended_text) >= 255) {
+ extended_text[252] = '.';
+ extended_text[253] = '.';
+ extended_text[254] = '.';
+ extended_text[255] = '\0';
+ }
+ xwimptextop_string_width(extended_text,
+ strlen(extended_text) > 256 ? 256 : strlen(extended_text),
&width);
- width += 32 + 36 + 16;
- if (width < entry->collapsed_width) width = entry->collapsed_width;
- entry->expanded_width = width;
- } else {
- entry->expanded_width = width + 32 + 36 + 16;
+ if (width > max_width) max_width = width;
+ entry->widths[line_number++] = width;
+ }
+
+ /* Get the width of the add date
+ */
+ if (entry->add_date != -1) {
+ snprintf(extended_text, HOTLIST_TEXT_BUFFER,
+ messages_get("HotlistAdd"), ctime(&entry->add_date));
+ xwimptextop_string_width(extended_text,
+ strlen(extended_text) > 256 ? 256 : strlen(extended_text),
+ &width);
+ if (width > max_width) max_width = width;
+ entry->widths[line_number++] = width;
+ }
+
+ /* Get the width of the last visit
+ */
+ if (entry->last_date != -1) {
+ snprintf(extended_text, HOTLIST_TEXT_BUFFER,
+ messages_get("HotlistLast"), ctime(&entry->last_date));
+ xwimptextop_string_width(extended_text,
+ strlen(extended_text) > 256 ? 256 : strlen(extended_text),
+ &width);
+ if (width > max_width) max_width = width;
+ entry->widths[line_number++] = width;
+ }
+
+ /* Get the width of the visit count
+ */
+ if (entry->visits > 0) {
+ snprintf(extended_text, HOTLIST_TEXT_BUFFER,
+ messages_get("HotlistVisits"), entry->visits);
+ xwimptextop_string_width(extended_text,
+ strlen(extended_text) > 256 ? 256 : strlen(extended_text),
+ &width);
+ if (width > max_width) max_width = width;
+ entry->widths[line_number++] = width;
}
+
+ /* Increase the text width by the borders
+ */
+ entry->expanded_width = max_width + 32 + 36 + 16;
+ entry->collapsed_width += 32 + 36 + 16;
+ reformat_pending = true;
}
/**
* Redraws a section of the hotlist window
- *
+ *
* \param redraw the area to redraw
*/
void ro_gui_hotlist_redraw(wimp_draw *redraw) {
@@ -536,12 +614,12 @@ void ro_gui_hotlist_redraw(wimp_draw *redraw) {
osbool more;
unsigned int size;
os_box extent = {0, 0, 0, 0};;
-
+
/* Reset our min/max sizes
*/
max_width = 0;
max_height = 0;
-
+
/* Get a pixel translation table for the sprites. We only
get one for all the sprites, so they must all have the
same characteristics.
@@ -550,7 +628,7 @@ void ro_gui_hotlist_redraw(wimp_draw *redraw) {
colourtrans_CURRENT_MODE, colourtrans_CURRENT_PALETTE,
0, colourtrans_GIVEN_SPRITE, 0, 0, &size);
pixel_table = malloc(size);
- if (pixel_table) {
+ if (pixel_table) {
xcolourtrans_generate_table_for_sprite(gui_sprites, sprite[HOTLIST_EXPAND],
colourtrans_CURRENT_MODE, colourtrans_CURRENT_PALETTE,
pixel_table, colourtrans_GIVEN_SPRITE, 0, 0, 0);
@@ -562,22 +640,22 @@ void ro_gui_hotlist_redraw(wimp_draw *redraw) {
*/
more = wimp_redraw_window(redraw);
while (more) {
- clip_x0 = redraw->clip.x0;
- clip_y0 = redraw->clip.y0;
- clip_x1 = redraw->clip.x1;
- clip_y1 = redraw->clip.y1;
+ clip_x0 = redraw->clip.x0;
+ clip_y0 = redraw->clip.y0;
+ clip_x1 = redraw->clip.x1;
+ clip_y1 = redraw->clip.y1;
origin_x = redraw->box.x0 - redraw->xscroll;
origin_y = redraw->box.y1 - redraw->yscroll;
ro_gui_hotlist_redraw_tree(root.child_entry, 0,
origin_x + 8, origin_y - 4);
more = wimp_get_rectangle(redraw);
}
-
+
/* Free our memory
*/
if (pixel_table) free(pixel_table);
pixel_table = NULL;
-
+
/* Check if we should reformat
*/
if (reformat_pending) {
@@ -601,8 +679,8 @@ void ro_gui_hotlist_redraw(wimp_draw *redraw) {
*
* \param entry the entry to draw descendants and siblings of
* \param level the tree level of the entry
- * \param x0 the x co-ordinate to plot from
- * \param y0 the y co-ordinate to plot from
+ * \param x0 the x co-ordinate to plot from
+ * \param y0 the y co-ordinate to plot from
* \returns the height of the tree
*/
int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, int y0) {
@@ -610,13 +688,13 @@ int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, i
int cumulative = 0;
int height = 0;
int box_y0;
-
+
if (!entry) return 0;
-
+
/* Repeatedly draw our entries
*/
while (entry) {
-
+
/* Redraw the item
*/
height = ro_gui_hotlist_redraw_item(entry, level, x0 + 32, y0);
@@ -659,7 +737,7 @@ int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, i
y0 -= 44;
height -= 44;
}
-
+
/* Draw the rest of the lines
*/
while (height > 0) {
@@ -671,7 +749,7 @@ int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, i
y0 -= 44;
height -= 44;
}
-
+
} else {
/* Draw a half-line for the last entry
*/
@@ -700,17 +778,17 @@ int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, i
gui_sprites, sprite[HOTLIST_COLLAPSE],
x0, box_y0 - 31,
osspriteop_USE_MASK | osspriteop_USE_PALETTE,
- 0, pixel_table);
+ 0, pixel_table);
} else {
xosspriteop_put_sprite_scaled(osspriteop_PTR,
gui_sprites, sprite[HOTLIST_EXPAND],
x0, box_y0 - 31,
osspriteop_USE_MASK | osspriteop_USE_PALETTE,
0, pixel_table);
-
-
+
+
}
-
+
}
/* Move to the next entry
@@ -718,7 +796,7 @@ int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, i
entry = entry->next_entry;
first = false;
}
-
+
/* Return our height
*/
return cumulative;
@@ -730,26 +808,30 @@ int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, i
*
* \param entry the entry to redraw
* \param level the level of the entry
- * \param x0 the x co-ordinate to plot at
- * \param y0 the y co-ordinate to plot at
+ * \param x0 the x co-ordinate to plot at
+ * \param y0 the y co-ordinate to plot at
* \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 index;
-
+ 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;
}
-
+
/* Check whether we need to redraw
*/
if ((x0 < clip_x1) && (y0 > clip_y0) && ((x0 + entry->width) > clip_x0) &&
((y0 - height) < clip_y1)) {
-
-
+
+
/* Update the selection state
*/
text_icon.flags = wimp_ICON_TEXT | (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) |
@@ -784,11 +866,11 @@ int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, i
/* Get the icon sprite
*/
sprintf(icon_name, "small_%x", entry->filetype);
-
+
/* Check it exists
*/
if (xwimpspriteop_read_sprite_info(icon_name, 0, 0, 0, 0)) {
- sprintf(icon_name, "small_xxx");
+ sprintf(icon_name, "small_xxx");
}
}
xwimp_plot_icon(&sprite_icon);
@@ -798,8 +880,8 @@ int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, i
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 - 44;
- text_icon.extent.y1 = y0 - origin_y;
+ text_icon.extent.y0 = y0 - origin_y - 42;
+ text_icon.extent.y1 = y0 - origin_y - 2;
xwimp_plot_icon(&text_icon);
/* Clear the selection state
@@ -810,38 +892,91 @@ 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)) {
+ if ((entry->children == -1) && (entry->expanded) && (height > 44)) {
text_icon.flags = wimp_ICON_TEXT | (wimp_COLOUR_DARK_GREY << wimp_ICON_FG_COLOUR_SHIFT) |
wimp_ICON_INDIRECTED | wimp_ICON_VCENTRED;
-
-/* URL
- Date added
- Last visited
- Visit count
-*/
-
-
+ text_icon.extent.y0 = y0 - origin_y - 44;
+ text_icon.extent.y1 = y0 - origin_y;
+
/* Draw the lines
*/
y0 -= 44;
- xosspriteop_put_sprite_scaled(osspriteop_PTR,
- gui_sprites, sprite[HOTLIST_TLINE],
- x0 + 16, y0 - 22,
- osspriteop_USE_MASK | osspriteop_USE_PALETTE,
- 0, pixel_table);
- xosspriteop_put_sprite_scaled(osspriteop_PTR,
- gui_sprites, sprite[HOTLIST_ENTRY],
- x0 + 8, y0 - 29,
- osspriteop_USE_MASK | osspriteop_USE_PALETTE,
- 0, pixel_table);
+ line_y0 = y0;
+ line_height = height - 44;
+ while (line_height > 0) {
+ if (line_height == 44) {
+ xosspriteop_put_sprite_scaled(osspriteop_PTR,
+ gui_sprites, sprite[HOTLIST_TLINE],
+ x0 + 16, line_y0 - 22,
+ osspriteop_USE_MASK | osspriteop_USE_PALETTE,
+ 0, pixel_table);
+ } else {
+ xosspriteop_put_sprite_scaled(osspriteop_PTR,
+ gui_sprites, sprite[HOTLIST_LINE],
+ x0 + 16, line_y0 - 44,
+ osspriteop_USE_MASK | osspriteop_USE_PALETTE,
+ 0, pixel_table);
+
+ }
+ xosspriteop_put_sprite_scaled(osspriteop_PTR,
+ gui_sprites, sprite[HOTLIST_ENTRY],
+ x0 + 8, line_y0 - 29,
+ osspriteop_USE_MASK | osspriteop_USE_PALETTE,
+ 0, pixel_table);
+ line_height -= 44;
+ line_y0 -= 44;
+ }
- /* Plot the text
+ /* Set the right extent of the icon to be big enough for anything
*/
- text_icon.data.indirected_text.text = entry->url;
text_icon.extent.x1 = x0 - origin_x + 4096;
- text_icon.extent.y0 -= 44;
- text_icon.extent.y1 -= 44;
- xwimp_plot_icon(&text_icon);
+
+ /* Plot the URL text
+ */
+ text_icon.data.indirected_text.text = extended_text;
+ if (entry->url) {
+ snprintf(extended_text, HOTLIST_TEXT_BUFFER,
+ messages_get("HotlistURL"), entry->url);
+ if (strlen(extended_text) >= 255) {
+ extended_text[252] = '.';
+ extended_text[253] = '.';
+ extended_text[254] = '.';
+ extended_text[255] = '\0';
+ }
+ text_icon.extent.y0 -= 44;
+ text_icon.extent.y1 -= 44;
+ xwimp_plot_icon(&text_icon);
+ }
+
+ /* Plot the date added text
+ */
+ 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;
+ xwimp_plot_icon(&text_icon);
+ }
+
+ /* Plot the last visited text
+ */
+ 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;
+ xwimp_plot_icon(&text_icon);
+ }
+
+ /* Plot the visit count text
+ */
+ 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;
+ xwimp_plot_icon(&text_icon);
+ }
}
}
@@ -861,6 +996,7 @@ int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, i
* /param pointer the pointer state
*/
void ro_gui_hotlist_click(wimp_pointer *pointer) {
+ wimp_drag drag;
struct hotlist_entry *entry;
wimp_window_state state;
wimp_mouse_state buttons;
@@ -884,7 +1020,7 @@ void ro_gui_hotlist_click(wimp_pointer *pointer) {
x = (pointer->pos.x - (state.visible.x0 - state.xscroll));
y = (pointer->pos.y - (state.visible.y1 - state.yscroll));
-
+
/* Find our entry
*/
entry = ro_gui_hotlist_find_entry(x, y, root.child_entry);
@@ -895,10 +1031,14 @@ void ro_gui_hotlist_click(wimp_pointer *pointer) {
y_offset = y - (entry->y0 + entry->height);
if (((x_offset < 32) && (y_offset > -44)) || ((entry->children != -1) &&
((buttons == wimp_DOUBLE_SELECT) || (buttons == wimp_DOUBLE_ADJUST)))) {
+ ro_gui_hotlist_selection_state(entry->child_entry,
+ false, false);
entry->expanded = !entry->expanded;
if (x_offset >= 32) entry->selected = false;
reformat_pending = true;
- xwimp_force_redraw(hotlist_window, 0, -16384, 16384, 0);
+ xwimp_force_redraw(hotlist_window,
+ 0, -16384, 16384,
+ entry->y0 + entry->height);
} else if (x_offset >= 32) {
/* Check for selection
*/
@@ -913,19 +1053,19 @@ void ro_gui_hotlist_click(wimp_pointer *pointer) {
false, true);
entry->selected = true;
xwimp_force_redraw(hotlist_window,
- entry->x0, entry->y0,
+ entry->x0, entry->y0 + entry->height - 44,
entry->x0 + entry->width,
- entry->y0 + entry->height);
+ 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->x0, entry->y0 + entry->height - 44,
entry->x0 + entry->width,
- entry->y0 + entry->height);
-
+ entry->y0 + entry->height);
+
}
-
+
/* Check if we should open the URL
*/
if (((buttons == wimp_DOUBLE_SELECT) || (buttons == wimp_DOUBLE_ADJUST)) &&
@@ -945,37 +1085,63 @@ void ro_gui_hotlist_click(wimp_pointer *pointer) {
} else {
no_entry = true;
}
-
-
+
+
/* Handle a click without an entry
*/
if (no_entry) {
- /* Deselect everything if we click nowhere
- */
+ /* Deselect everything if we click nowhere
+ */
if (buttons == (wimp_CLICK_SELECT << 8)) {
ro_gui_hotlist_selection_state(root.child_entry,
false, true);
}
- }
+
+ /* Handle the start of a drag
+ */
+ if (buttons == (wimp_CLICK_SELECT << 4) ||
+ buttons == (wimp_CLICK_ADJUST << 4)) {
+
+ /* Clear the current selection
+ */
+ if (buttons == (wimp_CLICK_SELECT << 4)) {
+ ro_gui_hotlist_selection_state(root.child_entry,
+ false, true);
+ }
+ /* Start a drag box
+ */
+ drag_buttons = buttons;
+ gui_current_drag_type = GUI_DRAG_HOTLIST_SELECT;
+ drag.w = hotlist_window;
+ drag.type = wimp_DRAG_USER_RUBBER;
+ drag.initial.x0 = pointer->pos.x;
+ drag.initial.x1 = pointer->pos.x;
+ drag.initial.y0 = pointer->pos.y;
+ drag.initial.y1 = pointer->pos.y;
+ drag.bbox.x0 = state.visible.x0;
+ drag.bbox.x1 = state.visible.x1;
+ drag.bbox.y0 = state.visible.y0;
+ drag.bbox.y1 = state.visible.y1;
+ xwimp_drag_box(&drag);
+ }
+ }
}
/**
* Find an entry at a particular position
*
- * For this calculation, the entry is deemed to occupy a box from the left edge of
- * the expansion image to the right extent of the widest text string for the first
- * line, and a box inset by the width of a expansion button and an icon for the rest.
- *
- * \param x the x co-ordinate
- * \param y the y co-ordinate
+ * \param x the x co-ordinate
+ * \param y the y co-ordinate
* \param entry the entry to check down from (root->child_entry for the entire tree)
* /return the entry occupying the positon
*/
struct hotlist_entry *ro_gui_hotlist_find_entry(int x, int y, struct hotlist_entry *entry) {
struct hotlist_entry *find_entry;
-
+ int inset_x = 0;
+ int inset_y = 0;
+
/* Check we have an entry (only applies if we have an empty hotlist)
*/
if (!entry) return NULL;
@@ -983,17 +1149,30 @@ struct hotlist_entry *ro_gui_hotlist_find_entry(int x, int y, struct hotlist_ent
/* Get the first child entry
*/
while (entry) {
- /* Check this entry
+ /* Check if this entry could possibly match
*/
if ((x > entry->x0) && (y > entry->y0) && (x < (entry->x0 + entry->width)) &&
(y < (entry->y0 + entry->height))) {
- /* The top line extends the full width
+
+ /* The top line extends all the way left
*/
- if ((y - (entry->y0 + entry->height)) > -44) return entry;
- if ((x - entry->x0) > (32 + 36)) return entry;
- return NULL;
+ if (y - (entry->y0 + entry->height) > -44) {
+ 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;
+ 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;
+ return NULL;
}
-
+
/* Continue onwards
*/
if ((entry->child_entry) && (entry->expanded)) {
@@ -1009,7 +1188,7 @@ struct hotlist_entry *ro_gui_hotlist_find_entry(int x, int y, struct hotlist_ent
/**
* Updated the selection state of the tree
*
- * \param entry the entry to update all siblings and descendants of
+ * \param entry the entry to update all siblings and descendants of
* \param selected the selection state to set
* \param redraw update the icons in the Wimp
* \return the number of entries that have changed
@@ -1031,12 +1210,12 @@ int ro_gui_hotlist_selection_state(struct hotlist_entry *entry, bool selected, b
*/
entry->selected = selected;
changes++;
-
- /* Redraw the entry
+
+ /* Redraw the entrys first line
*/
if (redraw) {
xwimp_force_redraw(hotlist_window,
- entry->x0, entry->y0,
+ entry->x0, entry->y0 + entry->height - 44,
entry->x0 + entry->width,
entry->y0 + entry->height);
}
@@ -1046,13 +1225,158 @@ int ro_gui_hotlist_selection_state(struct hotlist_entry *entry, bool selected, b
*/
if (entry->child_entry) {
changes += ro_gui_hotlist_selection_state(entry->child_entry,
- selected & (entry->expanded), redraw);
+ selected, redraw & (entry->expanded));
}
entry = entry->next_entry;
}
return changes;
}
+
+/**
+ * Updated the selection state of the tree
+ *
+ * \param entry the entry to update all siblings and descendants of
+ * \param x0 the left edge of the box
+ * \param y0 the top edge of the box
+ * \param x1 the right edge of the box
+ * \param y1 the bottom edge of the box
+ * \param toggle toggle the selection state, otherwise set
+ * \param redraw update the icons in the Wimp
+ */
+void ro_gui_hotlist_selection_drag(struct hotlist_entry *entry,
+ int x0, int y0, int x1, int y1,
+ bool toggle, bool redraw) {
+ bool do_update;
+ int line;
+ int test_y;
+
+ /* Check we have an entry (only applies if we have an empty hotlist)
+ */
+ if (!entry) return;
+
+ /* Get the first child entry
+ */
+ while (entry) {
+ /* Check if this entry could possibly match
+ */
+ if ((x1 > (entry->x0 + 32)) && (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) &&
+ (x0 < (entry->x0 + entry->collapsed_width)) &&
+ (y1 < (entry->y0 + entry->height))) {
+ do_update = true;
+ }
+
+ /* Check the other lines
+ */
+ line = 1;
+ test_y = entry->y0 + entry->height - 44;
+ while (((line * 44) < 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))) {
+ do_update = true;
+ }
+
+ /* Move to the next line
+ */
+ line++;
+ test_y -= 44;
+ }
+
+ /* Redraw the entrys first line
+ */
+ if (do_update) {
+ if (toggle) {
+ entry->selected = !entry->selected;
+ } else {
+ entry->selected = true;
+ }
+ if (redraw) {
+ xwimp_force_redraw(hotlist_window,
+ entry->x0, entry->y0 + entry->height - 44,
+ entry->x0 + entry->width,
+ entry->y0 + entry->height);
+ }
+ }
+ }
+
+ /* Continue onwards
+ */
+ if ((entry->child_entry) && (entry->expanded)) {
+ ro_gui_hotlist_selection_drag(entry->child_entry,
+ x0, y0, x1, y1, toggle, redraw);
+ }
+ entry = entry->next_entry;
+ do_update = false;
+ }
+}
+
+
+/**
+ * The end of a selection drag has been reached
+ *
+ * \param drag the final drag co-ordinates
+ */
+void ro_gui_hotlist_selection_drag_end(wimp_dragged *drag) {
+ wimp_window_state state;
+ int x0, y0, x1, y1;
+
+ /* Get the window state to make everything relative
+ */
+ state.w = hotlist_window;
+ wimp_get_window_state(&state);
+
+ /* Create the relative positions
+ */
+ x0 = drag->final.x0 - state.visible.x0 - state.xscroll;
+ x1 = drag->final.x1 - state.visible.x0 - state.xscroll;
+ y0 = drag->final.y0 - state.visible.y1 - state.yscroll;
+ y1 = drag->final.y1 - state.visible.y1 - state.yscroll;
+
+ /* Make sure x0 < x1 and y0 > y1
+ */
+ if (x0 > x1) {
+ x0 ^= x1;
+ x1 ^= x0;
+ x0 ^= x1;
+ }
+ if (y0 < y1) {
+ y0 ^= y1;
+ y1 ^= y0;
+ y0 ^= y1;
+ }
+
+ /* Update the selection state
+ */
+ if (drag_buttons == (wimp_CLICK_SELECT << 4)) {
+ ro_gui_hotlist_selection_drag(root.child_entry, x0, y0, x1, y1, false, true);
+ } else {
+ ro_gui_hotlist_selection_drag(root.child_entry, x0, y0, x1, y1, true, true);
+ }
+}
+
+
+/**
+ * The end of a item moving drag has been reached
+ *
+ * \param drag the final drag co-ordinates
+ */
+void ro_gui_hotlist_move_drag_end(wimp_dragged *drag) {
+
+}
+
+
+
+
+
+
/**
* Convert the time of the last visit into a human friendly string
*
diff --git a/riscos/window.c b/riscos/window.c
index f0b787bcc..b765b361c 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -891,7 +891,6 @@ void gui_window_start_throbber(struct gui_window* g) {
void gui_window_stop_throbber(gui_window* g) {
ro_gui_prepare_navigate(g);
- ro_gui_hotlist_visited(g->data.browser.bw->current_content);
g->throbber = 0;
sprintf(g->throb_buf, "throbber%u", g->throbber);
ro_gui_redraw_icon(g->data.browser.toolbar->toolbar_handle, ICON_TOOLBAR_THROBBER);