def __init__(self, parent, input_image, image_ft, RMS_error): super().__init__(parent, title="Phase View") self._panel = wx.Panel(self) wx_img_real = _np_grey_img_to_wx_image(input_image) wx_img_fourier = _np_grey_img_to_wx_image(image_ft) self._canvas = FloatCanvas(self._panel, size=wx_img_real.GetSize()) self._real_bmp = self._canvas.AddBitmap(wx_img_real, (0, 0), Position="cc") self._fourier_bmp = self._canvas.AddBitmap(wx_img_fourier, (0, 0), Position="cc") # By default, show real and hide the fourier transform. self._fourier_bmp.Hide() save_btn = wx.ToggleButton(self._panel, label="Show Fourier") save_btn.Bind(wx.EVT_TOGGLEBUTTON, self.OnToggleFourier) rms_txt = wx.StaticText(self._panel, label="RMS difference: %.05f" % (RMS_error)) panel_sizer = wx.BoxSizer(wx.VERTICAL) panel_sizer.Add(self._canvas) bottom_sizer = wx.BoxSizer(wx.HORIZONTAL) bottom_sizer.Add(save_btn, wx.SizerFlags().Center().Border()) bottom_sizer.Add(rms_txt, wx.SizerFlags().Center().Border()) panel_sizer.Add(bottom_sizer) self._panel.SetSizer(panel_sizer) frame_sizer = wx.BoxSizer(wx.VERTICAL) frame_sizer.Add(self._panel) self.SetSizerAndFit(frame_sizer)
def __init__(self, builder=None, brick_size=(0.2, 0.05)): super(Designer, self).__init__(None) # config # self.builder = builder self.brick_size = brick_size # bind # self.Bind(wx.EVT_LISTBOX, self.on_listBox, self.listBox) self.Bind(wx.EVT_BUTTON, self.add_brick, self.button_add) self.Bind(wx.EVT_BUTTON, self.remove_brick, self.button_remove) self.Bind(wx.EVT_BUTTON, self.rotate_brick, self.button_rotate) self.Bind(wx.EVT_BUTTON, self.run, self.button_run) self.Bind(wx.EVT_BUTTON, self.load, self.button_load) self.Bind(wx.EVT_BUTTON, self.save, self.button_save) self.Bind(wx.EVT_TEXT_ENTER, self.update_brick, self.textBox_name) self.Bind(wx.EVT_TEXT_ENTER, self.update_input, self.textBox_X) self.Bind(wx.EVT_TEXT_ENTER, self.update_input, self.textBox_Y) self.Bind(wx.EVT_TEXT_ENTER, self.update_input, self.textBox_R) # Publisher().subscribe(self.on_msg, "update") # canvas # self.canvas = FloatCanvas(self.draw_panel, size=(600, 500), ProjectionFun=None, BackgroundColor="White") self.canvas.Bind(wx.EVT_MOUSE_EVENTS, self.on_mouse) self.refresh()
def __init__(self, world): self.world = world self.app = wx.PySimpleApp() self.w = 500 self.h = 500 self.frame = wx.Frame(None, -1, 'Ant Plot', size=(self.w, self.h)) self.canvas = FloatCanvas(self.frame, -1)
def __init__(self, city, population): self.city = city self.population = population self.app = wx.App(False) self.w = self.city.size + 100 self.h = self.city.size + 120 self.frame = wx.Frame(None, -1, 'Income Map', size=(self.w, self.h)) self.canvas = FloatCanvas(self.frame, -1)
class _PhaseViewer(wx.Frame): """This is a window for selecting the ROI for interferometry.""" def __init__(self, parent, input_image, image_ft, RMS_error): super().__init__(parent, title="Phase View") self._panel = wx.Panel(self) wx_img_real = _np_grey_img_to_wx_image(input_image) wx_img_fourier = _np_grey_img_to_wx_image(image_ft) self._canvas = FloatCanvas(self._panel, size=wx_img_real.GetSize()) self._real_bmp = self._canvas.AddBitmap(wx_img_real, (0, 0), Position="cc") self._fourier_bmp = self._canvas.AddBitmap(wx_img_fourier, (0, 0), Position="cc") # By default, show real and hide the fourier transform. self._fourier_bmp.Hide() save_btn = wx.ToggleButton(self._panel, label="Show Fourier") save_btn.Bind(wx.EVT_TOGGLEBUTTON, self.OnToggleFourier) rms_txt = wx.StaticText(self._panel, label="RMS difference: %.05f" % (RMS_error)) panel_sizer = wx.BoxSizer(wx.VERTICAL) panel_sizer.Add(self._canvas) bottom_sizer = wx.BoxSizer(wx.HORIZONTAL) bottom_sizer.Add(save_btn, wx.SizerFlags().Center().Border()) bottom_sizer.Add(rms_txt, wx.SizerFlags().Center().Border()) panel_sizer.Add(bottom_sizer) self._panel.SetSizer(panel_sizer) frame_sizer = wx.BoxSizer(wx.VERTICAL) frame_sizer.Add(self._panel) self.SetSizerAndFit(frame_sizer) def OnToggleFourier(self, event: wx.CommandEvent) -> None: show_fourier = event.IsChecked() # These bmp are wx.lib.floatcanvas.FCObjects.Bitmap and not # wx.Bitmap. Their Show method does not take show argument # and therefore we can't do `Show(show_fourier)`. if show_fourier: self._fourier_bmp.Show() self._real_bmp.Hide() else: self._real_bmp.Show() self._fourier_bmp.Hide() self._canvas.Draw(Force=True)
class AntPlot: """Class that uses wx to draw a plot of the Ants in the World.""" def __init__(self, world): self.world = world self.app = wx.PySimpleApp() self.w = 500 self.h = 500 self.frame = wx.Frame(None, -1, 'Ant Plot', size=(self.w, self.h)) self.canvas = FloatCanvas(self.frame, -1) def draw(self): """Pops up a wx window that represents the current state of the World. """ positions = self.world.get_ant_dict() for pos in positions: x, y = pos x -= self.w / 2 y -= self.h / 2 self.canvas.AddPoint((x, y)) self.frame.Show() self.app.MainLoop()
def __init__(self, parent): super(PaintPanel, self).__init__(parent=parent) self.network = Engine.Instance().network szr = wx.BoxSizer() self.canvas = FloatCanvas(parent=self) szr.Add(self.canvas, proportion=1, flag=wx.EXPAND) self.SetSizer(szr) self.Bind(wx.EVT_RIGHT_UP, Engine.Instance().OnRightClick) self.canvas.Bind(wx.EVT_RIGHT_UP, Engine.Instance().OnRightClick) # The following is called a lambda expression: # It allows us to define functions on-the-go. # It is no more than a function without definition. self.canvas.Bind( wx.EVT_LEFT_UP, lambda event, panel=self.canvas: self.OnLeftClick(event)) self.canvas.Bind(wx.EVT_PAINT, self.OnWindowBack)
class PaintPanel(wx.Panel): """Canvas to let people draw networks""" def __init__(self, parent): super(PaintPanel, self).__init__(parent=parent) self.network = Engine.Instance().network szr = wx.BoxSizer() self.canvas = FloatCanvas(parent=self) szr.Add(self.canvas, proportion=1, flag=wx.EXPAND) self.SetSizer(szr) self.Bind(wx.EVT_RIGHT_UP, Engine.Instance().OnRightClick) self.canvas.Bind(wx.EVT_RIGHT_UP, Engine.Instance().OnRightClick) # The following is called a lambda expression: # It allows us to define functions on-the-go. # It is no more than a function without definition. self.canvas.Bind( wx.EVT_LEFT_UP, lambda event, panel=self.canvas: self.OnLeftClick(event)) self.canvas.Bind(wx.EVT_PAINT, self.OnWindowBack) # self.canvas.Bind(wx.EVT_HIBERNATE) def OnWindowBack(self, event): pass def OnLeftClick(self, event): if Engine.Instance().toolbarClicked: dc = wx.ClientDC(self.canvas) if Engine.Instance().item == "Node": x, y = event.GetX(), event.GetY() frontNode = NodeRepr() frontNode.circle = FC.Circle(XY=(x, y), Diameter=NodeDrawer.size) dc.DrawCircle(frontNode.circle.XY[0], frontNode.circle.XY[1], NodeDrawer.size / 2) Engine.Instance().releaseFocus() Engine.Instance().AddNode(frontNode)
def __init__(self, parent, input_image: np.ndarray, initial_roi, scale_factor=1) -> None: super().__init__(parent, title="ROI selector") self._panel = wx.Panel(self) self._img = _np_grey_img_to_wx_image(input_image) self._scale_factor = scale_factor # What, if anything, is being dragged. # XXX: When we require Python 3.8, annotate better with # `typing.Literal[None, "xy", "r"]` self._dragging: typing.Optional[str] = None # Canvas self.canvas = FloatCanvas(self._panel, size=self._img.GetSize()) self.canvas.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse) self.bitmap = self.canvas.AddBitmap(self._img, (0, 0), Position="cc") self.circle = self.canvas.AddCircle( self.canvas.PixelToWorld(initial_roi[:2]), initial_roi[2] * 2, LineColor="cyan", LineWidth=2, ) # Save button saveBtn = wx.Button(self._panel, label="Save ROI") saveBtn.Bind(wx.EVT_BUTTON, self.OnSave) panel_sizer = wx.BoxSizer(wx.VERTICAL) panel_sizer.Add(self.canvas) panel_sizer.Add(saveBtn, wx.SizerFlags().Border()) self._panel.SetSizer(panel_sizer) frame_sizer = wx.BoxSizer(wx.VERTICAL) frame_sizer.Add(self._panel) self.SetSizerAndFit(frame_sizer)
class _ROISelect(wx.Frame): """Display a window that allows the user to select a circular area. This is a window for selecting the ROI for interferometry. """ def __init__(self, parent, input_image: np.ndarray, initial_roi, scale_factor=1) -> None: super().__init__(parent, title="ROI selector") self._panel = wx.Panel(self) self._img = _np_grey_img_to_wx_image(input_image) self._scale_factor = scale_factor # What, if anything, is being dragged. # XXX: When we require Python 3.8, annotate better with # `typing.Literal[None, "xy", "r"]` self._dragging: typing.Optional[str] = None # Canvas self.canvas = FloatCanvas(self._panel, size=self._img.GetSize()) self.canvas.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse) self.bitmap = self.canvas.AddBitmap(self._img, (0, 0), Position="cc") self.circle = self.canvas.AddCircle( self.canvas.PixelToWorld(initial_roi[:2]), initial_roi[2] * 2, LineColor="cyan", LineWidth=2, ) # Save button saveBtn = wx.Button(self._panel, label="Save ROI") saveBtn.Bind(wx.EVT_BUTTON, self.OnSave) panel_sizer = wx.BoxSizer(wx.VERTICAL) panel_sizer.Add(self.canvas) panel_sizer.Add(saveBtn, wx.SizerFlags().Border()) self._panel.SetSizer(panel_sizer) frame_sizer = wx.BoxSizer(wx.VERTICAL) frame_sizer.Add(self._panel) self.SetSizerAndFit(frame_sizer) @property def ROI(self): """Convert circle parameters to ROI x, y and radius""" roi_x, roi_y = self.canvas.WorldToPixel(self.circle.XY) roi_r = max(self.circle.WH) return (roi_x, roi_y, roi_r) def OnSave(self, event: wx.CommandEvent) -> None: del event roi = [x * self._scale_factor for x in self.ROI] userConfig.setValue("dm_circleParams", (roi[1], roi[0], roi[2])) def MoveCircle(self, pos: wx.Point, r) -> None: """Set position and radius of circle with bounds checks.""" x, y = pos _x, _y, _r = self.ROI xmax, ymax = self._img.GetSize() if r == _r: x_bounded = min(max(r, x), xmax - r) y_bounded = min(max(r, y), ymax - r) r_bounded = r else: r_bounded = max(_ROI_MIN_RADIUS, min(xmax - x, x, ymax - y, y, r)) x_bounded = min(max(r_bounded, x), xmax - r_bounded) y_bounded = min(max(r_bounded, y), ymax - r_bounded) self.circle.SetPoint(self.canvas.PixelToWorld((x_bounded, y_bounded))) self.circle.SetDiameter(2 * r_bounded) if any((x_bounded != x, y_bounded != y, r_bounded != r)): self.circle.SetColor("magenta") else: self.circle.SetColor("cyan") def OnMouse(self, event: wx.MouseEvent) -> None: pos = event.GetPosition() x, y, r = self.ROI if event.LeftDClick(): # Set circle centre self.MoveCircle(pos, r) elif event.Dragging(): # Drag circle centre or radius drag_r = np.sqrt((x - pos[0])**2 + (y - pos[1])**2) if self._dragging is None: # determine what to drag if drag_r < 0.5 * r: # closer to center self._dragging = "xy" else: # closer to edge self._dragging = "r" elif self._dragging == "r": # Drag circle radius self.MoveCircle((x, y), drag_r) elif self._dragging == "xy": # Drag circle centre self.MoveCircle(pos, r) if not event.Dragging(): # Stop dragging self._dragging = None self.circle.SetColor("cyan") self.canvas.Draw(Force=True)
class CityPrinter(object): def __init__(self, city, population): self.city = city self.population = population self.app = wx.App(False) self.w = self.city.size + 100 self.h = self.city.size + 120 self.frame_rent = wx.Frame(None, -1, 'Rent Map', size=(self.w, self.h)) self.frame_income = wx.Frame(None, -1, 'Income Map', size=(self.w, self.h)) self.canvas_rent = FloatCanvas(self.frame_rent, -1) self.canvas_income = FloatCanvas(self.frame_income, -1) def create_heatmaps(self): self.create_rent_map() self.create_income_map() self.app.MainLoop() def create_rent_map(self): print("Lowest Rent: " + str(self.city.min_price)) print("Highest Rent: " + str(self.city.max_price)) min_price = self.city.min_price max_price = self.city.max_price time1 = time.time() print("Generating Rent Map") for house in self.city.houses: x = house.x - self.city.size / 2 y = house.y - self.city.size / 2 col = self.color(self.city.get_house(house).price, min_price, max_price, \ self.city.get_house(house).occupant == None) self.canvas_rent.AddPoint((x, y), Color = col) time2 = time.time() print('Generating Image took %0.3f ms' % ((time2-time1) * 1000.0)) self.frame_rent.Show() def create_income_map(self): print("Lowest Income: " + str(self.population.min_income)) print("Highest Income: " + str(self.population.max_income)) min_income = self.population.min_income max_income = self.population.max_income time1 = time.time() print("Generating Income Map") for house in self.city.houses: x = house.x - self.city.size / 2 y = house.y - self.city.size / 2 person = self.city.get_house(house).occupant if person != None: col = self.color(person.income, min_income, max_income) self.canvas_income.AddPoint((x, y), Color = col) time2 = time.time() print('Generating Image took %0.3f ms' % ((time2-time1) * 1000.0)) self.frame_income.Show() def color(self, value, min, max, red=False): #print("Colouring In") if not red: # Approximating http://geog.uoregon.edu/datagraphics/color/Bu_10.txt on the fly red_range = (0, 0.9) green_range = (0.25, 1.0) blue_range = (1.0, 1.0) else: # Colour Shifting it to red red_range = (1.0, 1.0) green_range = (0, 0.9) blue_range = (0.25, 1.0) percentage_of_range = 1 - (value - min)/(max - min) red = (((red_range[1] - red_range[0]) * percentage_of_range) + red_range[0]) * 255 green = (((green_range[1] - green_range[0]) * percentage_of_range) + green_range[0]) * 255 blue = (((blue_range[1] - blue_range[0]) * percentage_of_range) + blue_range[0]) * 255 return wx.Colour(red, green, blue, 1) """ Write the city to standard out for quick testing and debugging. """ def __str__(self): output = "" output += "Cheapest Place: " + str(self.city.min_price) + "\n" output += "Most Expensive Place: " + str(self.city.max_price) + "\n" output += "\n" for y in range(self.city.size): row = "" for x in range(self.city.size): coords = Coordinates(x, y) occupied_string = "_" if self.city.get_house(coords).occupant == None else "X" row += str("%3d%s " % (self.city.get_house(coords).price, occupied_string)) output += row + "\n" return output
class CityPrinter(object): def __init__(self, city, population): self.city = city self.population = population self.app = wx.App(False) self.w = self.city.size + 100 self.h = self.city.size + 120 self.frame = wx.Frame(None, -1, 'Income Map', size=(self.w, self.h)) self.canvas = FloatCanvas(self.frame, -1) def create_heatmap(self): min_income = self.population.min_income max_income = self.population.max_income print("Lowest Income: " + str(min_income)) print("Highest Income: " + str(max_income)) for house in self.city.houses: x = house.x - self.city.size / 2 y = house.y - self.city.size / 2 person = self.city.get_house(house) if person != None: col = self.color(person.income, min_income, max_income) self.canvas.AddPoint((x, y), Color=col) self.frame.Show() self.app.MainLoop() def color(self, value, min_val, max_val): # Approximating http://geog.uoregon.edu/datagraphics/color/Bu_10.txt on the fly red_range = (0, 0.9) green_range = (0.25, 1.0) blue_range = (1.0, 1.0) percentage_of_range = 1 - (value - min_val) / (max_val - min_val) red = (((red_range[1] - red_range[0]) * percentage_of_range) + red_range[0]) * 255 green = (((green_range[1] - green_range[0]) * percentage_of_range) + green_range[0]) * 255 blue = (((blue_range[1] - blue_range[0]) * percentage_of_range) + blue_range[0]) * 255 return wx.Colour(red, green, blue, 1) """ Write the city to standard out for quick testing and debugging. """ def __str__(self): output = "" for y in range(self.city.size): row = "" for x in range(self.city.size): coords = Coordinates(x, y) occupied = self.city.get_house(coords) != None if occupied: row += str("%3d " % (self.city.get_house(coords).income)) else: row += str(" ") output += row + "\n" return output
def __init__(self, parent): self.parent = parent FloatCanvas.__init__(self, parent, BackgroundColor="BLACK") self.circles = [] self.GUIMode = GUICustom(self)
class Designer(MyFrame): # config # builder = None brick_size = (0.2, 0.05) # bricks # cur_index = -1 bricks = [] bricks_count = 0 # canvas # canvas_scale = 500.0 canvas_offset = (0, -0.4) def __init__(self, builder=None, brick_size=(0.2, 0.05)): super(Designer, self).__init__(None) # config # self.builder = builder self.brick_size = brick_size # bind # self.Bind(wx.EVT_LISTBOX, self.on_listBox, self.listBox) self.Bind(wx.EVT_BUTTON, self.add_brick, self.button_add) self.Bind(wx.EVT_BUTTON, self.remove_brick, self.button_remove) self.Bind(wx.EVT_BUTTON, self.rotate_brick, self.button_rotate) self.Bind(wx.EVT_BUTTON, self.run, self.button_run) self.Bind(wx.EVT_BUTTON, self.load, self.button_load) self.Bind(wx.EVT_BUTTON, self.save, self.button_save) self.Bind(wx.EVT_TEXT_ENTER, self.update_brick, self.textBox_name) self.Bind(wx.EVT_TEXT_ENTER, self.update_input, self.textBox_X) self.Bind(wx.EVT_TEXT_ENTER, self.update_input, self.textBox_Y) self.Bind(wx.EVT_TEXT_ENTER, self.update_input, self.textBox_R) # Publisher().subscribe(self.on_msg, "update") # canvas # self.canvas = FloatCanvas(self.draw_panel, size=(600, 500), ProjectionFun=None, BackgroundColor="White") self.canvas.Bind(wx.EVT_MOUSE_EVENTS, self.on_mouse) self.refresh() def on_listBox(self, event): self.cur_index = event.GetEventObject().GetSelection() self.refresh() # def on_msg(self): # def is_selected(self): if 0 <= self.cur_index < len(self.bricks): return True else: self.cur_index = -1 return False # ---- bricks ---- # def add_brick(self, event): name = 'brick' + str(self.bricks_count) new_brick = Brick(name, 0, self.brick_size[1] / 2) self.bricks.append(new_brick) self.cur_index = len(self.bricks) - 1 self.bricks_count += 1 self.refresh() def remove_brick(self, event): if self.is_selected(): del self.bricks[self.cur_index] if self.cur_index >= len(self.bricks): self.cur_index = len(self.bricks) - 1 self.refresh() def rotate_brick(self, event): if self.is_selected(): d = pi / 4 cur = self.bricks[self.cur_index] cur.r = ((int(cur.r / d) + 1) * d) % pi self.refresh() def update_brick(self, event): if self.is_selected(): cur = self.bricks[self.cur_index] new_name = self.textBox_name.GetValue() if cur.name != new_name: for i in range(0, len(self.bricks), 1): if self.bricks[i].name == new_name: return cur.name = new_name cur.x = float(self.textBox_X.GetValue()) cur.y = float(self.textBox_Y.GetValue()) cur.r = float(self.textBox_R.GetValue()) self.refresh() def update_input(self, event): x = self.textBox_X.GetValue() y = self.textBox_Y.GetValue() r = self.textBox_R.GetValue() if self.is_selected( ) and x != '' and y != '' and r != '' and self.down_pos is None: cur = self.bricks[self.cur_index] cur.x = float(x) cur.y = float(y) cur.r = float(r) self.refresh_canvas() # ---- refresh ---- # def refresh(self): self.refresh_list() self.refresh_prop() self.refresh_canvas() def refresh_list(self): self.listBox.Clear() for brick in self.bricks: self.listBox.Append(brick.name) if self.is_selected(): self.listBox.Select(self.cur_index) def refresh_prop(self): if self.is_selected(): cur = self.bricks[self.cur_index] self.textBox_name.SetValue(str(cur.name)) self.textBox_X.SetValue(str(cur.x)) self.textBox_Y.SetValue(str(cur.y)) self.textBox_R.SetValue(str(cur.r)) # self.prop_panel.Show() else: self.textBox_name.Clear() self.textBox_X.Clear() self.textBox_Y.Clear() self.textBox_R.Clear() # self.prop_panel.Hide() # ---- canvas ---- # def refresh_canvas(self): self.canvas.ClearAll() self.draw_lines() for brick in self.bricks: if not self.is_selected() or brick != self.bricks[self.cur_index]: self.canvas.AddObject(self.get_box(brick, "Yellow")) if self.is_selected(): self.canvas.AddObject( self.get_box(self.bricks[self.cur_index], "Yellow", "Orange")) self.canvas.Draw() def draw_lines(self): self.canvas.AddObject( Line([self.to_offset( (1, 0)), self.to_offset((-1, 0))], LineWidth=5)) self.canvas.AddObject( Line([self.to_offset( (0, 1)), self.to_offset((0, -1))], LineWidth=2, LineStyle="ShortDash")) for x in range(-5, 6, 1): self.canvas.AddObject( Line([ self.to_offset((x * 0.1, 1)), self.to_offset((x * 0.1, -1)) ], LineStyle="Dot", LineWidth=0.1)) for y in range(-5, 10, 1): self.canvas.AddObject( Line([ self.to_offset((1, y * 0.1)), self.to_offset((-1, y * 0.1)) ], LineStyle="Dot", LineWidth=0.1)) def get_box(self, brick, FillColor, LineColor="Black"): brick = ((brick.x + self.canvas_offset[0]) * self.canvas_scale, (brick.y + self.canvas_offset[1]) * self.canvas_scale, brick.r) brick_size = (self.brick_size[0] * self.canvas_scale, self.brick_size[1] * self.canvas_scale) p1 = to_points(brick, (brick_size[0] / 2, brick_size[1] / 2)) p2 = to_points(brick, (brick_size[0] / 2, -brick_size[1] / 2)) p3 = to_points(brick, (-brick_size[0] / 2, -brick_size[1] / 2)) p4 = to_points(brick, (-brick_size[0] / 2, brick_size[1] / 2)) return Polygon([p1, p2, p3, p4], LineWidth=2, FillColor=FillColor, LineColor=LineColor) def to_offset(self, point): return ((point[0] + self.canvas_offset[0]) * self.canvas_scale, (point[1] + self.canvas_offset[1]) * self.canvas_scale) def from_offset(self, point): return ((point[0] / self.canvas_scale - self.canvas_offset[0]), (point[1] / self.canvas_scale - self.canvas_offset[1])) # ---- run ---- # def run(self, event): targets = self.get_targets() self.builder.set_targets(targets) self.builder.show_target() rospy.sleep(2) self.builder.show_source() thread.start_new_thread(self.builder.build, ()) def get_targets(self): targets = [] for brick in self.bricks: transform = build_frame( (brick.x, 0, brick.y), (-pi / 2, 0, 0)) * build_frame(rpy=(0, 0, brick.r)) targets.append(transform) return targets # ----- drag ---- # down_pos = None pre_pos = None def on_mouse(self, event): if not self.is_selected(): return brick = self.bricks[self.cur_index] cur_pos = self.from_offset(event.GetPosition()) if event.ButtonDown(): self.down_pos = cur_pos self.pre_pos = (brick.x, brick.y) elif event.Dragging(): if self.down_pos is not None: pos = (cur_pos[0] - self.down_pos[0], cur_pos[1] - self.down_pos[1]) brick.x = self.pre_pos[0] + pos[0] brick.y = self.pre_pos[1] - pos[1] if self.is_aligned.GetValue(): align = self.brick_size[1] / 2 brick.x = int(brick.x / align) * align brick.y = int(brick.y / align) * align self.refresh() elif event.ButtonUp(): self.down_pos = None self.pre_pos = None # ---- file ---- # def load(self, event): dlg = wx.FileDialog(self, "加载图纸", defaultDir=os.getcwd(), wildcard='图纸文件 (*.dsg)|*.dsg|全部文件|*', style=wx.OPEN | wx.FILE_MUST_EXIST) if dlg.ShowModal() == wx.ID_OK: try: with open(dlg.GetPath(), 'r') as design_file: bricks = [] for target in json.load(design_file): bricks.append( Brick(target['name'], target['x'], target['y'], target['r'])) self.bricks = bricks self.cur_index = -1 self.refresh() except BaseException, e: error_dlg = wx.MessageDialog(None, "无法识别的图纸文件!\n错误详情: " + e.message, "加载失败", wx.ICON_ERROR) error_dlg.ShowModal() error_dlg.Destroy() dlg.Destroy()