# 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 vector import Vector import gtk, math, rsvg STEM_SVG = rsvg.Handle('balance_stem.svg') ARM_SVG = rsvg.Handle('balance_arm.svg') PAN_SVG = rsvg.Handle('balance_pan.svg') OVAL_SVG = rsvg.Handle('oval.svg') MIDDLE_SVG = rsvg.Handle('balance_middle.svg') LEFT_SVG = rsvg.Handle('balance_left.svg') RIGHT_SVG = rsvg.Handle('balance_right.svg') # 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 BalanceObject(Object): """Balance scale for comparing masses.""" def __init__(self, pos, container): Object.__init__(self) self.pos = pos self.size = Vector (200, 200) self.selectable = False self.rotatable = False self.container = container self.amount_scale = 1.0 self.state = 'middle' self.left_pan_full = False self.right_pan_full = False self.pan1_position = Vector(200, 500) self.pan2_position = Vector(725, 500) def draw(self, cr): cr.scale(self.amount_scale, self.amount_scale) #if self.state == 'left': # self.draw_pan(cr, Vector (self.pos.x + self.amount_scale * 20, self.pos.y + self.amount_scale * (255 + 68))) # self.draw_pan(cr, Vector (self.pos.x + self.amount_scale * 539, self.pos.y + self.amount_scale * (255 - 72))) #elif self.state == 'right': # self.draw_pan(cr, Vector (self.pos.x + self.amount_scale * 20, self.pos.y + self.amount_scale * (255 - 72))) # self.draw_pan(cr, Vector (self.pos.x + self.amount_scale * 539, self.pos.y + self.amount_scale * (255 + 68))) #else: # self.draw_pan(cr, Vector (self.pos.x + self.amount_scale * 20, self.pos.y + self.amount_scale * 255)) # self.draw_pan(cr, Vector (self.pos.x + self.amount_scale * 539, self.pos.y + self.amount_scale * 255)) # #self.draw_arm(cr, Vector (self.pos.x + self.amount_scale * 177, self.pos.y + self.amount_scale * 210)) if self.state == 'left': self.draw_left(cr, Vector (self.pos.x, self.pos.y)) elif self.state == 'right': self.draw_right(cr, Vector (self.pos.x, self.pos.y)) else: self.draw_middle(cr, Vector (self.pos.x, self.pos.y)) def adjust_balance_state(self): #print "BalanceObject: adjust_balance_state called, self.state =", self.state if self.state == 'left': self.pan1_position = Vector(200, 500 + 68) self.pan2_position = Vector(725, 500 - 72) elif self.state == 'right': self.pan1_position = Vector(200, 500 - 72) self.pan2_position = Vector(725, 500 + 68) else: self.pan1_position = Vector(200, 500) self.pan2_position = Vector(725, 500) self.queue_draw() 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_stem(self, cr, pos): cr.save() cr.translate(pos.x, pos.y) cr.scale(3.0, 3.0) STEM_SVG.render_cairo(cr) cr.restore() def draw_left(self, cr, pos): cr.save() cr.translate(pos.x, pos.y) cr.scale(3.0, 3.0) LEFT_SVG.render_cairo(cr) cr.restore() def draw_right(self, cr, pos): cr.save() cr.translate(pos.x, pos.y) cr.scale(3.0, 3.0) RIGHT_SVG.render_cairo(cr) cr.restore() def draw_middle(self, cr, pos): cr.save() cr.translate(pos.x, pos.y) cr.scale(3.0, 3.0) MIDDLE_SVG.render_cairo(cr) cr.restore() def draw_arm(self, cr, pos): cr.save() if self.state == 'left': cr.rotate(-15.0 * math.pi/180.0) cr.translate(pos.x - 150 + 68, pos.y + 113) elif self.state == 'right': cr.rotate(15.0 * math.pi/180.0) cr.translate(pos.x - 150 + 168 + 32, pos.y - 90 -40) else: cr.translate(pos.x, pos.y) cr.scale(3.0, 3.0) ARM_SVG.render_cairo(cr) cr.restore() def draw_pan(self, cr, pos): cr.save() cr.translate(pos.x, pos.y) cr.scale(3.0, 3.0) PAN_SVG.render_cairo(cr) cr.restore()