[Sugar-devel] [PATCH v2 Paint Activity] Fixed aspect ratio mode for Shape tools (OLPC#3705)

Ayush Goyal ayush at seeta.in
Thu Oct 28 16:17:52 EDT 2010


Added fixed aspect ratio mode for line,ellipse and rectangle tool using Shift
key as mask or using a keep aspect ratio checkbox from palette.This allows
drawing of straight lines & 45 degree lines from line tool,circle from
ellipse tool and square from rectangle tool

Signed-off-by: Ayush Goyal <ayush at seeta.in>
---
 Area.py    |   40 +++++++++++++++++++++++++++++++++++++++-
 toolbox.py |   11 +++++++++++
 2 files changed, 50 insertions(+), 1 deletions(-)
 v1->v2:Added checkbox for keep aspect in shape menu palette

diff --git a/Area.py b/Area.py
index ba06758..db84e65 100644
--- a/Area.py
+++ b/Area.py
@@ -173,6 +173,10 @@ class Area(gtk.DrawingArea):
         self.last = []
         self.rainbow_counter = 0
         self.keep_aspect_ratio = False
+        self.keep_ratio = {
+            'line': False,
+            'rectangle': False,
+            'ellipse': False}
 
         self.font = pango.FontDescription('Sans 9')
         self._set_selection_bounds(0, 0, 0, 0)
@@ -411,6 +415,13 @@ class Area(gtk.DrawingArea):
         self.x_cursor, self.y_cursor = int(x), int(y)
 
         coords = int(x), int(y)
+        if self.tool['name'] in ['rectangle', 'ellipse', 'line']:
+            if (state & gtk.gdk.SHIFT_MASK) or \
+                self.keep_ratio[self.tool['name']]:
+                if self.tool['name'] in ['rectangle', 'ellipse']:
+                    coords = self._keep_selection_ratio(coords)
+                elif self.tool['name'] == 'line':
+                    coords = self._keep_line_ratio(coords)
 
         if state & gtk.gdk.BUTTON1_MASK and self.pixmap != None:
             if self.tool['name'] == 'pencil':
@@ -530,11 +541,19 @@ class Area(gtk.DrawingArea):
             @param  event -- GdkEvent
         """
         coords = int(event.x), int(event.y)
+        if self.tool['name'] in ['rectangle', 'ellipse', 'line']:
+            if (event.state & gtk.gdk.SHIFT_MASK) or \
+                self.keep_ratio[self.tool['name']]:
+                if self.tool['name'] in ['rectangle', 'ellipse']:
+                    coords = self._keep_selection_ratio(coords)
+                if self.tool['name'] == 'line':
+                    coords = self._keep_line_ratio(coords)
+
         width, height = self.window.get_size()
         if self.desenha or self.sel_get_out:
             if self.tool['name'] == 'line':
                 self.pixmap.draw_line(self.gc_line, self.oldx, self.oldy,
-                    int(event.x), int(event.y))
+                    coords[0], coords[1])
                 widget.queue_draw()
                 self.enableUndo(widget)
 
@@ -1411,3 +1430,22 @@ class Area(gtk.DrawingArea):
 
         return (self.oldx + sign(dx) * size,
                 self.oldy + sign(dy) * size)
+
+    def _keep_line_ratio(self, coords):
+
+        def sign(x):
+            return x and x / abs(x) or 0
+
+        dx = int(coords[0]) - self.oldx
+        dy = int(coords[1]) - self.oldy
+        size = max(abs(dx), abs(dy))
+
+        if abs(dx) > 0.5 * size and abs(dy) > 0.5 * size:
+            return (self.oldx + sign(dx) * size,
+                   self.oldy + sign(dy) * size)
+        elif abs(dx) < 0.5 * size and abs(dy) > 0.5 * size:
+            return (self.oldx,
+                   self.oldy + sign(dy) * size)
+        elif abs(dx) > 0.5 * size and abs(dy) < 0.5 * size:
+            return (self.oldx + sign(dx) * size,
+                   self.oldy)
diff --git a/toolbox.py b/toolbox.py
index 3c8ab92..e8569c8 100644
--- a/toolbox.py
+++ b/toolbox.py
@@ -855,6 +855,10 @@ class ShapesToolbar(gtk.Toolbar):
         tool['fill'] = checkbutton.get_active()
         self.set_tool(tool=tool)
 
+    def _on_keep_aspect_checkbutton_toggled(self, checkbutton, tool):
+        self._activity.area.keep_ratio[tool['name']] = checkbutton.get_active()
+        self.set_tool(tool=tool)
+
     def _configure_palette_shape_ellipse(self):
         logging.debug('Creating palette to shape ellipse')
         self._create_simple_palette(self._shape_ellipse, self._SHAPE_ELLIPSE)
@@ -960,6 +964,13 @@ class ShapesToolbar(gtk.Toolbar):
         palette.content_box = gtk.VBox()
         palette.set_content(palette.content_box)
 
+        if tool['name'] in ['rectangle', 'ellipse', 'line']:
+            keep_aspect_checkbutton = gtk.CheckButton(_('Keep Aspect'))
+            ratio = self._activity.area.keep_ratio[tool['name']]
+            keep_aspect_checkbutton.set_active(ratio)
+            keep_aspect_checkbutton.connect('toggled',
+                self._on_keep_aspect_checkbutton_toggled, tool)
+            palette.content_box.pack_start(keep_aspect_checkbutton)
         # Fill option
         if not line_size_only:
             fill_checkbutton = gtk.CheckButton(_('Fill'))
-- 
1.7.1



More information about the Sugar-devel mailing list