[ease] [editor] Fixed proportional drag, removed from center drag



commit 009e59c765bb8989925f097dbcb0ef558a1c3c56
Author: Nate Stedman <natesm gmail com>
Date:   Sun Sep 19 15:55:45 2010 -0400

    [editor] Fixed proportional drag, removed from center drag
    
    Related to bug 627822
    
    - Shift-resize works properly for all directions.
    - When the user presses/releases shift, the entire transformation
      will readjust itself.
    - However, ctrl-drag has been temporarily removed (not until after 0.4)

 ease-core/ease-actor.vala   |    8 +-
 ease-core/ease-element.vala |   32 +++++++
 ease/ease-editor-embed.vala |   59 +++++++++++-
 ease/ease-handle.vala       |  212 ++++++++++++++++++++++++++++--------------
 4 files changed, 229 insertions(+), 82 deletions(-)
---
diff --git a/ease-core/ease-actor.vala b/ease-core/ease-actor.vala
index cfc4f79..7e017bb 100644
--- a/ease-core/ease-actor.vala
+++ b/ease-core/ease-actor.vala
@@ -95,10 +95,12 @@ public abstract class Ease.Actor : Clutter.Group
 		e.notify["width"].connect((o, p) => {
 			width = element.width;
 			contents.width = element.width;
+			if (editor_rect != null) editor_rect.width = width;
 		});
 		e.notify["height"].connect((o, p) => {
 			height = element.height;
 			contents.height = element.height;
+			if (editor_rect != null) editor_rect.height = height;
 		});
 	}
 	
@@ -192,12 +194,6 @@ public abstract class Ease.Actor : Clutter.Group
 		
 		element.width = width;
 		element.height = height;
-		
-		if (editor_rect != null)
-		{
-			editor_rect.width = width;
-			editor_rect.height = height;
-		}
 	}
 	
 	/**
diff --git a/ease-core/ease-element.vala b/ease-core/ease-element.vala
index 05ca7f3..9777a50 100644
--- a/ease-core/ease-element.vala
+++ b/ease-core/ease-element.vala
@@ -33,6 +33,16 @@ public abstract class Ease.Element : GLib.Object, UndoSource
 	 * The default height of { link Theme} master slides.
 	 */
 	private const float THEME_HEIGHT = 600;
+	
+	/**
+	 * The default height minimum Element width.
+	 */
+	private const float DEFAULT_MIN_WIDTH = 20;
+	
+	/**
+	 * The default height minimum Element height.
+	 */
+	private const float DEFAULT_MIN_HEIGHT = 20;
 
 	/**
 	 * The { link Slide} that this Element is a part of.
@@ -255,6 +265,28 @@ public abstract class Ease.Element : GLib.Object, UndoSource
 	}
 	
 	/**
+	 * This method represents the minimum width of this Element type. The user
+	 * will be unable to resize the Element's width any smaller than this.
+	 * If desired, subclasses can override this method to provide a custom
+	 * minimum size.
+	 */
+	public virtual float get_minimum_width()
+	{
+		return DEFAULT_MIN_WIDTH;
+	}
+	
+	/**
+	 * This method represents the minimum height of this Element type. The user
+	 * will be unable to resize the Element's height any smaller than this.
+	 * If desired, subclasses can override this method to provide a custom
+	 * minimum size.
+	 */
+	public virtual float get_minimum_height()
+	{
+		return DEFAULT_MIN_HEIGHT;
+	}
+	
+	/**
 	 * The Element's identifier on its master { link Slide}.
 	 *
 	 * This property allows Ease to simply change the theme of a { link Slide}.
diff --git a/ease/ease-editor-embed.vala b/ease/ease-editor-embed.vala
index 2beace2..c0f5409 100644
--- a/ease/ease-editor-embed.vala
+++ b/ease/ease-editor-embed.vala
@@ -121,6 +121,26 @@ internal class Ease.EditorEmbed : ScrollableEmbed, UndoSource
 	private float orig_h;
 	
 	/**
+	 * The sum x change of the current drag action.
+	 */
+	private float drag_total_x;
+	
+	/**
+	 * The sum y change of the current drag action.
+	 */
+	private float drag_total_y;
+	
+	/**
+	 * If the proportional drag key was pressed in the previous drag.
+	 */
+	private bool proportional_drag;
+	
+	/**
+	 * If the center drag key was pressed in the previous drag.
+	 */
+	private bool from_center_drag;
+	
+	/**
 	 * If the embed is currently receiving key events.
 	 */
 	private bool keys_connected = false;
@@ -658,7 +678,7 @@ internal class Ease.EditorEmbed : ScrollableEmbed, UndoSource
 	 */
 	private bool handle_motion(Clutter.Actor sender, Clutter.MotionEvent event)
 	{
-		Handle handle = (Handle)sender;
+		var handle = (Handle)sender;
 		
 		if (!is_drag_initialized)
 		{
@@ -670,26 +690,55 @@ internal class Ease.EditorEmbed : ScrollableEmbed, UndoSource
 			orig_y = selected.y;
 			orig_w = selected.width;
 			orig_h = selected.height;
+			drag_total_x = 0;
+			drag_total_y = 0;
+			
+			proportional_drag =
+				(event.modifier_state & Clutter.ModifierType.SHIFT_MASK) != 0;
+			from_center_drag =
+				(event.modifier_state & Clutter.ModifierType.CONTROL_MASK) != 0;
 			
 			return true;
 		}
 		
 		float factor = 1 / zoom;
-		var p = (event.modifier_state & Clutter.ModifierType.SHIFT_MASK) != 0;
+		var proportional =
+			(event.modifier_state & Clutter.ModifierType.SHIFT_MASK) != 0;
+		var from_center =
+			(event.modifier_state & Clutter.ModifierType.CONTROL_MASK) != 0;
 		float change_x = event.x - mouse_x;
 		float change_y = event.y - mouse_y;
+		drag_total_x += change_x;
+		drag_total_y += change_y;
+		
+		// if the 
+		
+		// if proportional drag is changed, reset and apply the full drag
+		if (proportional != proportional_drag)
+		{
+			selected.element.x = orig_x;
+			selected.element.y = orig_y;
+			selected.element.width = orig_w;
+			selected.element.height = orig_h;
+			
+			handle.drag(drag_total_x, drag_total_y,
+			            selected.element, proportional, from_center);
+			proportional_drag = proportional;
+			return true;
+		}
 		
 		// if control is held, resize from the center
-		if ((event.modifier_state & Clutter.ModifierType.CONTROL_MASK) != 0)
+		/*if ((event.modifier_state & Clutter.ModifierType.CONTROL_MASK) != 0)
 		{
 			handle.drag_from_center(factor * change_x, factor * change_y,
 			                        selected, p);
 		}
 		
 		// otherwise, drag normally
-		else
+		else*/
 		{
-			handle.drag(factor * change_x, factor * change_y, selected, p);
+			handle.drag(factor * change_x, factor * change_y,
+			            selected.element, proportional, from_center);
 		}
 		
 		mouse_x = event.x;
diff --git a/ease/ease-handle.vala b/ease/ease-handle.vala
index c45fbc1..700e659 100644
--- a/ease/ease-handle.vala
+++ b/ease/ease-handle.vala
@@ -23,7 +23,7 @@ internal class Ease.Handle : Clutter.CairoTexture
 	/**
 	 * The position of this handle relative to the selection rectangle.
 	 */
-	private HandlePosition position;
+	internal HandlePosition position;
 	
 	/**
 	 * If the handle is being dragged and should alter its appearance.
@@ -66,106 +66,176 @@ internal class Ease.Handle : Clutter.CairoTexture
 	 *
 	 * @param change_x The x drag distance.
 	 * @param change_y The y drag distance.
-	 * @param target The actor to update.
-	 * @param prop If any scaling should be proportional, if possible.
+	 * @param target The Element to update.
+	 * @param proportional If any scaling should be proportional, if possible.
+	 * @param from_center If the resize should operate from the center of the
+	 * target element.
 	 */
-	internal void drag(float change_x, float change_y, Actor target, bool prop)
+	internal void drag(float change_x, float change_y, Element target,
+	                   bool proportional, bool from_center)
 	{
+		float translate_x = 0, translate_y = 0, resize_x = 0, resize_y = 0;
+		
 		switch (position)
 		{
 			case HandlePosition.TOP_LEFT:
-				target.translate(change_x, change_y);
-				target.resize(-change_x, -change_y, prop);
+				if (proportional)
+				{
+					if (change_x / change_y > target.width / target.height)
+					{
+						translate_x = change_y * (target.width / target.height);
+						translate_y = change_y;
+					}
+					else
+					{
+						translate_y = change_x * (target.height / target.width);
+						translate_x = change_x;
+					}
+					resize_x = -translate_x;
+					resize_y = -translate_y;
+					break;
+				}
+				
+				translate_x = change_x;
+				translate_y = change_y;
+				resize_x = -change_x;
+				resize_y = -change_y;
 				break;
 				
 			case HandlePosition.TOP_RIGHT:
-				target.translate(0, change_y);
-				target.resize(change_x, -change_y, prop);
+				if (proportional)
+				{
+					if (change_x / change_y > target.width / target.height)
+					{
+						resize_x = change_y * (target.width / target.height);
+						resize_y = change_y;
+					}
+					else
+					{
+						resize_y = change_x * (target.height / target.width);
+						resize_x = change_x;
+					}
+					translate_y = -resize_y;
+					break;
+				}
+			
+				translate_y = change_y;
+				resize_x = change_x;
+				resize_y = -change_y;
 				break;
 				
 			case HandlePosition.TOP:
-				target.translate(0, change_y);
-				target.resize(0, -change_y, false);
+				if (proportional)
+				{
+					resize_x = -change_y * (target.width / target.height);
+					translate_x = -resize_x / 2;
+				}
+			
+				translate_y = change_y;
+				resize_y = -change_y;
 				break;
 				
 			case HandlePosition.BOTTOM:
-				target.resize(0, change_y, false);
+				if (proportional)
+				{
+					resize_x = change_y * (target.width / target.height);
+					translate_x = -resize_x / 2;
+				}
+			
+				resize_y = change_y;
 				break;
 				
 			case HandlePosition.LEFT:
-				target.translate(change_x, 0);
-				target.resize(-change_x, 0, false);
+				if (proportional)
+				{
+					resize_y = -change_x * (target.width / target.height);
+					translate_y = -resize_y / 2;
+				}
+			
+				translate_x = change_x;
+				resize_x = -change_x;
 				break;
 				
 			case HandlePosition.RIGHT:
-				target.resize(change_x, 0, false);
+				if (proportional)
+				{
+					resize_y = change_x * (target.width / target.height);
+					translate_y = -resize_y / 2;
+				}
+				
+				resize_x = change_x;
 				break;
 				
 			case HandlePosition.BOTTOM_LEFT:
-				target.translate(change_x, 0);
-				target.resize(-change_x, change_y, prop);
+				if (proportional)
+				{
+					if (change_x / change_y > target.width / target.height)
+					{
+						resize_x = -change_y * (target.width / target.height);
+						resize_y = -change_y;
+					}
+					else
+					{
+						resize_y = -change_x * (target.height / target.width);
+						resize_x = -change_x;
+					}
+					
+					translate_x = -resize_x;
+					break;
+				}
+			
+				translate_x = change_x;
+				resize_x = -change_x;
+				resize_y = change_y;
 				break;
 				
 			case HandlePosition.BOTTOM_RIGHT:
-				target.resize(change_x, change_y, prop);
+				if (proportional)
+				{
+					if (change_x / change_y > target.width / target.height)
+					{
+						resize_x = change_y * (target.width / target.height);
+						resize_y = change_y;
+					}
+					else
+					{
+						resize_y = change_x * (target.height / target.width);
+						resize_x = change_x;
+					}
+					break;
+				}
+			
+				resize_x = change_x;
+				resize_y = change_y;
 				break;
 		}
-	}
-	
-	/**
-	 * Performs a drag of the handle, scaling from the center. Updates the
-	 * selected { link Actor}'s size and position.
-	 *
-	 * @param change_x The x drag distance.
-	 * @param change_y The y drag distance.
-	 * @param target The actor to update.
-	 * @param prop If any scaling should be proportional, if possible.
-	 */
-	internal void drag_from_center(float change_x, float change_y, Actor target,
-	                             bool prop)
-	{
-		switch (position)
+		
+		if (target.width + resize_x - translate_x <= target.get_minimum_width())
 		{
-			case HandlePosition.TOP_LEFT:
-				target.translate(change_x, change_y);
-				target.resize(-change_x * 2, -change_y * 2, false);
-				break;
-				
-			case HandlePosition.TOP_RIGHT:
-				target.translate(-change_x, change_y);
-				target.resize(change_x * 2, -change_y * 2, prop);
-				break;
-				
-			case HandlePosition.TOP:
-				target.translate(0, change_y);
-				target.resize(0, -change_y * 2, false);
-				break;
-				
-			case HandlePosition.BOTTOM:
-				target.translate(0, -change_y);
-				target.resize(0, change_y * 2, false);
-				break;
-				
-			case HandlePosition.LEFT:
-				target.translate(change_x, 0);
-				target.resize(-change_x * 2, 0, false);
-				break;
-				
-			case HandlePosition.RIGHT:
-				target.translate(-change_x, 0);
-				target.resize(change_x * 2, 0, false);
-				break;
-				
-			case HandlePosition.BOTTOM_LEFT:
-				target.translate(change_x, -change_y);
-				target.resize(-change_x * 2, change_y * 2, prop);
-				break;
-				
-			case HandlePosition.BOTTOM_RIGHT:
-				target.translate(-change_x, -change_y);
-				target.resize(change_x * 2, change_y * 2, prop);
-				break;
+			translate_x = 0;
+			resize_x = 0;
+			if (proportional)
+			{
+				translate_y = 0;
+				resize_y = 0;
+			}
+		}
+		if (target.height + resize_y - translate_y <=
+		    target.get_minimum_height())
+		{
+			translate_y = 0;
+			resize_y = 0;
+			if (proportional)
+			{
+				translate_x = 0;
+				resize_x = 0;
+			}
 		}
+		
+		target.x += translate_x;
+		target.y += translate_y;
+		target.width += resize_x;
+		target.height += resize_y;
 	}
 	
 	/**



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