[Gtk-sharp-list] ExposeEvent Feedback ?

Daniel Kornhauser dkor@media.mit.edu
Wed, 17 Dec 2003 17:52:29 -0500


--=-4grzcLkOTT4woD7M00Sb
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Here is the full source. I still have to clean up the code

But I commented above the line that "bugs" me with
// THIS IS RE-EMITING THE SIGNAL

						Daniel.

On Wed, 2003-12-17 at 18:33, Miguel de Icaza wrote:
> Hello,
> 
> > I'm trying to resize an image when my window is resized. But when I'm in
> > a ExposeEvent handler, doing
> > 
> > viewDisplay.Pixbuf = scaled_image;
> > 
> > throws another ExposeEvent witch leaves me continually throwing
> > ExposeEvent.
> > 
> > What I'm I doing wrong ?
> > 
> > Should I use another Event type ?
> 
> Hard to tell what is going on there without the full source.

--=-4grzcLkOTT4woD7M00Sb
Content-Disposition: attachment; filename=viewbyexample.glade
Content-Type: application/x-glade; name=viewbyexample.glade
Content-Transfer-Encoding: 7bit

<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">

<glade-interface>

<widget class="GtkWindow" id="window1">
  <property name="visible">True</property>
  <property name="title" translatable="yes">window1</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_NONE</property>
  <property name="modal">False</property>
  <property name="resizable">True</property>
  <property name="destroy_with_parent">False</property>
  <signal name="delete_event" handler="WindowDelete" last_modification_time="Tue, 16 Dec 2003 05:58:55 GMT"/>

  <child>
    <widget class="GtkHPaned" id="hpaned1">
      <property name="visible">True</property>
      <property name="can_focus">True</property>

      <child>
	<widget class="GtkVBox" id="vbox1">
	  <property name="visible">True</property>
	  <property name="homogeneous">False</property>
	  <property name="spacing">0</property>

	  <child>
	    <widget class="GtkMenuBar" id="menubar1">
	      <property name="visible">True</property>

	      <child>
		<widget class="GtkMenuItem" id="menuitem4">
		  <property name="visible">True</property>
		  <property name="label" translatable="yes">_File</property>
		  <property name="use_underline">True</property>

		  <child>
		    <widget class="GtkMenu" id="menuitem4_menu">

		      <child>
			<widget class="GtkImageMenuItem" id="new1">
			  <property name="visible">True</property>
			  <property name="label">gtk-new</property>
			  <property name="use_stock">True</property>
			</widget>
		      </child>

		      <child>
			<widget class="GtkImageMenuItem" id="open1">
			  <property name="visible">True</property>
			  <property name="label">gtk-open</property>
			  <property name="use_stock">True</property>
			</widget>
		      </child>

		      <child>
			<widget class="GtkImageMenuItem" id="save1">
			  <property name="visible">True</property>
			  <property name="label">gtk-save</property>
			  <property name="use_stock">True</property>
			</widget>
		      </child>

		      <child>
			<widget class="GtkImageMenuItem" id="save_as1">
			  <property name="visible">True</property>
			  <property name="label">gtk-save-as</property>
			  <property name="use_stock">True</property>
			</widget>
		      </child>

		      <child>
			<widget class="GtkMenuItem" id="separatormenuitem1">
			  <property name="visible">True</property>
			</widget>
		      </child>

		      <child>
			<widget class="GtkImageMenuItem" id="quit1">
			  <property name="visible">True</property>
			  <property name="label">gtk-quit</property>
			  <property name="use_stock">True</property>
			</widget>
		      </child>
		    </widget>
		  </child>
		</widget>
	      </child>

	      <child>
		<widget class="GtkMenuItem" id="menuitem5">
		  <property name="visible">True</property>
		  <property name="label" translatable="yes">_Edit</property>
		  <property name="use_underline">True</property>

		  <child>
		    <widget class="GtkMenu" id="menuitem5_menu">

		      <child>
			<widget class="GtkImageMenuItem" id="cut1">
			  <property name="visible">True</property>
			  <property name="label">gtk-cut</property>
			  <property name="use_stock">True</property>
			</widget>
		      </child>

		      <child>
			<widget class="GtkImageMenuItem" id="copy1">
			  <property name="visible">True</property>
			  <property name="label">gtk-copy</property>
			  <property name="use_stock">True</property>
			</widget>
		      </child>

		      <child>
			<widget class="GtkImageMenuItem" id="paste1">
			  <property name="visible">True</property>
			  <property name="label">gtk-paste</property>
			  <property name="use_stock">True</property>
			</widget>
		      </child>

		      <child>
			<widget class="GtkImageMenuItem" id="delete1">
			  <property name="visible">True</property>
			  <property name="label">gtk-delete</property>
			  <property name="use_stock">True</property>
			</widget>
		      </child>
		    </widget>
		  </child>
		</widget>
	      </child>

	      <child>
		<widget class="GtkMenuItem" id="menuitem6">
		  <property name="visible">True</property>
		  <property name="label" translatable="yes">_View</property>
		  <property name="use_underline">True</property>
		</widget>
	      </child>

	      <child>
		<widget class="GtkMenuItem" id="menuitem7">
		  <property name="visible">True</property>
		  <property name="label" translatable="yes">_Help</property>
		  <property name="use_underline">True</property>

		  <child>
		    <widget class="GtkMenu" id="menuitem7_menu">

		      <child>
			<widget class="GtkMenuItem" id="about1">
			  <property name="visible">True</property>
			  <property name="label" translatable="yes">_About</property>
			  <property name="use_underline">True</property>
			</widget>
		      </child>
		    </widget>
		  </child>
		</widget>
	      </child>
	    </widget>
	    <packing>
	      <property name="padding">0</property>
	      <property name="expand">False</property>
	      <property name="fill">False</property>
	    </packing>
	  </child>

	  <child>
	    <widget class="GtkHandleBox" id="handlebox1">
	      <property name="visible">True</property>
	      <property name="shadow_type">GTK_SHADOW_OUT</property>
	      <property name="handle_position">GTK_POS_LEFT</property>
	      <property name="snap_edge">GTK_POS_TOP</property>

	      <child>
		<widget class="GtkToolbar" id="toolbar1">
		  <property name="visible">True</property>
		  <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
		  <property name="toolbar_style">GTK_TOOLBAR_ICONS</property>
		  <property name="tooltips">True</property>

		  <child>
		    <placeholder/>
		  </child>

		  <child>
		    <placeholder/>
		  </child>

		  <child>
		    <placeholder/>
		  </child>

		  <child>
		    <placeholder/>
		  </child>

		  <child>
		    <placeholder/>
		  </child>

		  <child>
		    <placeholder/>
		  </child>

		  <child>
		    <placeholder/>
		  </child>

		  <child>
		    <placeholder/>
		  </child>

		  <child>
		    <placeholder/>
		  </child>

		  <child>
		    <placeholder/>
		  </child>
		</widget>
	      </child>
	    </widget>
	    <packing>
	      <property name="padding">0</property>
	      <property name="expand">True</property>
	      <property name="fill">True</property>
	    </packing>
	  </child>

	  <child>
	    <placeholder/>
	  </child>

	  <child>
	    <placeholder/>
	  </child>

	  <child>
	    <placeholder/>
	  </child>

	  <child>
	    <placeholder/>
	  </child>

	  <child>
	    <placeholder/>
	  </child>

	  <child>
	    <placeholder/>
	  </child>

	  <child>
	    <widget class="GtkScrolledWindow" id="scrolledwindow1">
	      <property name="visible">True</property>
	      <property name="can_focus">True</property>
	      <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
	      <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
	      <property name="shadow_type">GTK_SHADOW_NONE</property>
	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>

	      <child>
		<placeholder/>
	      </child>
	    </widget>
	    <packing>
	      <property name="padding">0</property>
	      <property name="expand">True</property>
	      <property name="fill">True</property>
	    </packing>
	  </child>
	</widget>
	<packing>
	  <property name="shrink">True</property>
	  <property name="resize">False</property>
	</packing>
      </child>

      <child>
	<placeholder/>
      </child>
    </widget>
  </child>
</widget>

</glade-interface>

--=-4grzcLkOTT4woD7M00Sb
Content-Disposition: attachment; filename=ViewByExample.cs
Content-Type: text/plain; name=ViewByExample.cs; charset=
Content-Transfer-Encoding: 7bit

// Monopad.cs - A Simple Viewer  Example
//
// Author: Daniel Kornhauser
//
// (c) 2003 Daniel Kornhauser


using System;
using Gdk;
using Gtk;
using Glade;
using GtkSharp;
using System.Collections;
using System.IO;

public class Viewer
{
	public static void Main (string[] args)
	{
		new Viewer (args);
	}
	
	[Glade.Widget] Gtk.Window window;
	[Glade.Widget] VBox vbox1;
	[Glade.Widget] HPaned hpaned1;
	[Glade.Widget] ScrolledWindow scrolledwindow1;
	
	public Viewer (string[] args) 
	{
		Application.Init ();

		Glade.XML gxml = new Glade.XML ("viewbyexample.glade", "window1", null);
		gxml.Autoconnect (this);

		ArrayList images = new PixbufList ();

		ImageView imageView = new ImageView(images);
		hpaned1.Add2(imageView);

		ListStore thumbnailStore = new ThumbnailStore (images);
		ThumbnailView thumbnailView = new ThumbnailView (thumbnailStore, 
				                                 imageView);
		thumbnailView.ShowAll();
		scrolledwindow1.Add (thumbnailView);

		Application.Run ();	

	}		

	private void WindowDelete (object o, DeleteEventArgs args)
	{
		Application.Quit ();	
	}

}			

public class ImageView : ScrolledWindow
{
	public Gtk.Image viewDisplay;
	public ArrayList images;
	public Viewport viewport;
	public int pos;

	public ImageView (ArrayList images) 
	{
		this.images = images;

		Viewport viewport = new Viewport();
		this.Add(viewport);
		this.viewport = viewport;
		this.viewDisplay = new Gtk.Image ();
		this.viewDisplay.ExposeEvent += new ExposeEventHandler (ResizePixbuf);
		viewport.Add(viewDisplay);
		this.ShowAll();

	}
	public void ResizePixbuf (object obj, ExposeEventArgs args)
	{
		Gdk.EventExpose ev = args.Event;
		Gdk.Rectangle area = ev.area;
		Console.WriteLine ("area" , area.ToString());
	     	int image_width, image_height;
		int available_width = this.Allocation.width;
		int available_height = this.Allocation.height;
			Console.WriteLine("width {0}  height {1}",
					available_width.ToString(),
				        available_height.ToString());
		PixbufUtils.Fit ((Pixbuf) images[pos], 
				available_width,
				available_height, false,
				out image_width, out image_height);
		Pixbuf pixbuf = (Pixbuf) images[pos];
		Pixbuf scaled_image = pixbuf.ScaleSimple (
			                         image_width, image_height,
						 Gdk.InterpType.Bilinear); 
		viewDisplay.Pixbuf = scaled_image;		

	}

	public void LoadPixbuf (int pos)
	{
		int image_width, image_height;
		int available_width = this.Allocation.width;
		int available_height = this.Allocation.height;
		this.pos = pos;
			Console.WriteLine("width {0}  height {1}",
					available_width.ToString(),
				        available_height.ToString());
		PixbufUtils.Fit ((Pixbuf) images[pos], 
				available_width,
				available_height, false,
				out image_width, out image_height);
		Pixbuf pixbuf = (Pixbuf) images[pos];
		Pixbuf scaled_image = pixbuf.ScaleSimple (
			                         image_width, image_height,
						 Gdk.InterpType.Bilinear); 
		// THIS IS RE-EMITING THE SIGNAL
		viewDisplay.Pixbuf = scaled_image;		
	}

}


public class ThumbnailView : TreeView
{
	ImageView imageView;
	public ThumbnailView (ListStore thumbnailStore,
			      ImageView imageView) 
		: base (thumbnailStore)
	{
		this.imageView = imageView;
		Gtk.CellRendererPixbuf rendererPixbuf = new Gtk.CellRendererPixbuf();
		this.Selection.Changed += new EventHandler (OnTreeChanged);
		TreeViewColumn  column = new TreeViewColumn(null, rendererPixbuf, "pixbuf", 0);
		this.AppendColumn(column);
		//this.Selection.SelectPath(new TreePath("0"));
	}


	private void OnTreeChanged (object o, EventArgs args)
	{

		TreeIter iter;
		TreeModel model;

		if (this.Selection.GetSelected (out model, out iter)){
			TreePath path;
			path = this.Model.GetPath (iter);
			imageView.LoadPixbuf (path.Indices[0]);
		}
	}
}

public class ThumbnailStore : ListStore
{
	public ThumbnailStore (ArrayList images) : base (typeof(Pixbuf))
	{
		foreach (object image in images) {
			Console.WriteLine(image);
			Pixbuf pixbuf = (Pixbuf) image;
			pixbuf = pixbuf.ScaleSimple (64, 64, InterpType.Bilinear);
			this.AppendValues(pixbuf);}
	}
}

public class PixbufList : ArrayList
{
	public  PixbufList ()
	{

		DirectoryInfo dir_info = new DirectoryInfo (".");

		if (dir_info.Exists == false)
			throw new DirectoryNotFoundException ("." + " does not exist.");

		FileInfo [] files = dir_info.GetFiles ();

		foreach (FileInfo fi in files) {
			if (!fi.Name.EndsWith ("png") &&
					!fi.Name.EndsWith ("jpg") &&
					!fi.Name.EndsWith ("jpeg") &&
					!fi.Name.EndsWith ("gif"))
				continue;
			else {
				string filename = String.Format ("{0}/{1}", fi.DirectoryName, fi.Name);
				Pixbuf pixbuf = new Pixbuf (filename);
				this.Add (pixbuf);
			}
		}
	}

}


class PixbufUtils {

	public static int GetSize (Pixbuf pixbuf)
	{
		return Math.Max (pixbuf.Width, pixbuf.Height);
	}

	public static int ComputeScaledWidth (Pixbuf pixbuf, int size)
	{
		int orig_width = (int) pixbuf.Width;
		int orig_height = (int) pixbuf.Height;

		if (orig_width > orig_height)
			return size;
		else
			return (int) Math.Round ((int) size * ((double) orig_width / (double) orig_height));
	}

	public static int ComputeScaledHeight (Pixbuf pixbuf, int size)
	{
		int orig_width = (int) pixbuf.Width;
		int orig_height = (int) pixbuf.Height;

		if (orig_width > orig_height)
			return (int) Math.Round ((int) size * ((double) orig_height / (double) orig_width));
		else
			return size;
	}

	public static void Fit (Pixbuf pixbuf,
			int dest_width, int dest_height,
			bool upscale_smaller,
			out int fit_width, out int fit_height)
	{
		if (pixbuf.Width == 0 || pixbuf.Height == 0) {
			fit_width = 0;
			fit_height = 0;
			return;
		}

		if (pixbuf.Width <= dest_width && pixbuf.Height <= dest_height && ! upscale_smaller) {
			fit_width = pixbuf.Width;
			fit_height = pixbuf.Height;
			return;
		}

		fit_width = dest_width;
		fit_height = (int) Math.Round ((double) (pixbuf.Height * fit_width) / pixbuf.Width);

		if (fit_height > dest_height) {
			fit_height = dest_height;
			fit_width = (int) Math.Round ((double) (pixbuf.Width * fit_height) / pixbuf.Height);
		}
	}

}


--=-4grzcLkOTT4woD7M00Sb--