From a4c7f039f0b2785bcef54b16fb0afb26064c2b5a Mon Sep 17 00:00:00 2001 From: Ayush Goyal Date: Thu, 28 Oct 2010 20:07:37 +0000 Subject: Fixed aspect ratio mode for Shape tools (OLPC#3705) 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 --- diff --git a/Area.py b/Area.py index ba06758..13417fd 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_shape_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_shape_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_shape_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..ebed30f 100644 --- a/toolbox.py +++ b/toolbox.py @@ -855,6 +855,11 @@ 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_shape_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) @@ -991,6 +996,14 @@ class ShapesToolbar(gtk.Toolbar): size_spinbutton.connect('value-changed', self._on_line_size_value_changed, tool) + if tool['name'] in ['rectangle', 'ellipse', 'line']: + keep_aspect_checkbutton = gtk.CheckButton(_('Keep Aspect')) + ratio = self._activity.area.keep_shape_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) + palette.content_box.show_all() def _configure_palette_shape_line(self): -- cgit v0.9.1