use a pixbuf loader to allow the loading thread to be interrupted by the main thread...
[booh] / bin / booh-classifier
index b82e364703016c38e8c208dee8afb8e06b3ffd83..9959fd73cb9b592d63ea71c6e0ac48eaaf9ab6db 100644 (file)
@@ -231,7 +231,7 @@ end
 
 class Entry
     @@thumbnails_height = 64
 
 class Entry
     @@thumbnails_height = 64
-    @@max_height = nil
+    @@max_width = nil
     def Entry.thumbnails_height
         return @@thumbnails_height
     end
     def Entry.thumbnails_height
         return @@thumbnails_height
     end
@@ -241,8 +241,8 @@ class Entry
     def initialize(path, type)
         @path = path
         @type = type
     def initialize(path, type)
         @path = path
         @type = type
-        if @@max_height.nil?
-            @@max_height = $main_window.root_window.size[1]
+        if @@max_width.nil?
+            @@max_width = $main_window.root_window.size[0] - $labels_vbox.allocation.width
         end
         @protect_cleanup = Mutex.new
     end
         end
         @protect_cleanup = Mutex.new
     end
@@ -384,7 +384,27 @@ class Entry
                 image_path = @path
             end
             begin
                 image_path = @path
             end
             begin
-                @pixbuf_full = Gdk::Pixbuf.new(image_path)
+                #- use a pixbuf loader to allow the loading thread to be interrupted by the main thread more often, to keep the UI responsive even
+                #- if loaded pictures are several MBs large
+                loader = Gdk::PixbufLoader.new
+                loader.signal_connect('size-prepared') { |l,w,h|
+                    maxdim = w > h ? w : h
+                    if maxdim > @@max_width
+                        #- save memory and speedup (+35%) loading 
+                        loader.set_size(w * (factor = @@max_width.to_f/maxdim), h * factor)
+                        puts factor
+                    end
+                }
+                loader.signal_connect('area-prepared') { @pixbuf_full = loader.pixbuf }
+                file = File.new(image_path)
+                while (chunk = file.read(4096)) != nil
+                    loader.write(chunk)
+                end
+                file.close
+                loader.close
+                if @pixbuf_full.nil?
+                    raise "Loaded pixbuf nil - #{path} #{image_path}"
+                end
             rescue Gdk::PixbufError
                 msg 0, "Cannot load #{image_path}: #{$!}"
                 return
             rescue Gdk::PixbufError
                 msg 0, "Cannot load #{image_path}: #{$!}"
                 return
@@ -406,10 +426,6 @@ class Entry
                     msg 3, ">>> load_into_pixbuf_full #{image_path} => rotate #{@angle}"
                     @pixbuf_full = rotate_pixbuf(@pixbuf_full, @angle)
                 end
                     msg 3, ">>> load_into_pixbuf_full #{image_path} => rotate #{@angle}"
                     @pixbuf_full = rotate_pixbuf(@pixbuf_full, @angle)
                 end
-                if @pixbuf_full.height > @@max_height
-                    #- save a lot of memory, don't store in actual full size
-                    @pixbuf_full = @pixbuf_full.scale(@pixbuf_full.width * (@@max_height.to_f/@pixbuf_full.height), @@max_height, Gdk::Pixbuf::INTERP_BILINEAR)
-                end
             end
             if @type == 'video'
                 cleanup_dir(dest_dir)
             end
             if @type == 'video'
                 cleanup_dir(dest_dir)
@@ -445,7 +461,7 @@ class MainView < Gtk::DrawingArea
             @preloader = Thread.new {
                 #- background preloading
                 while true
             @preloader = Thread.new {
                 #- background preloading
                 while true
-                    msg 3, "background main preloading triggered..."
+                    msg 3, "*** >> background main preloading triggered..."
                     if ! @entry.nil?
                         index = $allentries.index(@entry)
                         w, h = window.size
                     if ! @entry.nil?
                         index = $allentries.index(@entry)
                         w, h = window.size
@@ -469,6 +485,7 @@ class MainView < Gtk::DrawingArea
                         end
                         check_memory_free_cache_if_needed
                     end
                         end
                         check_memory_free_cache_if_needed
                     end
+                    msg 3, "*** << background main preloading stopping"
                     Thread.stop
                 end
             }
                     Thread.stop
                 end
             }