| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- # ########################################################## ##
- # FlatCAM: 2D Post-processing for Manufacturing #
- # http://flatcam.org #
- # Author: Juan Pablo Caram (c) #
- # Date: 2/5/2014 #
- # MIT Licence #
- # ########################################################## ##
- from PyQt5 import QtGui, QtCore, QtWidgets, QtWidgets
- from PyQt5.QtCore import Qt
- from shapely.geometry import Polygon, LineString
- import gettext
- import FlatCAMTranslation as fcTranslate
- import builtins
- fcTranslate.apply_language('strings')
- if '_' not in builtins.__dict__:
- _ = gettext.gettext
- class FlatCAMTool(QtWidgets.QWidget):
- toolName = "FlatCAM Generic Tool"
- def __init__(self, app, parent=None):
- """
- :param app: The application this tool will run in.
- :type app: App
- :param parent: Qt Parent
- :return: FlatCAMTool
- """
- self.app = app
- self.decimals = app.decimals
- QtWidgets.QWidget.__init__(self, parent)
- # self.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
- self.layout = QtWidgets.QVBoxLayout()
- self.setLayout(self.layout)
- self.menuAction = None
- def install(self, icon=None, separator=None, shortcut=None, **kwargs):
- before = None
- # 'pos' is the menu where the Action has to be installed
- # if no 'pos' kwarg is provided then by default our Action will be installed in the menutool
- # as it previously was
- if 'pos' in kwargs:
- pos = kwargs['pos']
- else:
- pos = self.app.ui.menutool
- # 'before' is the Action in the menu stated by 'pos' kwarg, before which we want our Action to be installed
- # if 'before' kwarg is not provided, by default our Action will be added in the last place.
- if 'before' in kwargs:
- before = (kwargs['before'])
- # create the new Action
- self.menuAction = QtWidgets.QAction(self)
- # if provided, add an icon to this Action
- if icon is not None:
- self.menuAction.setIcon(icon)
- # set the text name of the Action, which will be displayed in the menu
- if shortcut is None:
- self.menuAction.setText(self.toolName)
- else:
- self.menuAction.setText(self.toolName + '\t%s' % shortcut)
- # add a ToolTip to the new Action
- # self.menuAction.setToolTip(self.toolTip) # currently not available
- # insert the action in the position specified by 'before' and 'pos' kwargs
- pos.insertAction(before, self.menuAction)
- # if separator parameter is True add a Separator after the newly created Action
- if separator is True:
- pos.addSeparator()
- self.menuAction.triggered.connect(self.run)
- def run(self):
- if self.app.tool_tab_locked is True:
- return
- # Remove anything else in the GUI
- self.app.ui.tool_scroll_area.takeWidget()
- # Put ourself in the GUI
- self.app.ui.tool_scroll_area.setWidget(self)
- # Switch notebook to tool page
- self.app.ui.notebook.setCurrentWidget(self.app.ui.tool_tab)
- # Set the tool name as the widget object name
- self.app.ui.tool_scroll_area.widget().setObjectName(self.toolName)
- self.show()
- def draw_tool_selection_shape(self, old_coords, coords, **kwargs):
- """
- :param old_coords: old coordinates
- :param coords: new coordinates
- :param kwargs:
- :return:
- """
- if 'shapes_storage' in kwargs:
- s_storage = kwargs['shapes_storage']
- else:
- s_storage = self.app.tool_shapes
- if 'color' in kwargs:
- color = kwargs['color']
- else:
- color = self.app.defaults['global_sel_line']
- if 'face_color' in kwargs:
- face_color = kwargs['face_color']
- else:
- face_color = self.app.defaults['global_sel_fill']
- if 'face_alpha' in kwargs:
- face_alpha = kwargs['face_alpha']
- else:
- face_alpha = 0.3
- x0, y0 = old_coords
- x1, y1 = coords
- pt1 = (x0, y0)
- pt2 = (x1, y0)
- pt3 = (x1, y1)
- pt4 = (x0, y1)
- sel_rect = Polygon([pt1, pt2, pt3, pt4])
- # color_t = Color(face_color)
- # color_t.alpha = face_alpha
- color_t = face_color[:-2] + str(hex(int(face_alpha * 255)))[2:]
- s_storage.add(sel_rect, color=color, face_color=color_t, update=True, layer=0, tolerance=None)
- if self.app.is_legacy is True:
- s_storage.redraw()
- def draw_selection_shape_polygon(self, points, **kwargs):
- """
- :param points: a list of points from which to create a Polygon
- :param kwargs:
- :return:
- """
- if 'shapes_storage' in kwargs:
- s_storage = kwargs['shapes_storage']
- else:
- s_storage = self.app.tool_shapes
- if 'color' in kwargs:
- color = kwargs['color']
- else:
- color = self.app.defaults['global_sel_line']
- if 'face_color' in kwargs:
- face_color = kwargs['face_color']
- else:
- face_color = self.app.defaults['global_sel_fill']
- if 'face_alpha' in kwargs:
- face_alpha = kwargs['face_alpha']
- else:
- face_alpha = 0.3
- if len(points) < 3:
- sel_rect = LineString(points)
- else:
- sel_rect = Polygon(points)
- # color_t = Color(face_color)
- # color_t.alpha = face_alpha
- color_t = face_color[:-2] + str(hex(int(face_alpha * 255)))[2:]
- s_storage.add(sel_rect, color=color, face_color=color_t, update=True, layer=0, tolerance=None)
- if self.app.is_legacy is True:
- s_storage.redraw()
- def delete_tool_selection_shape(self, **kwargs):
- """
- :param kwargs:
- :return:
- """
- if 'shapes_storage' in kwargs:
- s_storage = kwargs['shapes_storage']
- else:
- s_storage = self.app.tool_shapes
- s_storage.clear()
- s_storage.redraw()
- def draw_moving_selection_shape_poly(self, points, data, **kwargs):
- """
- :param points:
- :param data:
- :param kwargs:
- :return:
- """
- if 'shapes_storage' in kwargs:
- s_storage = kwargs['shapes_storage']
- else:
- s_storage = self.app.move_tool.sel_shapes
- if 'color' in kwargs:
- color = kwargs['color']
- else:
- color = self.app.defaults['global_sel_line']
- if 'face_color' in kwargs:
- face_color = kwargs['face_color']
- else:
- face_color = self.app.defaults['global_sel_fill']
- if 'face_alpha' in kwargs:
- face_alpha = kwargs['face_alpha']
- else:
- face_alpha = 0.3
- temp_points = [x for x in points]
- try:
- if data != temp_points[-1]:
- temp_points.append(data)
- except IndexError:
- return
- l_points = len(temp_points)
- if l_points == 2:
- geo = LineString(temp_points)
- elif l_points > 2:
- geo = Polygon(temp_points)
- else:
- return
- color_t = face_color[:-2] + str(hex(int(face_alpha * 255)))[2:]
- color_t_error = "#00000000"
- if geo.is_valid and not geo.is_empty:
- s_storage.add(geo, color=color, face_color=color_t, update=True, layer=0, tolerance=None)
- elif not geo.is_valid:
- s_storage.add(geo, color="red", face_color=color_t_error, update=True, layer=0, tolerance=None)
- if self.app.is_legacy is True:
- s_storage.redraw()
- def delete_moving_selection_shape(self, **kwargs):
- """
- :param kwargs:
- :return:
- """
- if 'shapes_storage' in kwargs:
- s_storage = kwargs['shapes_storage']
- else:
- s_storage = self.app.move_tool.sel_shapes
- s_storage.clear()
- s_storage.redraw()
- def confirmation_message(self, accepted, minval, maxval):
- if accepted is False:
- self.app.inform.emit('[WARNING_NOTCL] %s: [%.*f, %.*f]' %
- (_("Edited value is out of range"), self.decimals, minval, self.decimals, maxval))
- else:
- self.app.inform.emit('[success] %s' % _("Edited value is within limits."))
- def confirmation_message_int(self, accepted, minval, maxval):
- if accepted is False:
- self.app.inform.emit('[WARNING_NOTCL] %s: [%d, %d]' %
- (_("Edited value is out of range"), minval, maxval))
- else:
- self.app.inform.emit('[success] %s' % _("Edited value is within limits."))
- def sizeHint(self):
- """
- I've overloaded this just in case I will need to make changes in the future to enforce dimensions
- :return:
- """
- default_hint_size = super(FlatCAMTool, self).sizeHint()
- return QtCore.QSize(default_hint_size.width(), default_hint_size.height())
|