class LayoutWindow(Window): LINE_COLOR = pygame.Color('white') SELECT_COLOR = pygame.Color('yellow') BASE_COLOR = pygame.Color('light blue') def __init__(self, main, x, y, width, height=0): Window.__init__(self, main, x, y, width, height) self.grid_size = 10 self.grid_visible = True self.selected_stamp = None self.snap_to_grid = False self.keep_current_ratio = False self.keep_original_ratio = False self.layout = Layout(self.main.shape_window.shape) self.colors = [pygame.Color('white')] * 10 def setDirty(self): self.dirty = True self.main.fractal_window.setDirty() def updateSurface(self): self.fillBgd() if self.grid_visible: self.drawGrid() offset_x = self.rect.width / 2 offset_y = self.rect.height / 2 color = self.SELECT_COLOR # Draw the hightlight under the lines if self.selected_stamp: stamp = self.selected_stamp if stamp == self.layout.getBaseStamp(): color = self.BASE_COLOR rect = self.main.shape_window.shape.bounds.copy() rect.width *= stamp.scale[0] rect.height *= stamp.scale[1] width_greater_than_zero = rect.width > 0 height_greater_than_zero = rect.height > 0 rect.width = abs(rect.width) rect.height = abs(rect.height) # give the lines some room rect.width += 3 rect.height += 3 half_width = rect.width / 2 half_height = rect.height / 2 rect.center = (half_width, half_height) if rect.width > 0 and rect.height > 0: temp = pygame.Surface((rect.width, rect.height), pygame.SRCALPHA) pygame.draw.rect(temp, color, rect, 1) control_size = (stamp.control_size, stamp.control_size) rot_size = stamp.control_size / 2 if width_greater_than_zero: if height_greater_than_zero: #s1 r1 #r2 s2 scale_pos1 = (0, 0) scale_pos2 = (rect.width - control_size[0], rect.height - control_size[1]) rot_pos1 = (rect.width - control_size[0] + rot_size, rot_size) rot_pos2 = (rot_size, rect.height - control_size[1] + rot_size) else: #r2 s2 #s1 r1 scale_pos1 = (0, rect.height - control_size[1]) scale_pos2 = (rect.width - control_size[0], 0) rot_pos1 = (rect.width - control_size[0] + rot_size, rect.height - control_size[1] + rot_size) rot_pos2 = (rot_size, rot_size) else: if height_greater_than_zero: #r1 s1 #s2 r2 scale_pos1 = (rect.width - control_size[0], 0) scale_pos2 = (0, rect.height - control_size[1]) rot_pos1 = (rot_size, rot_size) rot_pos2 = (rect.width - control_size[0] + rot_size, rect.height - control_size[1] + rot_size) else: #s2 r2 #r1 s1 scale_pos1 = (rect.width - control_size[0], rect.height - control_size[1]) scale_pos2 = (0, 0) rot_pos1 = (rot_size, rect.height - control_size[1] + rot_size) rot_pos2 = (rect.width - control_size[0] + rot_size, rot_size) scale_rect1 = pygame.Rect(scale_pos1, control_size) scale_rect2 = pygame.Rect(scale_pos2, control_size) pygame.draw.rect(temp, color, scale_rect1, 1) pygame.draw.rect(temp, color, scale_rect2, 1) pygame.draw.circle(temp, color, rot_pos1, rot_size, 1) pygame.draw.circle(temp, color, rot_pos2,rot_size, 1) temp = pygame.transform.rotate(temp, stamp.angle) self.surface.blit(temp, ((self.surface.get_width() - temp.get_width()) / 2 + stamp.pos.x, (self.surface.get_height() - temp.get_height()) / 2 + stamp.pos.y)) lines = self.main.shape_window.shape.getLines() shape_size = self.main.shape_window.shape.bounds.size for stamp in self.layout.getStamps(): color = self.LINE_COLOR if stamp == self.layout.getBaseStamp(): color = self.BASE_COLOR for line in lines: p1 = stamp.coords().applyCoords(line.point1) p2 = stamp.coords().applyCoords(line.point2) pygame.draw.line(self.surface, color, (p1.x + offset_x, p1.y + offset_y), (p2.x + offset_x, p2.y + offset_y)) # Draw info over lines coords_str = "(,)" angle_str = "*" scale_str = "w: , h: " if self.selected_stamp: coords_str = "(%d, %d)" % (self.selected_stamp.pos.x, self.selected_stamp.pos.y) angle_str = "%.2f*" % (self.selected_stamp.angle) scale_str = "w: %.3f, h: %.3f" % (self.selected_stamp.scale) coords_text = self.main.plain_font.render(coords_str, 1, self.main.TEXT_COLOR) angle_text = self.main.plain_font.render(angle_str, 1, self.main.TEXT_COLOR) scale_text = self.main.plain_font.render(scale_str, 1, self.main.TEXT_COLOR) self.surface.blit(coords_text, (0, 0)) self.surface.blit(angle_text, (0, 20)) self.surface.blit(scale_text, (0, 40)) ## ### Mouse position relative to rotated box for debuging ## if len(self.layout.getStamps()) > 0: ## p = self.localPoint(Point(pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1])) ## p.x -= self.layout.getBaseStamp().pos.x ## p.y -= self.layout.getBaseStamp().pos.y ## p = Point.rotate(p, -self.layout.getBaseStamp().angle) ## p.x += self.layout.getBaseStamp().pos.x ## p.y += self.layout.getBaseStamp().pos.y ## pygame.draw.circle(self.surface, pygame.Color('white'), (int(p.x+offset_x), int(p.y+offset_y)), 2) ## self.setDirty() def handleLeftMouseDown(self, global_point): if not self.rect.collidepoint(global_point.x, global_point.y): return point = self.localPoint(global_point) print "layout display left down ", point.x, point.y if not self.selected_stamp: if self.snap_to_grid: point = self.snapToGrid(point) self.layout.newStamp(point) self.selected_stamp = self.layout.getStamp(point) self.layout.grabStamp(self.selected_stamp) self.setDirty() def handleRightMouseDown(self, global_point): if not self.rect.collidepoint(global_point.x, global_point.y): return point = self.localPoint(global_point) print "layout display right down ", point.x, point.y if len(self.layout.stamps) > 0: self.layout.removeStamp(self.selected_stamp) self.selected_stamp = None self.setDirty() def handleLeftMouseUp(self, global_point): if not self.rect.collidepoint(global_point.x, global_point.y): return point = self.localPoint(global_point) print "layout display left up ", point.x, point.y self.layout.releaseStamp() def handleRightMouseUp(self, global_point): if not self.rect.collidepoint(global_point.x, global_point.y): return point = self.localPoint(global_point) print "layout display right up ", point.x, point.y def handleMouseMove(self, global_point, rel): if not self.rect.collidepoint(global_point.x, global_point.y): return point = self.localPoint(global_point) print "layout display mouse move ", point.x, point.y, ":", rel.x, rel.y prev = self.selected_stamp self.selected_stamp = self.layout.getStamp(point, prev) if self.snap_to_grid: point = self.snapToGrid(point) ratio = None if self.keep_current_ratio and self.selected_stamp: ratio = self.selected_stamp.scale[1] / self.selected_stamp.scale[0] elif self.keep_original_ratio: ratio = 1 print ratio if (self.layout.updateStamp( point, rel, self.snap_to_grid, ratio) or self.selected_stamp != prev): self.setDirty()