- optimized the Move Tool
- added support for key-based panning in 3D graphic engine. Moving the mouse wheel while pressing the CTRL key will pan up-down and while pressing SHIFT key will pan left-right
This commit is contained in:
parent
0ca078abf2
commit
3bebc16725
203
FlatCAMApp.py
203
FlatCAMApp.py
|
@ -7996,7 +7996,7 @@ class App(QtCore.QObject):
|
|||
except Exception as e:
|
||||
App.log.debug("App.on_mouse_click_over_plot() --> Outside plot? --> %s" % str(e))
|
||||
|
||||
def on_double_click_over_plot(self, event):
|
||||
def on_mouse_double_click_over_plot(self, event):
|
||||
if event.button == 1:
|
||||
self.doubleclick = True
|
||||
|
||||
|
@ -8207,7 +8207,12 @@ class App(QtCore.QObject):
|
|||
"""
|
||||
poly_selection = Polygon([start_pos, (end_pos[0], start_pos[1]), end_pos, (start_pos[0], end_pos[1])])
|
||||
|
||||
# delete previous selection shape
|
||||
self.delete_selection_shape()
|
||||
|
||||
# make all objects inactive
|
||||
self.collection.set_all_inactive()
|
||||
|
||||
for obj in self.collection.get_list():
|
||||
try:
|
||||
# select the object(s) only if it is enabled (plotted)
|
||||
|
@ -11510,7 +11515,7 @@ class App(QtCore.QObject):
|
|||
self.mm = self.plotcanvas.graph_event_connect('mouse_move', self.on_mouse_move_over_plot)
|
||||
self.mp = self.plotcanvas.graph_event_connect('mouse_press', self.on_mouse_click_over_plot)
|
||||
self.mr = self.plotcanvas.graph_event_connect('mouse_release', self.on_mouse_click_release_over_plot)
|
||||
self.mdc = self.plotcanvas.graph_event_connect('mouse_double_click', self.on_double_click_over_plot)
|
||||
self.mdc = self.plotcanvas.graph_event_connect('mouse_double_click', self.on_mouse_double_click_over_plot)
|
||||
|
||||
# Keys over plot enabled
|
||||
self.kp = self.plotcanvas.graph_event_connect('key_press', self.ui.keyPressEvent)
|
||||
|
@ -11844,107 +11849,107 @@ class App(QtCore.QObject):
|
|||
self.options.update(self.defaults)
|
||||
self.options_write_form()
|
||||
|
||||
def on_options_project2app(self):
|
||||
"""
|
||||
Callback for Options->Transfer Options->Project=>App. Copies options
|
||||
from project defaults to application defaults.
|
||||
# def on_options_project2app(self):
|
||||
# """
|
||||
# Callback for Options->Transfer Options->Project=>App. Copies options
|
||||
# from project defaults to application defaults.
|
||||
#
|
||||
# :return: None
|
||||
# """
|
||||
#
|
||||
# self.report_usage("on_options_project2app")
|
||||
#
|
||||
# self.options_read_form()
|
||||
# self.defaults.update(self.options)
|
||||
# self.defaults_write_form()
|
||||
|
||||
:return: None
|
||||
"""
|
||||
# def on_options_project2object(self):
|
||||
# """
|
||||
# Callback for Options->Transfer Options->Project=>Object. Copies options
|
||||
# from project defaults to the currently selected object.
|
||||
#
|
||||
# :return: None
|
||||
# """
|
||||
#
|
||||
# self.report_usage("on_options_project2object")
|
||||
#
|
||||
# self.options_read_form()
|
||||
# obj = self.collection.get_active()
|
||||
# if obj is None:
|
||||
# self.inform.emit('[WARNING_NOTCL] %s' %
|
||||
# _("No object selected."))
|
||||
# return
|
||||
# for option in self.options:
|
||||
# if option.find(obj.kind + "_") == 0:
|
||||
# oname = option[len(obj.kind) + 1:]
|
||||
# obj.options[oname] = self.options[option]
|
||||
# obj.to_form() # Update UI
|
||||
|
||||
self.report_usage("on_options_project2app")
|
||||
# def on_options_object2project(self):
|
||||
# """
|
||||
# Callback for Options->Transfer Options->Object=>Project. Copies options
|
||||
# from the currently selected object to project defaults.
|
||||
#
|
||||
# :return: None
|
||||
# """
|
||||
#
|
||||
# self.report_usage("on_options_object2project")
|
||||
#
|
||||
# obj = self.collection.get_active()
|
||||
# if obj is None:
|
||||
# self.inform.emit('[WARNING_NOTCL] %s' %
|
||||
# _("No object selected."))
|
||||
# return
|
||||
# obj.read_form()
|
||||
# for option in obj.options:
|
||||
# if option in ['name']: # TODO: Handle this better...
|
||||
# continue
|
||||
# self.options[obj.kind + "_" + option] = obj.options[option]
|
||||
# self.options_write_form()
|
||||
|
||||
self.options_read_form()
|
||||
self.defaults.update(self.options)
|
||||
self.defaults_write_form()
|
||||
# def on_options_object2app(self):
|
||||
# """
|
||||
# Callback for Options->Transfer Options->Object=>App. Copies options
|
||||
# from the currently selected object to application defaults.
|
||||
#
|
||||
# :return: None
|
||||
# """
|
||||
#
|
||||
# self.report_usage("on_options_object2app")
|
||||
#
|
||||
# obj = self.collection.get_active()
|
||||
# if obj is None:
|
||||
# self.inform.emit('[WARNING_NOTCL] %s' %
|
||||
# _("No object selected."))
|
||||
# return
|
||||
# obj.read_form()
|
||||
# for option in obj.options:
|
||||
# if option in ['name']: # TODO: Handle this better...
|
||||
# continue
|
||||
# self.defaults[obj.kind + "_" + option] = obj.options[option]
|
||||
# self.defaults_write_form()
|
||||
|
||||
def on_options_project2object(self):
|
||||
"""
|
||||
Callback for Options->Transfer Options->Project=>Object. Copies options
|
||||
from project defaults to the currently selected object.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
self.report_usage("on_options_project2object")
|
||||
|
||||
self.options_read_form()
|
||||
obj = self.collection.get_active()
|
||||
if obj is None:
|
||||
self.inform.emit('[WARNING_NOTCL] %s' %
|
||||
_("No object selected."))
|
||||
return
|
||||
for option in self.options:
|
||||
if option.find(obj.kind + "_") == 0:
|
||||
oname = option[len(obj.kind) + 1:]
|
||||
obj.options[oname] = self.options[option]
|
||||
obj.to_form() # Update UI
|
||||
|
||||
def on_options_object2project(self):
|
||||
"""
|
||||
Callback for Options->Transfer Options->Object=>Project. Copies options
|
||||
from the currently selected object to project defaults.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
self.report_usage("on_options_object2project")
|
||||
|
||||
obj = self.collection.get_active()
|
||||
if obj is None:
|
||||
self.inform.emit('[WARNING_NOTCL] %s' %
|
||||
_("No object selected."))
|
||||
return
|
||||
obj.read_form()
|
||||
for option in obj.options:
|
||||
if option in ['name']: # TODO: Handle this better...
|
||||
continue
|
||||
self.options[obj.kind + "_" + option] = obj.options[option]
|
||||
self.options_write_form()
|
||||
|
||||
def on_options_object2app(self):
|
||||
"""
|
||||
Callback for Options->Transfer Options->Object=>App. Copies options
|
||||
from the currently selected object to application defaults.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
self.report_usage("on_options_object2app")
|
||||
|
||||
obj = self.collection.get_active()
|
||||
if obj is None:
|
||||
self.inform.emit('[WARNING_NOTCL] %s' %
|
||||
_("No object selected."))
|
||||
return
|
||||
obj.read_form()
|
||||
for option in obj.options:
|
||||
if option in ['name']: # TODO: Handle this better...
|
||||
continue
|
||||
self.defaults[obj.kind + "_" + option] = obj.options[option]
|
||||
self.defaults_write_form()
|
||||
|
||||
def on_options_app2object(self):
|
||||
"""
|
||||
Callback for Options->Transfer Options->App=>Object. Copies options
|
||||
from application defaults to the currently selected object.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
self.report_usage("on_options_app2object")
|
||||
|
||||
self.defaults_read_form()
|
||||
obj = self.collection.get_active()
|
||||
if obj is None:
|
||||
self.inform.emit('[WARNING_NOTCL] %s' %
|
||||
_("No object selected."))
|
||||
return
|
||||
for option in self.defaults:
|
||||
if option.find(obj.kind + "_") == 0:
|
||||
oname = option[len(obj.kind) + 1:]
|
||||
obj.options[oname] = self.defaults[option]
|
||||
obj.to_form() # Update UI
|
||||
# def on_options_app2object(self):
|
||||
# """
|
||||
# Callback for Options->Transfer Options->App=>Object. Copies options
|
||||
# from application defaults to the currently selected object.
|
||||
#
|
||||
# :return: None
|
||||
# """
|
||||
#
|
||||
# self.report_usage("on_options_app2object")
|
||||
#
|
||||
# self.defaults_read_form()
|
||||
# obj = self.collection.get_active()
|
||||
# if obj is None:
|
||||
# self.inform.emit('[WARNING_NOTCL] %s' %
|
||||
# _("No object selected."))
|
||||
# return
|
||||
# for option in self.defaults:
|
||||
# if option.find(obj.kind + "_") == 0:
|
||||
# oname = option[len(obj.kind) + 1:]
|
||||
# obj.options[oname] = self.defaults[option]
|
||||
# obj.to_form() # Update UI
|
||||
|
||||
|
||||
class ArgsThread(QtCore.QObject):
|
||||
|
|
|
@ -13,6 +13,8 @@ CAD program, and create G-Code for Isolation routing.
|
|||
|
||||
- fixed the Gerber Parser convert units unnecessary usage. The only units conversion should be done when creating the new object, after the parsing
|
||||
- more fixes in Rules Check Tool
|
||||
- optimized the Move Tool
|
||||
- added support for key-based panning in 3D graphic engine. Moving the mouse wheel while pressing the CTRL key will pan up-down and while pressing SHIFT key will pan left-right
|
||||
|
||||
11.10.2019
|
||||
|
||||
|
|
|
@ -2814,7 +2814,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.app.plotcanvas.graph_event_disconnect('mouse_press', self.app.on_mouse_click_over_plot)
|
||||
self.app.plotcanvas.graph_event_disconnect('mouse_move', self.app.on_mouse_move_over_plot)
|
||||
self.app.plotcanvas.graph_event_disconnect('mouse_release', self.app.on_mouse_click_release_over_plot)
|
||||
self.app.plotcanvas.graph_event_disconnect('mouse_double_click', self.app.on_double_click_over_plot)
|
||||
self.app.plotcanvas.graph_event_disconnect('mouse_double_click', self.app.on_mouse_double_click_over_plot)
|
||||
else:
|
||||
self.app.plotcanvas.graph_event_disconnect(self.app.mp)
|
||||
self.app.plotcanvas.graph_event_disconnect(self.app.mm)
|
||||
|
@ -2844,7 +2844,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
self.app.mr = self.app.plotcanvas.graph_event_connect('mouse_release',
|
||||
self.app.on_mouse_click_release_over_plot)
|
||||
self.app.mdc = self.app.plotcanvas.graph_event_connect('mouse_double_click',
|
||||
self.app.on_double_click_over_plot)
|
||||
self.app.on_mouse_double_click_over_plot)
|
||||
self.app.collection.view.clicked.connect(self.app.collection.on_mouse_down)
|
||||
|
||||
if self.app.is_legacy is False:
|
||||
|
|
|
@ -3390,7 +3390,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
self.app.plotcanvas.graph_event_disconnect('mouse_press', self.app.on_mouse_click_over_plot)
|
||||
self.app.plotcanvas.graph_event_disconnect('mouse_move', self.app.on_mouse_move_over_plot)
|
||||
self.app.plotcanvas.graph_event_disconnect('mouse_release', self.app.on_mouse_click_release_over_plot)
|
||||
self.app.plotcanvas.graph_event_disconnect('mouse_double_click', self.app.on_double_click_over_plot)
|
||||
self.app.plotcanvas.graph_event_disconnect('mouse_double_click', self.app.on_mouse_double_click_over_plot)
|
||||
else:
|
||||
|
||||
self.app.plotcanvas.graph_event_disconnect(self.app.mp)
|
||||
|
@ -3437,7 +3437,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
self.app.mr = self.app.plotcanvas.graph_event_connect('mouse_release',
|
||||
self.app.on_mouse_click_release_over_plot)
|
||||
self.app.mdc = self.app.plotcanvas.graph_event_connect('mouse_double_click',
|
||||
self.app.on_double_click_over_plot)
|
||||
self.app.on_mouse_double_click_over_plot)
|
||||
# self.app.collection.view.clicked.connect(self.app.collection.on_mouse_down)
|
||||
|
||||
if self.app.is_legacy is False:
|
||||
|
|
|
@ -3582,7 +3582,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
self.canvas.graph_event_disconnect('mouse_press', self.app.on_mouse_click_over_plot)
|
||||
self.canvas.graph_event_disconnect('mouse_move', self.app.on_mouse_move_over_plot)
|
||||
self.canvas.graph_event_disconnect('mouse_release', self.app.on_mouse_click_release_over_plot)
|
||||
self.canvas.graph_event_disconnect('mouse_double_click', self.app.on_double_click_over_plot)
|
||||
self.canvas.graph_event_disconnect('mouse_double_click', self.app.on_mouse_double_click_over_plot)
|
||||
else:
|
||||
self.canvas.graph_event_disconnect(self.app.mp)
|
||||
self.canvas.graph_event_disconnect(self.app.mm)
|
||||
|
@ -3623,7 +3623,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
self.app.mp = self.canvas.graph_event_connect('mouse_press', self.app.on_mouse_click_over_plot)
|
||||
self.app.mm = self.canvas.graph_event_connect('mouse_move', self.app.on_mouse_move_over_plot)
|
||||
self.app.mr = self.canvas.graph_event_connect('mouse_release', self.app.on_mouse_click_release_over_plot)
|
||||
self.app.mdc = self.canvas.graph_event_connect('mouse_double_click', self.app.on_double_click_over_plot)
|
||||
self.app.mdc = self.canvas.graph_event_connect('mouse_double_click', self.app.on_mouse_double_click_over_plot)
|
||||
self.app.collection.view.clicked.connect(self.app.collection.on_mouse_down)
|
||||
|
||||
if self.app.is_legacy is False:
|
||||
|
|
|
@ -12,6 +12,7 @@ import logging
|
|||
from flatcamGUI.VisPyCanvas import VisPyCanvas, time, Color
|
||||
from flatcamGUI.VisPyVisuals import ShapeGroup, ShapeCollection, TextCollection, TextGroup, Cursor
|
||||
from vispy.scene.visuals import InfiniteLine, Line
|
||||
|
||||
import numpy as np
|
||||
from vispy.geometry import Rect
|
||||
|
||||
|
@ -103,6 +104,8 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
|
|||
# Keep VisPy canvas happy by letting it be "frozen" again.
|
||||
self.freeze()
|
||||
|
||||
self.graph_event_connect('mouse_wheel', self.on_mouse_scroll)
|
||||
|
||||
# draw a rectangle made out of 4 lines on the canvas to serve as a hint for the work area
|
||||
# all CNC have a limited workspace
|
||||
def draw_workspace(self):
|
||||
|
@ -250,6 +253,43 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
|
|||
self.cursor_v_line.set_data(pos=pos[0], color=self.line_color)
|
||||
self.view.scene.update()
|
||||
|
||||
def on_mouse_scroll(self, event):
|
||||
# key modifiers
|
||||
modifiers = event.modifiers
|
||||
pan_delta_x = self.fcapp.defaults["global_gridx"]
|
||||
pan_delta_y = self.fcapp.defaults["global_gridy"]
|
||||
curr_pos = event.pos
|
||||
|
||||
# Controlled pan by mouse wheel
|
||||
if 'Shift' in modifiers:
|
||||
p1 = np.array(curr_pos)[:2]
|
||||
|
||||
if event.delta[1] > 0:
|
||||
curr_pos[0] -= pan_delta_x
|
||||
else:
|
||||
curr_pos[0] += pan_delta_x
|
||||
p2 = np.array(curr_pos)[:2]
|
||||
self.view.camera.pan(p2 - p1)
|
||||
elif 'Control' in modifiers:
|
||||
p1 = np.array(curr_pos)[:2]
|
||||
|
||||
if event.delta[1] > 0:
|
||||
curr_pos[1] += pan_delta_y
|
||||
else:
|
||||
curr_pos[1] -= pan_delta_y
|
||||
p2 = np.array(curr_pos)[:2]
|
||||
self.view.camera.pan(p2 - p1)
|
||||
|
||||
|
||||
if self.fcapp.grid_status() == True:
|
||||
pos_canvas = self.translate_coords(curr_pos)
|
||||
pos = self.fcapp.geo_editor.snap(pos_canvas[0], pos_canvas[1])
|
||||
|
||||
# Update cursor
|
||||
self.fcapp.app_cursor.set_data(np.asarray([(pos[0], pos[1])]),
|
||||
symbol='++', edge_color=self.fcapp.cursor_color_3D,
|
||||
size=self.fcapp.defaults["global_cursor_size"])
|
||||
|
||||
def new_text_group(self, collection=None):
|
||||
if collection:
|
||||
return TextGroup(collection)
|
||||
|
|
|
@ -133,6 +133,9 @@ class Camera(scene.PanZoomCamera):
|
|||
if event.handled or not self.interactive:
|
||||
return
|
||||
|
||||
# key modifiers
|
||||
modifiers = event.mouse_event.modifiers
|
||||
|
||||
# Limit mouse move events
|
||||
last_event = event.last_event
|
||||
t = time.time()
|
||||
|
@ -147,21 +150,21 @@ class Camera(scene.PanZoomCamera):
|
|||
event.handled = True
|
||||
return
|
||||
|
||||
# Scrolling
|
||||
# ################### Scrolling ##########################
|
||||
BaseCamera.viewbox_mouse_event(self, event)
|
||||
|
||||
if event.type == 'mouse_wheel':
|
||||
center = self._scene_transform.imap(event.pos)
|
||||
scale = (1 + self.zoom_factor) ** (-event.delta[1] * 30)
|
||||
self.limited_zoom(scale, center)
|
||||
if not modifiers:
|
||||
center = self._scene_transform.imap(event.pos)
|
||||
scale = (1 + self.zoom_factor) ** (-event.delta[1] * 30)
|
||||
self.limited_zoom(scale, center)
|
||||
event.handled = True
|
||||
|
||||
elif event.type == 'mouse_move':
|
||||
if event.press_event is None:
|
||||
return
|
||||
|
||||
modifiers = event.mouse_event.modifiers
|
||||
|
||||
# ################ Panning ############################
|
||||
# self.pan_button_setting is actually self.FlatCAM.APP.defaults['global_pan_button']
|
||||
if event.button == int(self.pan_button_setting) and not modifiers:
|
||||
# Translate
|
||||
|
|
|
@ -97,12 +97,16 @@ class ToolMove(FlatCAMTool):
|
|||
sel_obj_list = self.app.collection.get_selected()
|
||||
if sel_obj_list:
|
||||
self.app.inform.emit(_("MOVE: Click on the Start point ..."))
|
||||
|
||||
# if we have an object selected then we can safely activate the mouse events
|
||||
self.mm = self.app.plotcanvas.graph_event_connect('mouse_move', self.on_move)
|
||||
self.mp = self.app.plotcanvas.graph_event_connect('mouse_press', self.on_left_click)
|
||||
self.kr = self.app.plotcanvas.graph_event_connect('key_release', self.on_key_press)
|
||||
|
||||
# draw the selection box
|
||||
self.draw_sel_bbox(obj_list=sel_obj_list)
|
||||
self.draw_sel_bbox()
|
||||
else:
|
||||
self.setVisible(False)
|
||||
# signal that there is no command active
|
||||
self.app.command_active = None
|
||||
self.toggle()
|
||||
self.app.inform.emit('[WARNING_NOTCL] %s' % _("MOVE action cancelled. No object(s) to move."))
|
||||
|
||||
def on_left_click(self, event):
|
||||
|
@ -148,8 +152,9 @@ class ToolMove(FlatCAMTool):
|
|||
dx = pos[0] - self.point1[0]
|
||||
dy = pos[1] - self.point1[1]
|
||||
|
||||
# move only the objects selected and plotted
|
||||
obj_list = [obj for obj in self.app.collection.get_selected() if obj.options['plot']]
|
||||
# move only the objects selected and plotted and visible
|
||||
obj_list = [obj for obj in self.app.collection.get_selected()
|
||||
if obj.options['plot'] and obj.visible is True]
|
||||
|
||||
def job_move(app_obj):
|
||||
with self.app.proc_container.new(_("Moving...")) as proc:
|
||||
|
@ -254,47 +259,40 @@ class ToolMove(FlatCAMTool):
|
|||
self.toggle()
|
||||
return
|
||||
|
||||
def draw_sel_bbox(self, obj_list):
|
||||
def draw_sel_bbox(self):
|
||||
xminlist = []
|
||||
yminlist = []
|
||||
xmaxlist = []
|
||||
ymaxlist = []
|
||||
|
||||
if not obj_list:
|
||||
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Object(s) not selected"))
|
||||
self.toggle()
|
||||
else:
|
||||
# if we have an object selected then we can safely activate the mouse events
|
||||
self.mm = self.app.plotcanvas.graph_event_connect('mouse_move', self.on_move)
|
||||
self.mp = self.app.plotcanvas.graph_event_connect('mouse_press', self.on_left_click)
|
||||
self.kr = self.app.plotcanvas.graph_event_connect('key_release', self.on_key_press)
|
||||
obj_list = self.app.collection.get_selected()
|
||||
|
||||
# first get a bounding box to fit all
|
||||
for obj in obj_list:
|
||||
# don't move disabled objects, move only plotted objects
|
||||
if obj.options['plot']:
|
||||
xmin, ymin, xmax, ymax = obj.bounds()
|
||||
xminlist.append(xmin)
|
||||
yminlist.append(ymin)
|
||||
xmaxlist.append(xmax)
|
||||
ymaxlist.append(ymax)
|
||||
# first get a bounding box to fit all
|
||||
for obj in obj_list:
|
||||
# don't move disabled objects, move only plotted objects
|
||||
if obj.options['plot']:
|
||||
xmin, ymin, xmax, ymax = obj.bounds()
|
||||
xminlist.append(xmin)
|
||||
yminlist.append(ymin)
|
||||
xmaxlist.append(xmax)
|
||||
ymaxlist.append(ymax)
|
||||
|
||||
# get the minimum x,y and maximum x,y for all objects selected
|
||||
xminimal = min(xminlist)
|
||||
yminimal = min(yminlist)
|
||||
xmaximal = max(xmaxlist)
|
||||
ymaximal = max(ymaxlist)
|
||||
# get the minimum x,y and maximum x,y for all objects selected
|
||||
xminimal = min(xminlist)
|
||||
yminimal = min(yminlist)
|
||||
xmaximal = max(xmaxlist)
|
||||
ymaximal = max(ymaxlist)
|
||||
|
||||
p1 = (xminimal, yminimal)
|
||||
p2 = (xmaximal, yminimal)
|
||||
p3 = (xmaximal, ymaximal)
|
||||
p4 = (xminimal, ymaximal)
|
||||
p1 = (xminimal, yminimal)
|
||||
p2 = (xmaximal, yminimal)
|
||||
p3 = (xmaximal, ymaximal)
|
||||
p4 = (xminimal, ymaximal)
|
||||
|
||||
self.old_coords = [p1, p2, p3, p4]
|
||||
self.draw_shape(Polygon(self.old_coords))
|
||||
self.old_coords = [p1, p2, p3, p4]
|
||||
self.draw_shape(Polygon(self.old_coords))
|
||||
|
||||
if self.app.is_legacy is True:
|
||||
self.sel_shapes.redraw()
|
||||
if self.app.is_legacy is True:
|
||||
self.sel_shapes.redraw()
|
||||
|
||||
def update_sel_bbox(self, pos):
|
||||
self.delete_shape()
|
||||
|
|
Loading…
Reference in New Issue