# 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 . import gtk from vector import Vector from droptargetobject import DropTargetObject from linesegmentobject import LineSegmentObject from linesegmentmovableobject import LineSegmentMovableObject DEBUG = False class LineSegmentDropTarget(DropTargetObject): """Drop target which line segments can be dropped.""" def __init__(self, pos, container): DropTargetObject.__init__(self, pos, Vector(80, 270), container) self.draggable = False self.selectable = False self.hilite = False self.contents = None self.drop_origin = None self.drop_targets = None self.full = False self.shape1 = None self.shape2 = None self.answer = 'equal' def draw(self, cr): #cr.set_source_rgb(0, 1, 1) #self_bounds_mn, self_bounds_mx = self.get_bounds() #cr.rectangle(self_bounds_mn.x, self_bounds_mn.y, self_bounds_mx.x - self_bounds_mn.x, self_bounds_mx.y - self_bounds_mn.y) #cr.fill() cr.rectangle(self.pos.x, self.pos.y, self.size.x, self.size.y) cr.set_source_rgb(0, 0, 0) cr.set_line_width(4.0) if self.hilite: cr.set_dash((10, 10), 0) cr.stroke() n = 0 n = self.how_many_line_segment_movables_inside() def how_many_line_segment_movables_inside(self): i = 0 for o in self.container.objects: if isinstance(o, LineSegmentMovableObject): if self.contains(o.get_bounds()): i += 1 return i def get_bounds(self): #return self.pos - Vector(2,2), self.pos + self.size return self.pos - Vector(2,2), self.pos + self.size + Vector(0,2) def contains(self, other_bounds): self_bounds_mn, self_bounds_mx = self.get_bounds() other_bounds_mn, other_bounds_mx = other_bounds if other_bounds_mn.x > self_bounds_mn.x \ and other_bounds_mx.x < self_bounds_mx.x \ and other_bounds_mn.y > self_bounds_mn.y \ and other_bounds_mx.y < self_bounds_mx.y : return True else: return False def processDrop(self, draggable_object): if DEBUG: print "LineSegmentDropTarget: processDrop called on object at ", self.pos if not isinstance(draggable_object, LineSegmentObject) and not isinstance(draggable_object, LineSegmentMovableObject): if DEBUG: print "LineSegmentDropTarget: not a LineSegmentMovableObject" return False else: if DEBUG: print "LineSegmentDropTarget: IS LineSegmentMovableObject!" if self.full: self.drop_origin.reset() return False if isinstance(draggable_object, LineSegmentMovableObject): if draggable_object.length == 100: movable_object = LineSegmentMovableObject(Vector(40, 10), 100, self.drop_targets, self.container) movable_object.move(self.pos + Vector(40, 160)) elif draggable_object.length == 200: movable_object = LineSegmentMovableObject(Vector(40, 110), 200, self.drop_targets, self.container) movable_object.move(self.pos + Vector(40, 60)) draggable_object.move(Vector(10000, 10000)) draggable_object.dragged = False draggable_object.selected = False draggable_object.draggable = False draggable_object.selectable = False draggable_object.drag_type = None draggable_object.moving_by_key_press = False # Get rid of the incoming MovableObject. self.remove_object(draggable_object) movable_object.dragged = False #movable_object.selected = True if self.container: self.container.select_object(movable_object) movable_object.draggable = True movable_object.selectable = True movable_object.drop_targets = self.drop_targets movable_object.drop_origin = self.drop_origin if self.container: self.container.add_object(movable_object) self.contents = movable_object self.full = True self.hilite = False self.queue_draw() if self.drop_origin: if self.container: self.container.select_object(self.drop_origin.line1) else: #print "LineSegmentDropTarget: creating LineSegmentMovableObject with drop targets",self.drop_targets #print "LineSegmentDropTarget: len(self.drop_targets) =",len(self.drop_targets) if draggable_object.length == 100: movable_object = LineSegmentMovableObject(Vector(40, 10), 100, self.drop_targets, self.container) movable_object.move(self.pos + Vector(40, 160)) elif draggable_object.length == 200: movable_object = LineSegmentMovableObject(Vector(40, 110), 200, self.drop_targets, self.container) movable_object.move(self.pos + Vector(40, 60)) draggable_object.move(Vector(10000, 10000)) draggable_object.dragged = False draggable_object.selected = False draggable_object.draggable = False draggable_object.selectable = False draggable_object.drag_type = None draggable_object.moving_by_key_press = False movable_object.dragged = False movable_object.selected = False movable_object.draggable = True movable_object.selectable = True movable_object.drop_targets = self.drop_targets movable_object.drop_origin = self.drop_origin self.container.add_object(movable_object) self.contents = movable_object self.full = True self.hilite = False self.queue_draw() if self.drop_origin: self.container.select_object(self.drop_origin.line1) if not self.answer_correct() and self.all_drop_targets_full(): self.reset_all_drop_targets() self.container.register_error() elif self.answer_correct(): self.container.selected_object = None self.freeze_drop_targets() self.container.finish_problem_stage2() if self.drop_origin: self.drop_origin.reset() return True def freeze_drop_targets(self): for o in self.drop_targets: o.contents.selected = False o.contents.selectable = False o.contents.dragged = False o.contents.draggable = False o.full = False def reset_all_drop_targets(self): for o in self.drop_targets: o.reset() o.full = False def reset(self): self.remove_object(self.contents) def all_drop_targets_full(self): b = True for o in self.drop_targets: if not o.full: b = False break return b def answer_correct(self): b = False if self.drop_targets[0].full and self.drop_targets[1].full: if self.answer == 'greater' \ and self.drop_targets[0].contents.length > self.drop_targets[1].contents.length: b = True elif self.answer == 'equal' \ and self.drop_targets[0].contents.length == self.drop_targets[1].contents.length: b = True elif self.answer == 'less' \ and self.drop_targets[0].contents.length < self.drop_targets[1].contents.length: b = True return b