From dcae02d7f2c82a4c16e92bf1bc8a9534ea745785 Mon Sep 17 00:00:00 2001
From: David Brown <dbrown@gitlab.riscosopen.org>
Date: Thu, 18 Sep 1997 15:29:43 +0000
Subject: [PATCH] Much faster 3000%+ in some cases loading of hotlist files.

Also much faster drag box selections.
---
 c/Hotlist | 133 ++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 95 insertions(+), 38 deletions(-)

diff --git a/c/Hotlist b/c/Hotlist
index 80a3822..072ed6e 100644
--- a/c/Hotlist
+++ b/c/Hotlist
@@ -200,7 +200,8 @@ static void              hotlist_get_selected_shape_r    (hotlist_item * list,
                                                           unsigned int * itemno,
                                                           int          * found,
                                                           unsigned int   item_height);
-
+void hotlist_select_box(unsigned int first_item, unsigned int last_item, int minx, int maxx);
+void hotlist_select_box_r(unsigned int first_item, unsigned int last_item, hotlist_item *item, unsigned int *itemno, int minx, int maxx);
 
 /* Save Protocol */
 
@@ -2946,9 +2947,11 @@ static _kernel_oserror * hotlist_load_directory(FILE * fileptr, hotlist_item * t
   unsigned int      unfollowed_uls = 0;
   long int          file_position;
   int               character, count;
-
+  int               target_type;
   /* Go through the file in chunks */
 
+  target_type = 0; /* At end of directory */
+
   while (!feof(fileptr)) /* In theory the code below means you'll never get this; but just to be safe... */
   {
     file_position = ftell(fileptr);
@@ -3096,8 +3099,17 @@ static _kernel_oserror * hotlist_load_directory(FILE * fileptr, hotlist_item * t
 
       /* Add this item */
 
-      e = hotlist_new_url(target, HOTLIST_POSITION_END, str_ptr, url);
+      if (target_type == 0)
+      {
+        e = hotlist_new_url(target, HOTLIST_POSITION_END, str_ptr, url);
+        target_type = 1;
+      }
+      else
+      {
+        e = hotlist_new_url(target, HOTLIST_POSITION_AFTER, str_ptr, url);
+      }
       if (e) goto hotlist_load_directory_exit; /* (See near end of function) */
+      target = hotlist_newitem;
     }
 
     /* Treat any '<ul>' tags as the start of a new directory. The name comes */
@@ -3116,9 +3128,19 @@ static _kernel_oserror * hotlist_load_directory(FILE * fileptr, hotlist_item * t
       {
         /* Otherwise, add the directory */
 
-        e = hotlist_new_directory(target, next_directory_name, HOTLIST_POSITION_END, &new_dir);
+        if (target_type == 0)
+        {
+          e = hotlist_new_directory(target, next_directory_name, HOTLIST_POSITION_END, &new_dir);
+          target_type = 1;
+        }
+        else
+        {
+          e = hotlist_new_directory(target, next_directory_name, HOTLIST_POSITION_AFTER, &new_dir);
+        }
         if (e) goto hotlist_load_directory_exit;
 
+        target = hotlist_newitem;
+
         if (strstr(string_buffer, "<!--open-->") != NULL)
         {
           new_dir->flags |= HOTLIST_D_IS_OPEN;
@@ -5083,12 +5105,9 @@ static int hotlist_null_drag_select_handler(int event_code, WimpPollBlock * even
   WimpGetPointerInfoBlock pointerblock;
   unsigned int item_height, item_dir_width, item_url_width;
   int workx, worky;
-  hotlist_item *item;
   WimpGetWindowStateBlock state;
-  unsigned int item_min, item_max, itemno;
-  int itemxmin, itemxmax;
+  unsigned int item_min, item_max;
   int minx, maxx;
-  int last_item;
 
   wimp_get_pointer_info(&pointerblock);                          /* Read pointer position */
 
@@ -5116,39 +5135,59 @@ static int hotlist_null_drag_select_handler(int event_code, WimpPollBlock * even
     maxx = selection_x;
   }
 
-  last_item = hotlist_count_displayed_items(hotlist_root->data.directory_content);
+  hotlist_select_box(item_min, item_max, minx, maxx);
 
-  for(itemno = 0; itemno <= last_item; itemno++)
+  return 0;
+}
+
+/*************************************************/
+/* hotlist_select_box()                          */
+/*                                               */
+/* Sets the HOTLIST_G_DRAG_SELECTED flag for all */
+/* visible items in the range first_item to      */
+/* last_item where their horizontal visible area */
+/* intersects with the a line draw from minx to  */
+/* maxx.  Clears the HOTLIST_G_DRAG_SELECTED     */
+/* flag for all other items                      */
+/*                                               */
+/* Parameters: first visible item                */
+/* handler.    last visible item                 */
+/*             minx workspace relative           */
+/*             maxx workspace relative           */
+/*************************************************/
+
+void hotlist_select_box(unsigned int first_item, unsigned int last_item, int minx, int maxx)
+{
+  unsigned int itemno;
+  hotlist_select_box_r(first_item, last_item, hotlist_root->data.directory_content, &itemno, minx, maxx);
+}
+
+/*************************************************/
+/* hotlist_select_box_r()                        */
+/*                                               */
+/* Recursive backend to hotlist_select_box       */
+/*************************************************/
+
+void hotlist_select_box_r(unsigned int first_item, unsigned int last_item, hotlist_item *item, unsigned int *itemno, int minx, int maxx)
+{
+  int itemxmin, itemxmax;
+  while(item)
   {
-    item = hotlist_find_item(hotlist_root->data.directory_content, itemno);
-    if (item)
+    /* Do stuff */
+
+    if (*itemno >= first_item && *itemno <= last_item)
     {
-      if (itemno >= item_min && itemno <= item_max)
+      hotlist_get_shape(&itemxmin, &itemxmax, item);
+      if ((!(maxx < itemxmin || minx > itemxmax)))
       {
-        hotlist_get_shape(&itemxmin, &itemxmax, item);
-        if ((!(maxx < itemxmin || minx > itemxmax)))
+        if (!(item->flags & HOTLIST_G_DRAG_SELECTED))
         {
-          if (!(item->flags & HOTLIST_G_DRAG_SELECTED))
+          item->flags |= HOTLIST_G_DRAG_SELECTED;
+          hotlist_redraw_items(*itemno, *itemno);
+          if (item->type == hl_directory && !(item->flags & HOTLIST_D_IS_OPEN)) /* If directory is closed select everything in it */
           {
-            item->flags |= HOTLIST_G_DRAG_SELECTED;
-            hotlist_redraw_items(itemno, itemno);
-            if (item->type == hl_directory && !(item->flags & HOTLIST_D_IS_OPEN)) /* If directory is closed select everything in it */
-            {
-              hotlist_set_flags(item->data.directory_content, hl_ALL, HOTLIST_G_DRAG_SELECTED);
-              hotlist_clear_flags(item->data.directory_content, hl_ALL, HOTLIST_G_REDRAW_NOW);
-            }
-          }
-        }
-        else
-        {
-          if (item->flags & HOTLIST_G_DRAG_SELECTED)
-          {
-            item->flags &= ~HOTLIST_G_DRAG_SELECTED;
-            hotlist_redraw_items(itemno, itemno);
-            if (item->type == hl_directory && !(item->flags & HOTLIST_D_IS_OPEN)) /* If directory is closed unselect everything in it */
-            {
-              hotlist_clear_flags(item->data.directory_content, hl_ALL, HOTLIST_G_DRAG_SELECTED | HOTLIST_G_REDRAW_NOW);
-            }
+            hotlist_set_flags(item->data.directory_content, hl_ALL, HOTLIST_G_DRAG_SELECTED);
+            hotlist_clear_flags(item->data.directory_content, hl_ALL, HOTLIST_G_REDRAW_NOW);
           }
         }
       }
@@ -5157,7 +5196,7 @@ static int hotlist_null_drag_select_handler(int event_code, WimpPollBlock * even
         if (item->flags & HOTLIST_G_DRAG_SELECTED)
         {
           item->flags &= ~HOTLIST_G_DRAG_SELECTED;
-          hotlist_redraw_items(itemno, itemno);
+          hotlist_redraw_items(*itemno, *itemno);
           if (item->type == hl_directory && !(item->flags & HOTLIST_D_IS_OPEN)) /* If directory is closed unselect everything in it */
           {
             hotlist_clear_flags(item->data.directory_content, hl_ALL, HOTLIST_G_DRAG_SELECTED | HOTLIST_G_REDRAW_NOW);
@@ -5165,9 +5204,27 @@ static int hotlist_null_drag_select_handler(int event_code, WimpPollBlock * even
         }
       }
     }
-  }
+    else
+    {
+      if (item->flags & HOTLIST_G_DRAG_SELECTED)
+      {
+        item->flags &= ~HOTLIST_G_DRAG_SELECTED;
+        hotlist_redraw_items(*itemno, *itemno);
+        if (item->type == hl_directory && !(item->flags & HOTLIST_D_IS_OPEN)) /* If directory is closed unselect everything in it */
+        {
+          hotlist_clear_flags(item->data.directory_content, hl_ALL, HOTLIST_G_DRAG_SELECTED | HOTLIST_G_REDRAW_NOW);
+        }
+      }
+    }
 
-  return 0;
+    *itemno += 1;
+
+    if (item->type == hl_directory && item->flags & HOTLIST_D_IS_OPEN)
+    {
+      hotlist_select_box_r(first_item, last_item, item->data.directory_content, itemno, minx, maxx);
+    }
+    item = item->next;
+  }
 }
 
 /*************************************************/
-- 
GitLab