[glom/glom-1-30] ImageGlom: Do not instantiate unnecessary widgets.



commit 3fa3f676b790828aa506af3ab537d6133bd2cef4
Author: Murray Cumming <murrayc murrayc com>
Date:   Thu Feb 25 10:17:52 2016 +0100

    ImageGlom: Do not instantiate unnecessary widgets.

 glom/utility_widgets/imageglom.cc |  129 ++++++++++++++++++++++--------------
 glom/utility_widgets/imageglom.h  |    4 +-
 2 files changed, 82 insertions(+), 51 deletions(-)
---
diff --git a/glom/utility_widgets/imageglom.cc b/glom/utility_widgets/imageglom.cc
index 40f63ca..5500e94 100644
--- a/glom/utility_widgets/imageglom.cc
+++ b/glom/utility_widgets/imageglom.cc
@@ -50,6 +50,7 @@ ImageGlom::ImageGlom()
 : m_ev_scrolled_window(nullptr),
   m_ev_view(nullptr),
   m_ev_document_model(nullptr),
+  m_image(nullptr),
   m_pMenuPopup_UserMode(nullptr)
 {
   init();
@@ -60,25 +61,82 @@ ImageGlom::ImageGlom(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>&
   m_ev_scrolled_window(nullptr),
   m_ev_view(nullptr),
   m_ev_document_model(nullptr),
+  m_image(nullptr),
   m_pMenuPopup_UserMode(nullptr)
 {
   init();
 }
 
-void ImageGlom::init()
+void ImageGlom::clear_image_from_widgets()
+{
+  if(m_image)
+  {
+    m_image->set(Glib::RefPtr<Gdk::Pixbuf>()); //TODO: Add an unset() to gtkmm.
+  }
+
+  if(m_ev_document_model)
+  {
+    g_object_unref(m_ev_document_model);
+    m_ev_document_model = nullptr;
+  }
+}
+
+void ImageGlom::init_widgets(bool use_evince)
 {
-  //TODO: Don't instantiate this unnecessarily.
-  m_ev_view = EV_VIEW(ev_view_new());
+  clear_image_from_widgets();
 
-  //gtk_widget_add_events(GTK_WIDGET(m_ev_view), GDK_BUTTON_PRESS_MASK);
+  m_frame.remove();
 
-  //Connect the the EvView's button-press-event signal, 
-  //because we don't get it otherwise.
-  //For some reason this is not necessary with the GtkImage.
-  auto cppEvView = Glib::wrap(GTK_WIDGET(m_ev_view));
-  cppEvView->signal_button_press_event().connect(
-    sigc::mem_fun(*this, &ImageGlom::on_button_press_event), false);
+  Gtk::Widget* widget = nullptr;
 
+  if(use_evince)
+  {
+    if(!m_ev_view)
+    {
+      m_ev_view = EV_VIEW(ev_view_new());
+      gtk_widget_show(GTK_WIDGET(m_ev_view));
+
+      m_ev_scrolled_window = Gtk::manage(new Gtk::ScrolledWindow());
+      gtk_container_add(GTK_CONTAINER(m_ev_scrolled_window->gobj()), GTK_WIDGET(m_ev_view));
+
+      //gtk_widget_add_events(GTK_WIDGET(m_ev_view), GDK_BUTTON_PRESS_MASK);
+
+      //Connect the the EvView's button-press-event signal, 
+      //because we don't get it otherwise.
+      //For some reason this is not necessary with the GtkImage.
+      auto cppEvView = Glib::wrap(GTK_WIDGET(m_ev_view));
+      cppEvView->signal_button_press_event().connect(
+        sigc::mem_fun(*this, &ImageGlom::on_button_press_event), false);
+    }
+
+    if(m_image)
+    {
+      delete m_image;
+      m_image = nullptr;
+    }
+
+    widget = m_ev_scrolled_window;
+  }
+  else
+  {
+    m_image = Gtk::manage(new Gtk::Image());
+    if(m_ev_view)
+    {
+      gtk_widget_destroy(GTK_WIDGET(m_ev_view));
+      m_ev_view = nullptr;
+      delete m_ev_scrolled_window;
+      m_ev_scrolled_window = nullptr;
+    }
+
+    widget = m_image;
+  }
+
+  widget->show();
+  m_frame.add(*widget);
+}
+
+void ImageGlom::init()
+{
   m_read_only = false;
 
 #ifndef GLOM_ENABLE_CLIENT_ONLY
@@ -87,9 +145,6 @@ void ImageGlom::init()
 
   setup_menu_usermode();
 
-  //m_image.set_size_request(150, 150);
-
-
   m_frame.set_shadow_type(Gtk::SHADOW_ETCHED_IN); //Without this, the image widget has no borders and is 
completely invisible when empty.
   m_frame.show();
 
@@ -210,7 +265,7 @@ void ImageGlom::on_size_allocate(Gtk::Allocation& allocation)
   if(m_pixbuf_original)
   {
     const auto pixbuf_scaled = get_scaled_image();
-    m_image.set(pixbuf_scaled);
+    m_image->set(pixbuf_scaled);
   }
 }
 
@@ -338,37 +393,15 @@ void ImageGlom::show_image_data()
   if(iterFind != m_evince_supported_mime_types.end())
   {
     use_evince = true;
-  }  
+  }
   
-  m_frame.remove();
-    
+  init_widgets(use_evince);
+
   //Clear all possible display widgets:
   m_pixbuf_original.reset();
-  m_image.set(Glib::RefPtr<Gdk::Pixbuf>()); //TODO: Add an unset() to gtkmm.
-  
-  if(m_ev_document_model)
-  {
-    g_object_unref(m_ev_document_model);
-    m_ev_document_model = nullptr;
-  }
 
   if(use_evince)
   {
-    //Use EvView:
-    m_image.hide();
-    
-    gtk_widget_show(GTK_WIDGET(m_ev_view));
-
-    if (!m_ev_scrolled_window)
-    {
-      m_ev_scrolled_window = Gtk::manage(new Gtk::ScrolledWindow());
-      m_ev_scrolled_window->show();
-      gtk_container_add(GTK_CONTAINER(m_ev_scrolled_window->gobj()), GTK_WIDGET(m_ev_view));
-    }
-
-    m_frame.add(*m_ev_scrolled_window);
-
-
     // Try loading from data in memory:
     // TODO: Uncomment this if this API is added: https://bugzilla.gnome.org/show_bug.cgi?id=654832
     /*
@@ -406,10 +439,6 @@ void ImageGlom::show_image_data()
   else
   {
     //Use GtkImage instead:
-    gtk_widget_hide(GTK_WIDGET(m_ev_view));  
-    m_image.show();
-    m_frame.add(m_image);
-    
     Glib::RefPtr<const Gio::Icon> icon;
       
     bool use_gdkpixbuf = false;
@@ -436,16 +465,16 @@ void ImageGlom::show_image_data()
     
     if(m_pixbuf_original)
     {
-      Glib::RefPtr<Gdk::Pixbuf> pixbuf_scaled = get_scaled_image();
-      m_image.set(pixbuf_scaled);
+      auto pixbuf_scaled = get_scaled_image();
+      m_image->set(pixbuf_scaled);
     }
     else if(icon)
     {
-      m_image.set(icon, Gtk::ICON_SIZE_DIALOG);
+      m_image->set(icon, Gtk::ICON_SIZE_DIALOG);
     }
     else
     {
-      m_image.set_from_icon_name("image-missing", Gtk::ICON_SIZE_DIALOG);
+      m_image->set_from_icon_name("image-missing", Gtk::ICON_SIZE_DIALOG);
     }
   }
 }
@@ -457,7 +486,7 @@ Glib::RefPtr<Gdk::Pixbuf> ImageGlom::get_scaled_image()
   if(!pixbuf)
     return pixbuf;
  
-  const auto allocation = m_image.get_allocation();
+  const auto allocation = m_image->get_allocation();
   const auto pixbuf_height = pixbuf->get_height();
   const auto pixbuf_width = pixbuf->get_width();
     
@@ -477,8 +506,8 @@ Glib::RefPtr<Gdk::Pixbuf> ImageGlom::get_scaled_image()
       //Don't set a new pixbuf if the dimensions have not changed:
       Glib::RefPtr<Gdk::Pixbuf> pixbuf_in_image;
 
-      if(m_image.get_storage_type() == Gtk::IMAGE_PIXBUF) //Prevent warning.
-        pixbuf_in_image = m_image.get_pixbuf();
+      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()) )
       {
diff --git a/glom/utility_widgets/imageglom.h b/glom/utility_widgets/imageglom.h
index 6c832e4..fdafa45 100644
--- a/glom/utility_widgets/imageglom.h
+++ b/glom/utility_widgets/imageglom.h
@@ -66,6 +66,8 @@ public:
   
 private:
   void init();
+  void init_widgets(bool use_evince);
+  void clear_image_from_widgets();
 
   virtual void on_size_allocate(Gtk::Allocation& allocation);
 
@@ -115,7 +117,7 @@ private:
   
   //For anything supported by GdkPixbuf,
   //or for representative thumbnails and icons:
-  Gtk::Image m_image;
+  Gtk::Image* m_image;
   Glib::RefPtr<Gdk::Pixbuf> m_pixbuf_original; //Only stored temporarily, because it could be big.
   Glib::RefPtr<Gdk::Pixbuf> m_pixbuf_clipboard; //When copy is used, store it here until it is pasted.
 


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