[ease] Element resizing via Handles mostly functional*.
- From: Nate Stedman <natesm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ease] Element resizing via Handles mostly functional*.
- Date: Wed, 19 May 2010 06:40:10 +0000 (UTC)
commit 215aa1f25a4b941b8a78d79ada51027309eb300b
Author: Nate Stedman <natesm gmail com>
Date: Wed May 19 02:38:07 2010 -0400
Element resizing via Handles mostly functional*.
*There are a few issues:
- Top left handle is broken with shift held down.
- Handles only work where they do not overlap their Actor (hence the size)
- "Collapsing" an actor to the right or the bottom causes it to begin moving with the mouse.
src/libease/Actor.vala | 38 ++++++++++++++
src/libease/EditorEmbed.vala | 111 ++++++++++++++++++++++++++++++++++++++++--
src/libease/Handle.vala | 79 +++++++++++++++++++++---------
3 files changed, 200 insertions(+), 28 deletions(-)
---
diff --git a/src/libease/Actor.vala b/src/libease/Actor.vala
index 59ed449..769a9f3 100644
--- a/src/libease/Actor.vala
+++ b/src/libease/Actor.vala
@@ -69,5 +69,43 @@ public class Ease.Actor : Clutter.Group
element.x = x;
element.y = y;
}
+
+ /**
+ * Resize this Actor and update its { link Element}
+ *
+ * Used in the editor and tied to Clutter MotionEvents on handles.
+ *
+ * @param w_change The amount of width change.
+ * @param h_change The amount of height change.
+ * @param proportional If the resize should be proportional only
+ */
+ public void resize(float w_change, float h_change, bool proportional)
+ {
+ if (proportional)
+ {
+ if (w_change / h_change > width / height)
+ {
+ w_change = h_change * (width / height);
+ }
+ else if (w_change / h_change < width / height)
+ {
+ h_change = w_change * (height / width);
+ }
+ }
+
+ if (width + w_change > 1)
+ {
+ width += w_change;
+ contents.width += w_change;
+ }
+ if (height + h_change > 1)
+ {
+ height += h_change;
+ contents.height += h_change;
+ }
+
+ element.width = width;
+ element.height = height;
+ }
}
diff --git a/src/libease/EditorEmbed.vala b/src/libease/EditorEmbed.vala
index 977397b..406d5b5 100644
--- a/src/libease/EditorEmbed.vala
+++ b/src/libease/EditorEmbed.vala
@@ -157,10 +157,18 @@ public class Ease.EditorEmbed : ScrollableEmbed
// remove the selection rectangle
if (selection_rectangle != null)
{
- contents.remove_actor(selection_rectangle);
+ if (selection_rectangle.get_parent() == contents)
+ {
+ contents.remove_actor(selection_rectangle);
+ }
foreach (var h in handles)
{
- contents.remove_actor(h);
+ if (h.get_parent() == contents)
+ {
+ contents.remove_actor(h);
+ }
+ h.button_press_event.disconnect(handle_clicked);
+ h.button_release_event.disconnect(handle_released);
}
}
@@ -255,14 +263,23 @@ public class Ease.EditorEmbed : ScrollableEmbed
return true;
}
- // remove the selection rectangle
+ // remove the selection rectangle and handles
if (selection_rectangle != null)
{
foreach (var h in handles)
{
- contents.remove_actor(h);
+ h.button_press_event.disconnect(handle_clicked);
+ h.button_release_event.disconnect(handle_released);
+
+ if (h.get_parent() == contents)
+ {
+ contents.remove_actor(h);
+ }
+ }
+ if (selection_rectangle.get_parent() == contents)
+ {
+ contents.remove_actor(selection_rectangle);
}
- contents.remove_actor(selection_rectangle);
}
selected = (Actor)sender;
@@ -281,6 +298,9 @@ public class Ease.EditorEmbed : ScrollableEmbed
handles[i] = new Handle((HandlePosition)i);
handles[i].reposition(selection_rectangle);
contents.add_actor(handles[i]);
+
+ handles[i].button_press_event.connect(handle_clicked);
+ handles[i].button_release_event.connect(handle_released);
}
return true;
@@ -343,5 +363,86 @@ public class Ease.EditorEmbed : ScrollableEmbed
}
return true;
}
+
+ /**
+ * Signal handler for clicking on a { link Handle}.
+ *
+ * This handler is attached to the button_press_event of all
+ * { link Handle}s.
+ *
+ * @param sender The { link Handle} that was clicked
+ * @param event The corresponding Clutter.Event
+ */
+ public bool handle_clicked(Clutter.Actor sender, Clutter.Event event)
+ {
+ is_dragging = true;
+ is_drag_ready = false;
+ sender.motion_event.connect(handle_motion);
+ Clutter.grab_pointer(sender);
+ return true;
+ }
+
+ /**
+ * Signal handler for releasing an { link Handle}.
+ *
+ * This handler is attached to the button_release_event of all
+ * { link Handle}s.
+ *
+ * When the { link Handle} is being dragged, this ends the drag action.
+ *
+ * @param sender The { link Handle} that was released
+ * @param event The corresponding Clutter.Event
+ */
+ public bool handle_released(Clutter.Actor sender, Clutter.Event event)
+ {
+ if (is_dragging)
+ {
+ is_dragging = false;
+ sender.motion_event.disconnect(handle_motion);
+ }
+
+ Clutter.ungrab_pointer();
+ return true;
+ }
+
+ /**
+ * Signal handler for dragging an { link Handle}.
+ *
+ * This handler is attached to the motion_event of all
+ * { link Handle}s.
+ *
+ * It will only have an effect if a drag is active.
+ *
+ * @param sender The { link Handle} that was dragged
+ * @param event The corresponding Clutter.Event
+ */
+ public bool handle_motion(Clutter.Actor sender, Clutter.Event event)
+ {
+ Handle handle = (Handle)sender;
+
+ if (!is_drag_ready)
+ {
+ is_drag_ready = true;
+ mouse_x = event.motion.x;
+ mouse_y = event.motion.y;
+ return true;
+ }
+
+ float factor = 1 / zoom;
+ var motion = event.motion;
+ var p = (motion.modifier_state & Clutter.ModifierType.SHIFT_MASK) != 0;
+
+ handle.drag(factor * (motion.x - mouse_x),
+ factor * (motion.y - mouse_y),
+ selected,
+ p);
+
+ mouse_x = motion.x;
+ mouse_y = motion.y;
+
+ position_selection();
+
+ return true;
+ }
}
diff --git a/src/libease/Handle.vala b/src/libease/Handle.vala
index daa3314..cbd21cf 100644
--- a/src/libease/Handle.vala
+++ b/src/libease/Handle.vala
@@ -15,45 +15,78 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-public class Ease.Handle : Clutter.Group
-{
- // the graphical element of the rectangle
- private Clutter.Rectangle rectangle;
-
- // the position of this rectangle
+/**
+ * Interface element for manipulating the size of { link Actor}s.
+ */
+public class Ease.Handle : Clutter.Rectangle
+{
+ // the position of this handle
private HandlePosition position;
-
- // the offset of the pointer, so things don't jump
- private int pointer_offset_x;
- private int pointer_offset_y;
// constants
- public static const float SIZE = 10;
+ public const float SIZE = 50;
public Handle(HandlePosition pos)
{
// set the rectangle's position
position = pos;
- // make the actual rectangle
- rectangle = new Clutter.Rectangle();
-
// set the rectangle's color
- rectangle.color = {0, 0, 0, 255};
+ color = {0, 0, 0, 255};
// set the rectangle's border
- rectangle.border_width = 2;
- rectangle.border_color = {255, 255, 255, 255};
+ border_width = 2;
+ border_color = {255, 255, 255, 255};
// set the rectangle's size
- rectangle.width = SIZE;
- rectangle.height = SIZE;
+ width = SIZE;
+ height = SIZE;
set_anchor_point(SIZE / 2, SIZE / 2);
-
- // add the rectangle
- add_actor(rectangle);
- reactive = true;
+ set_reactive(true);
+ }
+
+ public void drag(float change_x, float change_y, Actor target, bool prop)
+ {
+ switch (position)
+ {
+ case HandlePosition.TOP_LEFT:
+ target.translate(change_x, change_y);
+ target.resize(-change_x, -change_y, prop);
+ break;
+
+ case HandlePosition.TOP_RIGHT:
+ target.translate(0, change_y);
+ target.resize(change_x, -change_y, prop);
+ break;
+
+ case HandlePosition.TOP:
+ target.translate(0, change_y);
+ target.resize(0, -change_y, false);
+ break;
+
+ case HandlePosition.BOTTOM:
+ target.resize(0, change_y, false);
+ break;
+
+ case HandlePosition.LEFT:
+ target.translate(change_x, 0);
+ target.resize(-change_x, 0, false);
+ break;
+
+ case HandlePosition.RIGHT:
+ target.resize(change_x, 0, false);
+ break;
+
+ case HandlePosition.BOTTOM_LEFT:
+ target.translate(change_x, 0);
+ target.resize(-change_x, change_y, prop);
+ break;
+
+ case HandlePosition.BOTTOM_RIGHT:
+ target.resize(change_x, change_y, prop);
+ break;
+ }
}
public void reposition(Clutter.Actor selection)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]