[glom] ImageGlom: Remove limits so we always scale, and use on_size_allocate().



commit 58e42d6de6975cecbfa2a9a948dd7461b6f91529
Author: Murray Cumming <murrayc murrayc com>
Date:   Thu Jul 14 10:22:59 2011 +0200

    ImageGlom: Remove limits so we always scale, and use on_size_allocate().
    
    * glom/utility_widgets/imageglom.[h|cc]: Use on_size_allocate() instead of
    on_draw(), which is slightly wiser.
    Remove the hard-coded checks for minumum and maximum sizes, because
    we get an initial allocation of 1, and because the max was arbitrarily small.
    
    This works now, but we still need to make the window get smaller when
    the GtkImage requests less space.

 ChangeLog                         |   15 ++++++++
 glom/utility_widgets/imageglom.cc |   70 +++++++++++++++++++-----------------
 glom/utility_widgets/imageglom.h  |    6 ++-
 glom/utils_ui.cc                  |   15 +++++---
 4 files changed, 66 insertions(+), 40 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 5452e8c..4f92751 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2011-07-14  Murray Cumming  <murrayc murrayc com>
+
+	ImageGlom: Remove limits so we always scale, and use on_size_allocate().
+
+	* glom/utility_widgets/imageglom.[h|cc]: Use on_size_allocate() instead of 
+	on_draw(), which is slightly wiser.
+	Remove the hard-coded checks for minumum and maximum sizes, because 
+	we get an initial allocation of 1, and because the max was arbitrarily small.
+	* glom/utils_ui.cc: Fix this for images that are both 
+	too wide and too high.
+	
+	This works now, but we still need to make the window get smaller when 
+	the GtkImage requests less space.
+
+
 2011-07-13  Murray Cumming  <murrayc murrayc com>
 
 	ImageGlom: Remove hard-coded mentions of PNG file formats.
diff --git a/glom/utility_widgets/imageglom.cc b/glom/utility_widgets/imageglom.cc
index 457a98b..65be900 100644
--- a/glom/utility_widgets/imageglom.cc
+++ b/glom/utility_widgets/imageglom.cc
@@ -222,14 +222,15 @@ Gnome::Gda::Value ImageGlom::get_value() const
   return Gnome::Gda::Value();
 }
 
-bool ImageGlom::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
+void ImageGlom::on_size_allocate(Gtk::Allocation& allocation)
 {
-  const bool result = Gtk::EventBox::on_draw(cr);
+  Gtk::EventBox::on_size_allocate(allocation);
 
   if(m_pixbuf_original)
-    scale_image();
-
-  return result;
+  {
+    Glib::RefPtr<Gdk::Pixbuf> pixbuf_scaled = get_scaled_image();
+    m_image.set(pixbuf_scaled);
+  }
 }
 
 static void image_glom_ev_job_finished(EvJob* job, void* user_data)
@@ -378,18 +379,21 @@ void ImageGlom::show_image_data()
     
     m_pixbuf_original = Utils::get_pixbuf_for_gda_value(m_original_data);
     if(m_pixbuf_original)
-       m_image.set(m_pixbuf_original);
+    {
+      Glib::RefPtr<Gdk::Pixbuf> pixbuf_scaled = get_scaled_image();
+      m_image.set(pixbuf_scaled);
+    }
     else
       m_image.set(Gtk::Stock::MISSING_IMAGE, Gtk::ICON_SIZE_DIALOG);
   }
 }
 
-void ImageGlom::scale_image()
+Glib::RefPtr<Gdk::Pixbuf> ImageGlom::get_scaled_image()
 {
   Glib::RefPtr<Gdk::Pixbuf> pixbuf = m_pixbuf_original;
 
   if(!pixbuf)
-    return;
+    return pixbuf;
  
   const Gtk::Allocation allocation = m_image.get_allocation();
   const int pixbuf_height = pixbuf->get_height();
@@ -397,42 +401,42 @@ void ImageGlom::scale_image()
     
   int allocation_height = allocation.get_height();
   int allocation_width = allocation.get_width();
-    
-  //If the Image widget has expanded to be big enough for the original image,
-  //it might be huge. We don't want that.
-  //Scaling it down will reduce how much it requests.
-  if(allocation_width >= 400)
-    allocation_width = 400;
-      
-  if(allocation_height >= 400)
-    allocation_height = 400;
       
-  //std::cout << "pixbuf_height=" << pixbuf_height << ", pixbuf_width=" << pixbuf_width << std::endl;
-  //std::cout << "allocation_height=" << allocation.get_height() << ", allocation_width=" << allocation.get_width() << std::endl;
+  std::cout << "pixbuf_height=" << pixbuf_height << ", pixbuf_width=" << pixbuf_width << std::endl;
+  std::cout << "allocation_height=" << allocation.get_height() << ", allocation_width=" << allocation.get_width() << std::endl;
 
-  if( (pixbuf_height >allocation_height ) ||
+  if( (pixbuf_height > allocation_height) ||
       (pixbuf_width > allocation_width) )
   {
-    if(allocation_height > 10 || allocation_width > 10)
+    if(true) //allocation_height > 10 || allocation_width > 10)
     {
-      Glib::RefPtr<Gdk::Pixbuf> pixbuf_scaled = Utils::image_scale_keeping_ratio(pixbuf, allocation.get_height(), allocation.get_width());
-      if(!pixbuf_scaled)
+      Glib::RefPtr<Gdk::Pixbuf> pixbuf_scaled = Utils::image_scale_keeping_ratio(pixbuf, allocation_height, allocation_width);
+      
+      //Don't set a new pixbuf if the dimensions have not changed:
+      Glib::RefPtr<const Gdk::Pixbuf> pixbuf_in_image;
+
+      if(m_image.get_storage_type() == Gtk::IMAGE_PIXBUF) //Prevent warning.
+        pixbuf_in_image = m_image.get_pixbuf();
+
+      if( !pixbuf_in_image || !pixbuf_scaled || (pixbuf_in_image->get_height() != pixbuf_scaled->get_height()) || (pixbuf_in_image->get_width() != pixbuf_scaled->get_width()) )
       {
-        std::cerr << "Utils::image_scale_keeping_ratio() returned NULL pixbuf." << std::endl;
+        std::cout << "get_scale(): returning scaled" << std::endl;
+        if(pixbuf_scaled)
+        {
+          std::cout << "scaled height=" << pixbuf_scaled->get_height() << ", scaled width=" << pixbuf_scaled->get_width() << std::endl;
+        }
+        
+        return pixbuf_scaled;
       }
-      else 
+      else
       {
-        //Don't set a new pixbuf if the dimensions have not changed:
-        Glib::RefPtr<const Gdk::Pixbuf> pixbuf_in_image;
-
-        if(m_image.get_storage_type() == Gtk::IMAGE_PIXBUF) //Prevent warning.
-          pixbuf_in_image = m_image.get_pixbuf();
-
-        if( !pixbuf_in_image || (pixbuf_in_image->get_height() != pixbuf_scaled->get_height()) || (pixbuf_in_image->get_width() != pixbuf_scaled->get_width()) )
-          m_image.set(pixbuf_scaled);
+        std::cout << "scaled image not used." << std::endl;
       }
     }
   }
+  
+  std::cout << "get_scaled(): returning original" << std::endl;
+  return pixbuf;
 }
 
 void ImageGlom::on_menupopup_activate_open_file()
diff --git a/glom/utility_widgets/imageglom.h b/glom/utility_widgets/imageglom.h
index 5e2bf7e..27b52c2 100644
--- a/glom/utility_widgets/imageglom.h
+++ b/glom/utility_widgets/imageglom.h
@@ -61,7 +61,7 @@ public:
 private:
   void init();
 
-  virtual bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr);
+  virtual void on_size_allocate(Gtk::Allocation& allocation);
 
   virtual bool on_button_press_event(GdkEventButton *event);
 
@@ -81,7 +81,9 @@ private:
 
   void setup_menu_usermode();
   void show_image_data();
-  void scale_image();
+  
+  //Get a pixbuf scaled down to the current size allocation:
+  Glib::RefPtr<Gdk::Pixbuf> get_scaled_image();
   
   Glib::ustring save_to_temp_file(bool show_progress = true);
   bool save_file(const Glib::ustring& uri);
diff --git a/glom/utils_ui.cc b/glom/utils_ui.cc
index 8e7a168..672f4f0 100644
--- a/glom/utils_ui.cc
+++ b/glom/utils_ui.cc
@@ -429,6 +429,7 @@ Glib::RefPtr<Gdk::Pixbuf> Utils::image_scale_keeping_ratio(const Glib::RefPtr<Gd
   {
     SCALE_WIDTH,
     SCALE_HEIGHT,
+    SCALE_BOTH,
     SCALE_NONE
   };
 
@@ -441,11 +442,7 @@ Glib::RefPtr<Gdk::Pixbuf> Utils::image_scale_keeping_ratio(const Glib::RefPtr<Gd
   {
     if(pixbuf_width > target_width)
     {
-      //Both are bigger than the target, so find the biggest one:
-      if(pixbuf_width > pixbuf_height)
-        scale_mode = SCALE_WIDTH;
-      else
-        scale_mode = SCALE_HEIGHT;
+      scale_mode = SCALE_BOTH;
     }
     else
     {
@@ -471,6 +468,14 @@ Glib::RefPtr<Gdk::Pixbuf> Utils::image_scale_keeping_ratio(const Glib::RefPtr<Gd
     const float ratio = (float)target_width / (float) pixbuf_width;
     target_height = (int)((float)pixbuf_height * ratio);
   }
+  else if(scale_mode == SCALE_BOTH)
+  {
+    const float ratio = std::min(
+      (float)target_width / (float) pixbuf_width,
+      (float)target_height / (float) pixbuf_height);
+    target_width = (int)((float)pixbuf_width * ratio);
+    target_height = (int)((float)pixbuf_height * ratio);
+  }
 
  if( (target_height == 0) || (target_width == 0) )
  {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]