mistelix r8 - in trunk: . data extensions/Effects extensions/Effects/Brightness extensions/Effects/Contrast extensions/Effects/RotateImage extensions/SlideTransitions/Fade gstreamer libmistelix po src src/core src/datamodel src/widgets



Author: jmas
Date: Mon Mar 30 13:14:15 2009
New Revision: 8
URL: http://svn.gnome.org/viewvc/mistelix?rev=8&view=rev

Log:
More work on effects. Brightness and Contrast effects

Added:
   trunk/extensions/Effects/Brightness/
   trunk/extensions/Effects/Brightness/Brightness.addin.xml
   trunk/extensions/Effects/Brightness/Brightness.cs
   trunk/extensions/Effects/Brightness/Makefile.am
   trunk/extensions/Effects/Contrast/
   trunk/extensions/Effects/Contrast/Contrast.addin.xml
   trunk/extensions/Effects/Contrast/Contrast.cs
   trunk/extensions/Effects/Contrast/Makefile.am
   trunk/src/datamodel/Effect.cs   (contents, props changed)
      - copied, changed from r7, /trunk/src/datamodel/IEffect.cs
Removed:
   trunk/data/ChangeLog
   trunk/gstreamer/ChangeLog
   trunk/libmistelix/ChangeLog
   trunk/src/ChangeLog
   trunk/src/core/NoneEffect.cs
   trunk/src/datamodel/IEffect.cs
Modified:
   trunk/ChangeLog
   trunk/configure.in
   trunk/extensions/Effects/Makefile.am
   trunk/extensions/Effects/RotateImage/RotateImage.addin.xml
   trunk/extensions/Effects/RotateImage/RotateImage.cs
   trunk/extensions/SlideTransitions/Fade/Fade.cs
   trunk/extensions/SlideTransitions/Fade/Makefile.am
   trunk/po/POTFILES.in
   trunk/src/Makefile.am
   trunk/src/core/EffectManager.cs
   trunk/src/core/SlideImage.cs
   trunk/src/datamodel/SlideShowProjectElement.cs
   trunk/src/mistelix.addin.xml
   trunk/src/mistelix.cs
   trunk/src/widgets/SlideShowImageView.cs

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Mon Mar 30 13:14:15 2009
@@ -1,4 +1,4 @@
-AC_INIT(mistelix, 0.10)
+AC_INIT(mistelix, 0.11)
 AC_CONFIG_SRCDIR(src/mistelix.cs)
 
 AM_CONFIG_HEADER(config.h)
@@ -135,4 +135,6 @@
 extensions/SlideTransitions/OpaqueLines/Makefile
 extensions/Effects/Makefile
 extensions/Effects/RotateImage/Makefile
+extensions/Effects/Brightness/Makefile
+extensions/Effects/Contrast/Makefile
 ])

Added: trunk/extensions/Effects/Brightness/Brightness.addin.xml
==============================================================================
--- (empty file)
+++ trunk/extensions/Effects/Brightness/Brightness.addin.xml	Mon Mar 30 13:14:15 2009
@@ -0,0 +1,17 @@
+<Addin namespace="Mistelix"
+	version="0.10"
+	name="Brightness"
+	description="Adjust image color brightness"
+	author="Jordi Mas"
+	url=""
+	defaultEnabled="true"
+	category="Effects">
+
+	<Dependencies>
+		<Addin id="Mistelix" version="0.10"/>
+	</Dependencies>
+
+	<Extension path="/Mistelix/Effects">
+		<Effects type="Mistelix.Effects.Brightness" />
+	</Extension>
+</Addin>

Added: trunk/extensions/Effects/Brightness/Brightness.cs
==============================================================================
--- (empty file)
+++ trunk/extensions/Effects/Brightness/Brightness.cs	Mon Mar 30 13:14:15 2009
@@ -0,0 +1,90 @@
+//
+// Copyright (C) 2009 Jordi Mas i Hernandez, jmas softcatala org
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using Mono.Unix;
+
+using Mistelix.DataModel;
+using Mistelix.Effects;
+
+namespace Mistelix.Effects
+{
+	public class Brightness: Effect
+	{
+		readonly UIOption [] options;
+		const int OPTION_INCREMENT = 0;
+		const int OPTION_REDUCE = 1;
+		double _value;
+
+		public Brightness ()
+		{
+			_value = 1.0;
+			options = new UIOption [2];
+			options[0] = new UIOption (Catalog.GetString ("Increase Brightness"), OPTION_INCREMENT, OnIncrement);
+			options[1] = new UIOption (Catalog.GetString ("Reduce Brightness"), OPTION_REDUCE, OnReduce);
+		}
+
+		public override string DisplayName {
+			get { return ("Brightness"); }
+		}
+
+		public override string Name {
+			get { return ("brightness"); }
+		}
+
+		public override SlideImage ApplyEffect (SlideImage org)
+		{
+			SlideImage image;
+
+			image = new SlideImage ();
+			image.CopyProperties (org);
+			image.Pixels = new byte [org.stride * org.height];
+
+			for (int i = 0; i < org.stride * org.height; i++)
+				image.Pixels[i] = (byte) ((double) org.Pixels[i] * _value);
+	
+			return image;
+		}
+
+		public override UIOption [] Options {
+			get {return options; }
+		}
+
+		public override string Value {
+			get { return _value.ToString (); }
+			set { _value = Double.Parse (value);}
+		}
+
+		void OnIncrement (object obj, EventArgs e)
+		{
+			_value += 0.1;
+			OnUIOptionInvoked (OPTION_INCREMENT);
+		}
+
+		void OnReduce (object obj, EventArgs e)
+		{
+			_value -= 0.1;
+			OnUIOptionInvoked (OPTION_REDUCE);
+		}
+	}
+}

Added: trunk/extensions/Effects/Brightness/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/extensions/Effects/Brightness/Makefile.am	Mon Mar 30 13:14:15 2009
@@ -0,0 +1,39 @@
+PLUGIN_NAME = Brightness
+
+PLUGIN_MANIFEST = $(PLUGIN_NAME).addin.xml
+
+PLUGIN_ASSEMBLY = $(PLUGIN_NAME).dll
+
+PLUGIN_SOURCES =			\
+	$(srcdir)/Brightness.cs
+
+REFS =					\
+	-r:$(top_builddir)/src/mistelix.exe
+
+PKGS =					\
+	-pkg:gtk-sharp-2.0
+
+RESOURCES =				\
+	-resource:$(srcdir)/$(PLUGIN_MANIFEST)
+
+all: $(PLUGIN_ASSEMBLY)
+
+mpack: $(PLUGIN_ASSEMBLY)
+	mautil p $(PLUGIN_ASSEMBLY)
+
+$(PLUGIN_ASSEMBLY): $(PLUGIN_SOURCES) $(PLUGIN_MANIFEST)
+	$(CSC) -target:library -out:$@ $(CSC_DEFINES) $(PLUGIN_SOURCES) $(REFS) $(PKGS) $(ASSEMBLIES) $(RESOURCES) -r:Mono.Posix
+
+plugindir = $(pkglibdir)/extensions
+
+plugin_DATA =			\
+	$(PLUGIN_ASSEMBLY)
+
+EXTRA_DIST = 			\
+	$(PLUGIN_SOURCES)	\
+	$(PLUGIN_MANIFEST)
+
+CLEANFILES =			\
+	$(PLUGIN_ASSEMBLY)	\
+	$(PLUGIN_ASSEMBLY).mdb	\
+	*.mpack

Added: trunk/extensions/Effects/Contrast/Contrast.addin.xml
==============================================================================
--- (empty file)
+++ trunk/extensions/Effects/Contrast/Contrast.addin.xml	Mon Mar 30 13:14:15 2009
@@ -0,0 +1,17 @@
+<Addin namespace="Mistelix"
+	version="0.10"
+	name="Contrast"
+	description="Adjust image color brightness"
+	author="Jordi Mas"
+	url=""
+	defaultEnabled="true"
+	category="Effects">
+
+	<Dependencies>
+		<Addin id="Mistelix" version="0.10"/>
+	</Dependencies>
+
+	<Extension path="/Mistelix/Effects">
+		<Effects type="Mistelix.Effects.Contrast" />
+	</Extension>
+</Addin>

Added: trunk/extensions/Effects/Contrast/Contrast.cs
==============================================================================
--- (empty file)
+++ trunk/extensions/Effects/Contrast/Contrast.cs	Mon Mar 30 13:14:15 2009
@@ -0,0 +1,119 @@
+//
+// Copyright (C) 2009 Jordi Mas i Hernandez, jmas softcatala org
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using Mono.Unix;
+
+using Mistelix.DataModel;
+using Mistelix.Effects;
+
+namespace Mistelix.Effects
+{
+	public class Contrast: Effect
+	{
+		readonly UIOption [] options;
+		const int OPTION_INCREMENT = 0;
+		const int OPTION_REDUCE = 1;
+		double contrast;
+
+		public Contrast ()
+		{
+			contrast = 10.0;
+			options = new UIOption [2];
+			options[0] = new UIOption (Catalog.GetString ("Increase Contrast"), OPTION_INCREMENT, OnIncrement);
+			options[1] = new UIOption (Catalog.GetString ("Reduce Contrast"), OPTION_REDUCE, OnReduce);
+		}
+
+		public override string DisplayName {
+			get { return ("Contrast"); }
+		}
+
+		public override string Name {
+			get { return ("Contrast"); }
+		}
+
+		public override SlideImage ApplyEffect (SlideImage org)
+		{
+			SlideImage image;
+
+			image = new SlideImage ();
+			image.CopyProperties (org);
+			image.Pixels = new byte [org.stride * org.height];
+
+			for (int i = 0; i < org.stride * org.height; i++)
+				image.Pixels[i] = ContrastPixel (org.Pixels[i]);
+
+			return image;
+		}
+
+		public override UIOption [] Options {
+			get {return options; }
+		}
+
+		public override string Value {
+			get { return contrast.ToString (); }
+			set { contrast = Double.Parse (value);}
+		}
+
+		byte ContrastPixel (byte pixel)
+		{
+			byte result;
+			double pixel_contrast;
+
+			if (pixel >= 127) {
+				pixel_contrast = pixel + contrast;
+
+				if (pixel_contrast > 255)
+					result = 255;
+				else
+					if (pixel_contrast < 127)
+						result = 127;
+					else
+						result = (byte) pixel_contrast;
+			} else {
+				pixel_contrast = pixel - contrast;
+
+				if (pixel_contrast < 0)
+					result = 0;
+				else
+					if (pixel_contrast > 127)
+						result = 126;
+					else
+						result = (byte) pixel_contrast;
+			}
+			return result;
+		}
+
+		void OnIncrement (object obj, EventArgs e)
+		{
+			contrast += 10;
+			OnUIOptionInvoked (OPTION_INCREMENT);
+		}
+
+		void OnReduce (object obj, EventArgs e)
+		{
+			contrast -= 10;
+			OnUIOptionInvoked (OPTION_REDUCE);
+		}
+	}
+}

Added: trunk/extensions/Effects/Contrast/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/extensions/Effects/Contrast/Makefile.am	Mon Mar 30 13:14:15 2009
@@ -0,0 +1,39 @@
+PLUGIN_NAME = Contrast
+
+PLUGIN_MANIFEST = $(PLUGIN_NAME).addin.xml
+
+PLUGIN_ASSEMBLY = $(PLUGIN_NAME).dll
+
+PLUGIN_SOURCES =			\
+	$(srcdir)/Contrast.cs
+
+REFS =					\
+	-r:$(top_builddir)/src/mistelix.exe
+
+PKGS =					\
+	-pkg:gtk-sharp-2.0
+
+RESOURCES =				\
+	-resource:$(srcdir)/$(PLUGIN_MANIFEST)
+
+all: $(PLUGIN_ASSEMBLY)
+
+mpack: $(PLUGIN_ASSEMBLY)
+	mautil p $(PLUGIN_ASSEMBLY)
+
+$(PLUGIN_ASSEMBLY): $(PLUGIN_SOURCES) $(PLUGIN_MANIFEST)
+	$(CSC) -target:library -out:$@ $(CSC_DEFINES) $(PLUGIN_SOURCES) $(REFS) $(PKGS) $(ASSEMBLIES) $(RESOURCES) -r:Mono.Posix
+
+plugindir = $(pkglibdir)/extensions
+
+plugin_DATA =			\
+	$(PLUGIN_ASSEMBLY)
+
+EXTRA_DIST = 			\
+	$(PLUGIN_SOURCES)	\
+	$(PLUGIN_MANIFEST)
+
+CLEANFILES =			\
+	$(PLUGIN_ASSEMBLY)	\
+	$(PLUGIN_ASSEMBLY).mdb	\
+	*.mpack

Modified: trunk/extensions/Effects/Makefile.am
==============================================================================
--- trunk/extensions/Effects/Makefile.am	(original)
+++ trunk/extensions/Effects/Makefile.am	Mon Mar 30 13:14:15 2009
@@ -1,2 +1,4 @@
 SUBDIRS = 			\
-	RotateImage
+	RotateImage	\
+	Brightness	\
+	Contrast

Modified: trunk/extensions/Effects/RotateImage/RotateImage.addin.xml
==============================================================================
--- trunk/extensions/Effects/RotateImage/RotateImage.addin.xml	(original)
+++ trunk/extensions/Effects/RotateImage/RotateImage.addin.xml	Mon Mar 30 13:14:15 2009
@@ -1,6 +1,6 @@
 <Addin namespace="Mistelix"
 	version="0.10"
-	name="Fade"
+	name="Rotate Image"
 	description="Rotate images"
 	author="Jordi Mas"
 	url=""

Modified: trunk/extensions/Effects/RotateImage/RotateImage.cs
==============================================================================
--- trunk/extensions/Effects/RotateImage/RotateImage.cs	(original)
+++ trunk/extensions/Effects/RotateImage/RotateImage.cs	Mon Mar 30 13:14:15 2009
@@ -28,17 +28,22 @@
 
 namespace Mistelix.Effects
 {
-	public class RotateImage: IEffect
+	// TODO: Complete implementation
+	public class RotateImage: Effect
 	{
-		public string DisplayName {
+		public override string DisplayName {
 			get { return ("Rotate image"); }
 		}
 
-		public string Name {
+		public override string Name {
 			get { return ("rotate image"); }
 		}
 
-		public SlideImage ApplyEffect (SlideImage org)
+		public override UIOption [] Options {
+			get { return new UIOption [0]; }
+		}
+
+		public override SlideImage ApplyEffect (SlideImage org)
 		{
 			SlideImage image;
 
@@ -47,7 +52,7 @@
 			image.Pixels = new byte [org.stride * org.height];
 
 			for (int i = 0; i < org.stride * org.height; i++)
-				image.Pixels[i] = (byte) ((double) org.Pixels[i] * 0.5);
+				image.Pixels[i] = org.Pixels[i];
 	
 			return image;
 		}

Modified: trunk/extensions/SlideTransitions/Fade/Fade.cs
==============================================================================
--- trunk/extensions/SlideTransitions/Fade/Fade.cs	(original)
+++ trunk/extensions/SlideTransitions/Fade/Fade.cs	Mon Mar 30 13:14:15 2009
@@ -23,13 +23,14 @@
 
 using System;
 using Mistelix.DataModel;
+using Mono.Unix;
 
 namespace Mistelix.Transitions
 {
 	public class Fade: ITransition
 	{
 		public string DisplayName {
-			get { return ("Fade"); }
+			get { return ( Catalog.GetString ("Fade")); }
 		}
 
 		public string Name {

Modified: trunk/extensions/SlideTransitions/Fade/Makefile.am
==============================================================================
--- trunk/extensions/SlideTransitions/Fade/Makefile.am	(original)
+++ trunk/extensions/SlideTransitions/Fade/Makefile.am	Mon Mar 30 13:14:15 2009
@@ -22,7 +22,7 @@
 	mautil p $(PLUGIN_ASSEMBLY)
 
 $(PLUGIN_ASSEMBLY): $(PLUGIN_SOURCES) $(PLUGIN_MANIFEST)
-	$(CSC) -target:library -out:$@ $(CSC_DEFINES) $(PLUGIN_SOURCES) $(REFS) $(PKGS) $(ASSEMBLIES) $(RESOURCES)
+	$(CSC) -target:library -out:$@ $(CSC_DEFINES) $(PLUGIN_SOURCES) $(REFS) $(PKGS) $(ASSEMBLIES) $(RESOURCES) -r:Mono.Posix
 
 plugindir = $(pkglibdir)/extensions
 

Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in	(original)
+++ trunk/po/POTFILES.in	Mon Mar 30 13:14:15 2009
@@ -1,9 +1,11 @@
 [encoding: UTF-8]
+extensions/Effects/Brightness/Brightness.cs
+extensions/Effects/Contrast/Contrast.cs
+extensions/SlideTransitions/Fade/Fade.cs
 mistelix.desktop.in
 src/core/Dependencies.cs
 src/core/DvdProjectBuilder.cs
 src/core/MistelixLib.cs
-src/core/NoneEffect.cs
 src/core/NoneTransition.cs
 src/core/TheoraProjectBuilder.cs
 src/core/ThumbnailSizeManager.cs
@@ -16,8 +18,8 @@
 src/dialogs/NewProjectDialog.cs
 src/dialogs/ProjectPropertiesDialog.cs
 src/dialogs/ThemeSelectionDialog.cs
-src/mistelix.glade
 src/mistelix.cs
+src/mistelix.glade
 src/mono-addins-strings.xml
 src/widgets/AuthoringPaneView.cs
 src/widgets/BrowseDirectory.cs

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Mon Mar 30 13:14:15 2009
@@ -64,9 +64,8 @@
 	$(srcdir)/core/Dependencies.cs \
 	$(srcdir)/dialogs/CheckDependenciesDialog.cs \
 	$(srcdir)/datamodel/ObservableList.cs \
-	$(srcdir)/datamodel/IEffect.cs \
+	$(srcdir)/datamodel/Effect.cs \
  	$(srcdir)/core/EffectManager.cs \
-	$(srcdir)/core/NoneEffect.cs \
 	$(srcdir)/widgets/DataImageSurface.cs
 
 ASSEMBLIES = \

Modified: trunk/src/core/EffectManager.cs
==============================================================================
--- trunk/src/core/EffectManager.cs	(original)
+++ trunk/src/core/EffectManager.cs	Mon Mar 30 13:14:15 2009
@@ -23,54 +23,57 @@
 
 using System;
 using Mono.Addins;
+using System.Collections.Generic;
+
 using Mistelix.Effects;
 
 namespace Mistelix.Core
 {
 	// Manages all the available effects
+	//
+	// Different that in transitions, where even if there are no transitions at set of images from source
+	// to target should be created for effects we do not need a NoneEffect. Additionally, transitions are
+	// stateless and effects are not.
 	public static class EffectManager
 	{
-		static None none;
-		static EffectManager ()
-		{
-		}
+		static ExtensionNodeList effects;
+		static Dictionary <string, TypeExtensionNode> mapping;
 
-		static public IEffect None {
+		// Get the effect lists. Since they are not stateless we can not reuse the same objects
+		static public ExtensionNodeList List {
 			get {
-				if (none == null)
-					none = new None ();
+				if (effects == null)
+					effects = AddinManager.GetExtensionNodes ("/Mistelix/Effects");
 
-				return none;
+				return effects;
 			}
 		}
 
-		// Get default none transition + the ones provides by pluggins
-		static public IEffect[] List {
-			get {
-				IEffect[] effects;
-				int pos = 0;
-				ExtensionNodeList addins = AddinManager.GetExtensionNodes ("/Mistelix/Effects");
-				effects = new IEffect [addins.Count + 1];
-	
-				effects[pos++] = new None ();
+		static public Effect CreateEffectFromName (string name)
+		{
+			if (mapping == null) {
+				mapping = new Dictionary <string, TypeExtensionNode> ();
 
-				foreach (TypeExtensionNode node in addins) {
-					effects[pos++] =  (IEffect) node.CreateInstance ();
+				foreach (TypeExtensionNode node in List)
+				{
+					Effect effect =  (Effect) node.CreateInstance ();
+					mapping.Add (effect.Name, node);
 				}
-
-				return effects;
 			}
-		}
 
-		static public IEffect FromName (string val) 
-		{
-			foreach (IEffect effect in List)
+			try
 			{
-				if (effect.Name.Equals (val))
-					return effect;
+				TypeExtensionNode node = null;
+				mapping.TryGetValue (name, out node);
+
+				return (Effect) node.CreateInstance ();
 			}
-			Logger.Debug (String.Format ("EffectManager.FromName -> effect {0} not found", val));
-			return None;
+			catch (KeyNotFoundException)
+			{
+			    	Logger.Debug (String.Format ("EffectManager.FromName -> effect {0} not found", name));
+			}
+
+			return null;
 		}
 	}
 }

Modified: trunk/src/core/SlideImage.cs
==============================================================================
--- trunk/src/core/SlideImage.cs	(original)
+++ trunk/src/core/SlideImage.cs	Mon Mar 30 13:14:15 2009
@@ -309,7 +309,6 @@
 
 		public void ProcessEffects ()
 		{
-			IEffect effect;
 			SlideImage processed, previous;
 
 			if (Effects == null)
@@ -317,10 +316,9 @@
 
 			previous = processed = this;
 
-			foreach (string name in Effects)
+			foreach (Effect effect in Effects)
 			{
 				Logger.Debug ("SlideImage.ProcessEffects -> effect {0}", name);
-				effect = EffectManager.FromName (name);
 				previous = processed;
 				processed = effect.ApplyEffect (processed);
 				previous.ReleasePixels ();

Copied: trunk/src/datamodel/Effect.cs (from r7, /trunk/src/datamodel/IEffect.cs)
==============================================================================
--- /trunk/src/datamodel/IEffect.cs	(original)
+++ trunk/src/datamodel/Effect.cs	Mon Mar 30 13:14:15 2009
@@ -22,24 +22,124 @@
 //
 
 using System;
+
 using Mistelix.DataModel;
+using Mistelix.Core;
 
 namespace Mistelix.Effects
 {
 	//
 	// Interface that defines an effect to apply to an image
 	//
-	public interface IEffect
+	// Effects are applied to an image and have
+	//	Â A set of UI controls that set the extension (exposed as menu options)
+	//	Â A string value that is stored for the effect. This can be the rotation angle, brightness level, etc.
+	//
+	public abstract class Effect
 	{
-		SlideImage ApplyEffect (SlideImage slideimage);
+		public class OptionIDEventArgs : EventArgs
+		{
+			int id;
+
+			public OptionIDEventArgs (int id)
+			{
+				this.id = id;
+			}
+			public int ID {
+				get { return id; }
+			}
+		}
+
+		public class UIOption
+		{	
+			string name;
+			int id;
+			EventHandler handler;
+
+			public UIOption (string name, int id, EventHandler handler)
+			{
+				this.name = name;
+				this.id = id;
+				this.handler = handler;
+			}
+
+			public string Name {
+				get { return name; }
+				set { name = value; }
+			}
+	
+			public EventHandler Handler {
+				get { return handler; }
+				set { handler = value; }
+			}
+
+			public int ID {
+				get { return id; }
+			}
+		}
+
+		public struct Storage
+		{	
+			string name;
+			string _value;
+
+			public Storage (string name, string _value)
+			{
+				Name = name;
+				Value = _value;
+			}
+
+			public string Name {
+				get { return name; }
+				set { name = value; }
+			}
+
+			public string Value {
+				get { return _value; }
+				set { _value = value; }
+			}
+		}
 
-		string DisplayName {
+		public delegate void UIOptionEventHandler (object sender, OptionIDEventArgs e);
+		public virtual event UIOptionEventHandler UIOptionInvoked;
+
+		public abstract SlideImage ApplyEffect (SlideImage slideimage);
+
+		public abstract string DisplayName {
 			get;
 		}
 
-		string Name {
+		public abstract string Name {
 			get;
 		}
+
+		public abstract UIOption [] Options {
+			get;
+		}
+
+		public virtual string Value {
+			get {return null; }
+			set {}
+		}
+
+		// This method invokes the EventHandler associated to an option as
+		// it was called by the user
+		public virtual void InvokeOption (int id)
+		{
+			Logger.Debug ("Effect.InvokeOption -> id:{0}", id);
+
+			if (id > Options.Length)
+				throw new ArgumentException (String.Format ("Effect.InvokeOption -> Option with ID {0} does not exist", id));
+
+			Options[id].Handler (this, EventArgs.Empty);
+		}
+		
+		// Fires the UIOptionInvoked notification
+		public virtual void OnUIOptionInvoked (int id)
+		{
+			Logger.Debug ("Effect.OnUIOptionInvoked -> id:{0}", id);
+			if (UIOptionInvoked != null)
+				UIOptionInvoked (this, new OptionIDEventArgs (id));
+		}
 	}
 }
-

Modified: trunk/src/datamodel/SlideShowProjectElement.cs
==============================================================================
--- trunk/src/datamodel/SlideShowProjectElement.cs	(original)
+++ trunk/src/datamodel/SlideShowProjectElement.cs	Mon Mar 30 13:14:15 2009
@@ -28,6 +28,7 @@
 using System.Xml.Serialization;
 using Mono.Unix;
 using Gdk;
+using Mono.Addins;
 
 using Mistelix.Core;
 using Mistelix.Effects;
@@ -81,7 +82,7 @@
 		
 		}
 	
-		[XmlInclude(typeof(SlideImage))]
+		[XmlInclude (typeof (SlideImage))]
 		public abstract class Image : ProjectElement
 		{
 			public string image;
@@ -90,15 +91,51 @@
 			int shown_time; 
 			string transition;
 			TextPosition position;
-			List <string> effects;
+			List <Effect> effects;
 
-			// Text description
-			//[XmlElementAttribute ("effects")]
-			public List <string> Effects {
+			// Used by the application to set / get effects
+			[XmlIgnoreAttribute]
+			public List <Effect> Effects {
 				get { return effects;}
 				set { effects = value;}
 			}
 
+			// Used by serialization  set / get effects
+			//public List <Effect.Storage> EffectList {
+			public  Effect.Storage [] EffectList {
+				get {
+					if (effects == null)
+						return null;
+
+					Effect.Storage[] storage = new Effect.Storage [effects.Count];
+					int pos = 0;
+
+					foreach (Effect effect in effects)
+						storage [pos++] = new Effect.Storage (effect.Name, effect.Value);
+
+					return storage;
+				}
+				set {
+					if (value == null || value.Length == 0)
+						return;
+
+					Effect effect;
+
+					foreach (Effect.Storage stored in value)
+					{
+						effect = EffectManager.CreateEffectFromName (stored.Name);
+	
+						if (effect == null) {
+							Logger.Error ("SlideShowProjectElement.Storage-> No class found to handle effect {0}", stored.Name);
+							continue;
+						}
+
+						effect.Value = stored.Value;
+						AddEffect (effect);						
+					}
+				}
+			}
+
 			// Text description
 			[XmlElementAttribute ("title")]
 			public string Title {
@@ -132,15 +169,35 @@
 				get { return position;}
 				set { position = value;}
 			}
-						
+
+			
 			protected Image () {}
 
-			public void AddEffect (string effect)
+			public Effect FindEffect (string effect_name)
 			{
 				if (effects == null)
-					effects = new List <string> ();
+					return null;
+
+				// This O(N) but we always expect very few elements 
+				foreach (Effect previous in effects) 
+					if (String.Compare (previous.Name, effect_name) == 0)
+						return previous; // Element already present
 				
+				return null;
+			}
+
+			public Effect AddEffect (Effect effect)
+			{
+				if (effects == null)
+					effects = new List <Effect> ();
+
+				// This O(N) but we always expect very few elements 
+				foreach (Effect previous in effects)
+					if (String.Compare (previous.Name, effect.Name) == 0)
+						return previous; // Element already present
+
 				effects.Add (effect);
+				return effect;
 			}
 		}
 	}

Modified: trunk/src/mistelix.addin.xml
==============================================================================
--- trunk/src/mistelix.addin.xml	(original)
+++ trunk/src/mistelix.addin.xml	Mon Mar 30 13:14:15 2009
@@ -9,7 +9,7 @@
 	</ExtensionPoint>
 
 	<ExtensionPoint path="/Mistelix/Effects">
-		<ExtensionNode name="Effects" objectType="Mistelix.Effects.IEffect" />
+		<ExtensionNode name="Effects" objectType="Mistelix.Effects.Effect" />
 	</ExtensionPoint>
 </Addin>
 

Modified: trunk/src/mistelix.cs
==============================================================================
--- trunk/src/mistelix.cs	(original)
+++ trunk/src/mistelix.cs	Mon Mar 30 13:14:15 2009
@@ -96,7 +96,7 @@
 				Logger.Info ("Extension:" + node.CreateInstance ());
 			}
 
-			foreach (TypeExtensionNode node in AddinManager.GetExtensionNodes ("/Mistelix/Effects")) {
+			foreach (TypeExtensionNode node in EffectManager.List) {
 				Logger.Info ("Extension:" + node.CreateInstance ());
 			}
 

Modified: trunk/src/widgets/SlideShowImageView.cs
==============================================================================
--- trunk/src/widgets/SlideShowImageView.cs	(original)
+++ trunk/src/widgets/SlideShowImageView.cs	Mon Mar 30 13:14:15 2009
@@ -124,7 +124,7 @@
 		readonly int thumbnail_width;
 		readonly string notitle;
 		ImageSortType sort_type;
-		IEffect[] effects;
+		Effect[] effects;
 		Cairo.ImageSurface def_image;
 
 		public const int COL_INDEX = 0;
@@ -138,7 +138,6 @@
 
 		public ShowImageSelectionEventHandler 		ChangeEvent;
 		public ShowImageUpdatedElementsEventHandler	UpdatedElements;
-		DateTime start_time = DateTime.Now;
 		List <Gtk.TreeIter> iters_list;
 
 		public SlideShowImageView ()
@@ -490,23 +489,33 @@
 
 			menu = new GtkMenu ();
 
-			nodelist = AddinManager.GetExtensionNodes ("/Mistelix/Effects");
+			nodelist = EffectManager.List;
 			if (nodelist.Count > 0) {
-
-				effects = new IEffect [nodelist.Count];
-				int pos = 0;
-				foreach (TypeExtensionNode node in nodelist) {
-					IEffect effect = (IEffect) node.CreateInstance ();
-
-					MenuItem item = menu.AddItem (effect.DisplayName, OnEffect);
-					item.SetData (EFFECT, new IntPtr (pos));
-					effects [pos] = effect;
-					pos++;
+				if (effects == null) {
+					effects = new Effect [nodelist.Count];
+					int pos = 0;
+					
+					// The Effect class objects created here are just used to handle the effect
+					// user UI and used as stateless objects, just to capture user actions.
+					// The user actions are then transformed at OnEffect to the proper effect 
+					// for every image that are not stateless since they have the Value property
+					foreach (TypeExtensionNode node in nodelist) {
+						Effect effect = (Effect) node.CreateInstance ();
+						effect.UIOptionInvoked += new Effect.UIOptionEventHandler (OnEffect);
+						effects [pos] = effect;
+						pos++;
+					}
+					
 				}
-				
-				menu.AddSeparator ();
+
+				foreach (Effect effect in effects)
+					foreach (Effect.UIOption option in effect.Options)
+						menu.AddItem (option.Name, option.Handler);
 			}
 
+			menu.AddItem (Catalog.GetString ("Remove all effects"), OnRemoveEffects);
+			menu.AddSeparator ();
+
 			menu.AddItem (Catalog.GetString ("Sort by filename (Ascending)"), OnSortAscendingbyName);
 			menu.AddItem (Catalog.GetString ("Sort by filename (Descending)"), OnSortDescendingbyName);
 			menu.AddItem (Catalog.GetString ("Sort by date on disc (Ascending)"), OnSortAscendingbyDate);
@@ -609,11 +618,35 @@
 			}
 		}
 
-		void OnEffect (object obj, EventArgs e)
+		// Create the image indicating that there is no preview available yet
+		void CreateDefaultImage ()
+		{
+			const int min_xpad = 10;
+			Cairo.Context cr;
+			int box_width, box_height;
+	
+			def_image = new Cairo.ImageSurface (Format.Argb32, thumbnail_width, thumbnail_height);
+			cr = new Cairo.Context (def_image);
+
+			using (Pango.Layout layout = Pango.CairoHelper.CreateLayout (cr))
+			{
+				layout.FontDescription = Pango.FontDescription.FromString ("sans 8");
+				layout.SetMarkup (Catalog.GetString ("No preview available"));
+				layout.Alignment = Pango.Alignment.Center;
+				layout.SingleParagraphMode = false;
+				layout.Width = (int) ((thumbnail_width - min_xpad * 2) * Pango.Scale.PangoScale);
+				layout.GetPixelSize (out box_width, out box_height);
+				cr.MoveTo (min_xpad, (thumbnail_height - box_height) / 2);
+	     			Pango.CairoHelper.ShowLayout (cr, layout);
+			}
+			((IDisposable)cr).Dispose ();
+		}
+
+		void OnEffect (object sender, Effect.OptionIDEventArgs e)
 		{
 			TreeIter iter;
 			TreePath[] paths;
-			IEffect effect;
+			Effect effect;
 			SlideImage image, effect_image;
 			DataImageSurface cairo_image, prev_image;
 
@@ -622,17 +655,28 @@
 			if (paths.Length == 0)
 				return;
 
-			int pos = (int) ((MenuItem) obj).GetData (EFFECT);
-			effect = effects [pos];
+			effect = (Effect) sender;
 
-			Logger.Debug ("OnEffect {0} {1}", paths.Length, effect.Name);
+			Logger.Debug ("OnEffect {0} id:{1} (elements selected {2})", effect.Name, e.ID, paths.Length);
 
 			for (int i = 0; i < paths.Length; i++)
 			{
+				Effect image_effect;
+
 				store.GetIter (out iter, paths[i]);
 				prev_image = (DataImageSurface) store.GetValue (iter, COL_CAIROIMAGE);
 				image = (SlideImage) store.GetValue (iter, COL_OBJECT);
-				image.AddEffect (effect.Name);
+
+				image_effect = image.FindEffect (effect.Name);
+
+				if (image_effect == null) {
+					image_effect = EffectManager.CreateEffectFromName (effect.Name);
+					image.AddEffect (image_effect);
+				}
+				
+				// Inform the effect class that this option ID has been invoked
+				// if the object did have a previous status will be taked into account
+				image_effect.InvokeOption (e.ID);
 
 				cairo_image = image.GetThumbnail (thumbnail_width, thumbnail_height);
 				store.SetValue (iter, COL_CAIROIMAGE, cairo_image);
@@ -641,29 +685,33 @@
 					prev_image.Dispose ();
 			}
 		}
-	
-		// Create the image indicating that there is no preview available yet
-		void CreateDefaultImage ()
+
+		void OnRemoveEffects (object obj, EventArgs e)
 		{
-			Cairo.Context cr;
-			int box_width, box_height;
-			const int min_xpad = 10;
-	
-			def_image = new Cairo.ImageSurface (Format.Argb32, thumbnail_width, thumbnail_height);
-			cr = new Cairo.Context (def_image);
+			TreeIter iter;
+			TreePath[] paths;
+			SlideImage image;
+			DataImageSurface cairo_image, prev_image;
 
-			using (Pango.Layout layout = Pango.CairoHelper.CreateLayout (cr))
+			paths = Selection.GetSelectedRows ();
+
+			if (paths.Length == 0)
+				return;
+
+			for (int i = 0; i < paths.Length; i++)
 			{
-				layout.FontDescription = Pango.FontDescription.FromString ("sans 8");
-				layout.SetMarkup (Catalog.GetString ("No preview available"));
-				layout.Alignment = Pango.Alignment.Center;
-				layout.SingleParagraphMode = false;
-				layout.Width = (int) ((thumbnail_width - min_xpad * 2) * Pango.Scale.PangoScale);
-				layout.GetPixelSize (out box_width, out box_height);
-				cr.MoveTo (min_xpad, (thumbnail_height - box_height) / 2);
-	     			Pango.CairoHelper.ShowLayout (cr, layout);
+				store.GetIter (out iter, paths[i]);
+				prev_image = (DataImageSurface) store.GetValue (iter, COL_CAIROIMAGE);
+				image = (SlideImage) store.GetValue (iter, COL_OBJECT);
+				image.Effects = null;
+
+				cairo_image = image.GetThumbnail (thumbnail_width, thumbnail_height);
+				store.SetValue (iter, COL_CAIROIMAGE, cairo_image);
+
+				if (prev_image != null)
+					prev_image.Dispose ();
 			}
-			((IDisposable)cr).Dispose ();
-		}
+		}	
+	
 	}
 }



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