# Copyright 2008 by Peter Moxhay and Wade Brainerd. # This file is part of Math. # # Math is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Math is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Math. If not, see . from objectarea import Object from draggableobject import DraggableObject from vector import Vector import gtk, math, rsvg MOON_SVG = rsvg.Handle('moon.svg') OVAL_SVG = rsvg.Handle('oval.svg') from movableobject import MovableObject # Class containing various standard colors. Each color is a 3 element tuple. class Color: BLUE = (0.25, 0.25, 0.75) GREEN = (0.25, 0.75, 0.25) RED = (0.75, 0.25, 0.25) class GroupObject(MovableObject): """Draggable group of discrete shapes.""" def __init__(self, pos, size, color1, shape1_name, color2, shape2_name, shape1_in_pair, container): MovableObject.__init__(self) self.pos = pos self.size = size self.selectable = True self.rotatable = False self.color1 = color1 self.color2 = color2 self.shape1 = shape1_name self.shape2 = shape2_name self.shape1_in_pair = shape1_in_pair self.container = container self.amount_scale = 1.0 def draw(self, cr): cr.scale(self.amount_scale, self.amount_scale) self.draw_moon(cr, Vector (-20, 100), Vector (1.1, 1.2)) if self.shape1_in_pair: self.draw_oval(cr, Vector(15, -1), Vector(1.82, 1.4)) if self.shape1 == 'circle': self.draw_circle(cr, Vector(50 + 25, 50), self.color1) elif self.shape1 == 'square': self.draw_square(cr, Vector(18 + 25, 18), self.color1) else: self.draw_triangle(cr, Vector(9 + 25, 83), self.color1) if self.shape2 == 'circle': self.draw_circle(cr, Vector(50 + 25, 150), self.color2) elif self.shape2 == 'square': self.draw_square(cr, Vector(18 + 25, 118), self.color2) else: self.draw_triangle(cr, Vector(9 + 25, 183), self.color2) if self.shape1_in_pair: if self.shape1 == 'circle': self.draw_circle(cr, Vector(50 + 25 + 100, 50), self.color1) elif self.shape1 == 'square': self.draw_square(cr, Vector(18 + 25 + 100, 18), self.color1) else: self.draw_triangle(cr, Vector(9 + 25 + 100, 83), self.color1) def get_bounds(self): if self.shape1_in_pair: return (self.pos + Vector(-30, 0)).scaled(self.amount_scale), (self.pos + Vector(200, 200)).scaled(self.amount_scale) else: return (self.pos + Vector(-30, 0)).scaled(self.amount_scale), (self.pos + Vector(100, 200)).scaled(self.amount_scale) #def get_bounds(self): #if self.shape1_in_pair: # return self.pos + Vector(-30, 0), self.pos + Vector(200, 200) #else: # return self.pos + Vector(-30, 0), self.pos + Vector(100, 200) def draw_circle(self, cr, pos, color): cr.save() # Draw the fill. #cr.set_source_rgb(color[0], color[1], color[2]) if self.selected: cr.set_source_rgb(color[0]*1.6, color[1]*1.6, color[2]*1.6) else: cr.set_source_rgb(color[0], color[1], color[2]) cr.arc(self.pos.x + pos.x, self.pos.y + pos.y, 35, 0.0, 2.0 * math.pi) cr.fill() # Draw the outline. #cr.set_source_rgb(color[0]*0.75, color[1]*0.75, color[2]*0.75) if self.selected: cr.set_dash((10, 10), 0) cr.set_source_rgb(color[0]*0.75, color[1]*0.75, color[2]*0.75) cr.set_line_width(4.0) cr.arc(self.pos.x + pos.x, self.pos.y + pos.y, 35, 0.0, 2.0 * math.pi) cr.stroke() cr.restore() def draw_moon(self, cr, pos, scale): cr.save() cr.translate(self.pos.x - 20, self.pos.y + 62) cr.scale(0.7, 0.7) MOON_SVG.render_cairo(cr) cr.restore() def draw_oval(self, cr, pos, scale): cr.save() cr.translate(self.pos.x + 16, self.pos.y) cr.scale(1.42, 1.24) OVAL_SVG.render_cairo(cr) cr.restore() def draw_square(self, cr, pos, color): square_side = 65 SQUARE = [ Vector(0, 0), Vector(square_side, 0), Vector(square_side, square_side), Vector(0, square_side) ] cr.save() # Draw the fill. cr.move_to(self.pos.x + pos.x + SQUARE[0].x, self.pos.y + pos.y + SQUARE[0].y) cr.line_to(self.pos.x + pos.x + SQUARE[1].x, self.pos.y + pos.y + SQUARE[1].y) cr.line_to(self.pos.x + pos.x + SQUARE[2].x, self.pos.y + pos.y + SQUARE[2].y) cr.line_to(self.pos.x + pos.x + SQUARE[3].x, self.pos.y + pos.y + SQUARE[3].y) cr.close_path() # Draw the fill. #cr.set_source_rgb(color[0], color[1], color[2]) if self.selected: cr.set_source_rgb(color[0]*1.6, color[1]*1.6, color[2]*1.6) else: cr.set_source_rgb(color[0], color[1], color[2]) cr.fill() # Draw the outline. #cr.set_source_rgb(color[0]*0.75, color[1]*0.75, color[2]*0.75) if self.selected: cr.set_dash((10, 10), 0) cr.set_source_rgb(color[0]*0.75, color[1]*0.75, color[2]*0.75) cr.set_line_width(4.0) cr.move_to(self.pos.x + pos.x + SQUARE[0].x, self.pos.y + pos.y + SQUARE[0].y) cr.line_to(self.pos.x + pos.x + SQUARE[1].x, self.pos.y + pos.y + SQUARE[1].y) cr.line_to(self.pos.x + pos.x + SQUARE[2].x, self.pos.y + pos.y + SQUARE[2].y) cr.line_to(self.pos.x + pos.x + SQUARE[3].x, self.pos.y + pos.y + SQUARE[3].y) cr.close_path() cr.stroke() cr.restore() def draw_triangle(self, cr, pos, color): triangle_side = 80 TRIANGLE = [ Vector(0, 0), Vector(triangle_side/2, -triangle_side * math.sqrt(3)/2), Vector(triangle_side, 0) ] cr.save() # Draw the fill. cr.move_to(self.pos.x + pos.x + TRIANGLE[0].x, self.pos.y + pos.y + TRIANGLE[0].y) cr.line_to(self.pos.x + pos.x + TRIANGLE[1].x, self.pos.y + pos.y + TRIANGLE[1].y) cr.line_to(self.pos.x + pos.x + TRIANGLE[2].x, self.pos.y + pos.y + TRIANGLE[2].y) cr.close_path() # Draw the fill. #cr.set_source_rgb(color[0], color[1], color[2]) if self.selected: cr.set_source_rgb(color[0]*1.6, color[1]*1.6, color[2]*1.6) else: cr.set_source_rgb(color[0], color[1], color[2]) cr.fill() # Draw the outline. #cr.set_source_rgb(color[0]*0.75, color[1]*0.75, color[2]*0.75) if self.selected: cr.set_dash((10, 10), 0) cr.set_source_rgb(color[0]*0.75, color[1]*0.75, color[2]*0.75) cr.set_line_width(4.0) cr.move_to(self.pos.x + pos.x + TRIANGLE[0].x, self.pos.y + pos.y + TRIANGLE[0].y) cr.line_to(self.pos.x + pos.x + TRIANGLE[1].x, self.pos.y + pos.y + TRIANGLE[1].y) cr.line_to(self.pos.x + pos.x + TRIANGLE[2].x, self.pos.y + pos.y + TRIANGLE[2].y) cr.close_path() cr.stroke() cr.restore() def draw_rounded_rectangle(self, cr, w, h, pos): self.width, self.height = w, h rounded = 20 cr.save() # Make the path of rounded rectangle. cr.move_to(pos.x + rounded, pos.y) cr.line_to(pos.x + w - rounded, pos.y) cr.arc(pos.x + w - rounded, pos.y + rounded, rounded, -math.pi/2, 0) cr.line_to(pos.x + w, pos.y + h - rounded) cr.arc(pos.x + w - rounded, pos.y + h - rounded, rounded, 0, math.pi/2) cr.line_to(pos.x + rounded, pos.y + h) cr.arc(pos.x + rounded, pos .y + h - rounded, rounded, math.pi/2, math.pi) cr.line_to(pos.x, pos.y + rounded) cr.arc(pos.x + rounded, pos.y + rounded, rounded, math.pi, 3 * math.pi/2) cr.close_path() # Draw the outline. cr.set_source_rgb(0,0,0) cr.set_line_width(4.0) if self.selected: cr.set_dash((10, 10), 0) cr.stroke() cr.restore()