better rotations
authorgc <gc>
Fri, 1 Apr 2005 20:08:54 +0000 (20:08 +0000)
committergc <gc>
Fri, 1 Apr 2005 20:08:54 +0000 (20:08 +0000)
bin/booh-gui

index 3d77abd73b97f37d819f7f5dd30afcc2b0f1b611..c0a1f31ecee89ec9b6b7016d2852da42d21bd149 100755 (executable)
@@ -122,9 +122,8 @@ def view_element(filename)
 
     w = Gtk::Window.new
 
-    default_size = $images_size.detect { |sizeobj| sizeobj['default'] }
     msg 3, "filename: #{filename}"
-    dest_img = build_full_dest_filename(filename).sub(/\.[^\.]+$/, '') + "-#{default_size['fullscreen']}.jpg"
+    dest_img = build_full_dest_filename(filename).sub(/\.[^\.]+$/, '') + "-#{$default_size['fullscreen']}.jpg"
     #- typically this file won't exist in case of videos; try with the largest thumbnail around
     if !File.exists?(dest_img)
         alternatives = Dir[build_full_dest_filename(filename).sub(/\.[^\.]+$/, '') + '-*'].sort
@@ -164,11 +163,10 @@ def view_element(filename)
     w.show_all
 end
 
-$retail_tempfiles = {}
 def add_thumbnail(autotable, name, type, filename, caption)
 
     frame1 = Gtk::Frame.new
-    frame1.add(img = Gtk::Image.new(filename))
+    frame1.add(img = Gtk::Image.new($rotated_pixbufs[filename] ? $rotated_pixbufs[filename][:pixbuf] : filename))
     frame1.set_shadow_type(Gtk::SHADOW_ETCHED_OUT)
     hbox1 = Gtk::HBox.new
     hbox1.pack_start(Gtk::Label.new, true, true)
@@ -200,26 +198,38 @@ def add_thumbnail(autotable, name, type, filename, caption)
     $name2widgets[name] = { :textview => textview }
 
     rotate = Proc.new { |angle|
-        set_mousecursor_wait(vbox.window)
-
         #- update rotate attribute
         xmldir = $xmldoc.elements["//dir[@path='#{$current_path}']"]
         felem = xmldir.elements["[@filename='#{name}']"]
-        felem.add_attribute('rotate', felem.attributes['rotate'].to_i + angle)
-
-        #- rotate shown thumbnail
-        $retail_tempfiles[filename] = Tempfile.new('booh')
-        default_size = $images_size.detect { |sizeobj| sizeobj['default'] }
-        sys("#{$convert} -rotate #{angle} -geometry #{default_size['thumbnails']} '#{filename}' '#{$retail_tempfiles[filename].path}'")
-        img.set(filename = $retail_tempfiles[filename].path)
+        felem.add_attribute('rotate', current_angle = ( felem.attributes['rotate'].to_i + angle ) % 360)
 
         #- remove out of sync images
-        dest_img_base = build_full_dest_filename(name).sub(/\.[^\.]+$/, '')
-        for sizeobj in $images_size
-            system("rm -f #{dest_img_base}-#{sizeobj['fullscreen']}.jpg #{dest_img_base}-#{sizeobj['thumbnails']}.jpg")
+        if !$rotated_pixbufs[filename]
+            $rotated_pixbufs[filename] = { :orig => img.pixbuf, :angle_to_orig => angle % 360 }
+            dest_img_base = build_full_dest_filename(name).sub(/\.[^\.]+$/, '')
+            for sizeobj in $images_size
+                system("rm -f #{dest_img_base}-#{sizeobj['fullscreen']}.jpg #{dest_img_base}-#{sizeobj['thumbnails']}.jpg")
+            end
+        else
+            $rotated_pixbufs[filename][:angle_to_orig] = ( $rotated_pixbufs[filename][:angle_to_orig] + angle ) % 360
         end
+        msg 3, "angle: #{angle}, angle to orig: #{$rotated_pixbufs[filename][:angle_to_orig]}"
 
-        set_mousecursor_normal(vbox.window)
+        #- rotate shown thumbnail
+        pixbuf = $rotated_pixbufs[filename][:orig].rotate($rotated_pixbufs[filename][:angle_to_orig] == 90 ? Gdk::Pixbuf::ROTATE_CLOCKWISE :
+                                                              $rotated_pixbufs[filename][:angle_to_orig] == 180 ? Gdk::Pixbuf::ROTATE_UPSIDEDOWN :
+                                                              $rotated_pixbufs[filename][:angle_to_orig] == 270 ? Gdk::Pixbuf::ROTATE_COUNTERCLOCKWISE :
+                                                              Gdk::Pixbuf::ROTATE_NONE )
+        msg 3, "sizes: #{pixbuf.width} #{pixbuf.height} - desired #{$default_thumbnails[:x]}x#{$default_thumbnails[:y]}"
+        if pixbuf.height > $default_thumbnails[:y]
+            img.pixbuf = $rotated_pixbufs[filename][:pixbuf] = pixbuf.scale(pixbuf.width * ($default_thumbnails[:y].to_f/pixbuf.height), $default_thumbnails[:y],
+                                                                            Gdk::Pixbuf::INTERP_BILINEAR)
+        elsif pixbuf.width < $default_thumbnails[:x] && pixbuf.height < $default_thumbnails[:y]
+            img.pixbuf = $rotated_pixbufs[filename][:pixbuf] = pixbuf.scale($default_thumbnails[:x], pixbuf.height * ($default_thumbnails[:x].to_f/pixbuf.width),
+                                                                            Gdk::Pixbuf::INTERP_BILINEAR)
+        else
+            img.pixbuf = $rotated_pixbufs[filename][:pixbuf] = pixbuf
+        end
     }
 
     textview.signal_connect('key-press-event') { |w, event|
@@ -390,7 +400,6 @@ def save_changes
 end
 
 def show_thumbnails
-    default_size = $images_size.detect { |sizeobj| sizeobj['default'] }
     $autotable.clear
     $vbox2textview = {}
     $name2widgets = {}
@@ -398,7 +407,7 @@ def show_thumbnails
     xmldir = $xmldoc.elements["//dir[@path='#{$current_path}']"]
     xmldir.elements.each { |element|
         if element.name == 'image' || element.name == 'video'
-            dest_img = build_full_dest_filename(element.attributes['filename']).sub(/\.[^\.]+$/, '') + "-#{default_size['thumbnails']}.jpg"
+            dest_img = build_full_dest_filename(element.attributes['filename']).sub(/\.[^\.]+$/, '') + "-#{$default_size['thumbnails']}.jpg"
             msg 3, "dest_img: #{dest_img}"
             add_thumbnail($autotable, element.attributes['filename'], element.name, dest_img, from_utf8(element.attributes['caption']))
         end
@@ -408,6 +417,7 @@ end
 def open_file(filename)
     $filename = nil
     $current_path = nil   #- invalidate
+    $rotated_pixbufs = {}
 
     begin
         $xmldoc = REXML::Document.new File.new(filename)
@@ -433,6 +443,10 @@ def open_file(filename)
 
     $filename = filename
     select_theme(theme)
+    $default_size = $images_size.detect { |sizeobj| sizeobj['default'] }
+    $default_size['thumbnails'] =~ /(.*)x(.*)/
+    $default_thumbnails = { :x => $1.to_i, :y => $2.to_i }
+
     msg 3, "source: #{source}"
 
     xmldir = $xmldoc.elements["//dir[@path='#{source}']"]