- upgraded the FCButton widget (and made it used everywhere instead of the QPushButton) so it can have the color and font weight properties settable
288 lines
10 KiB
Python
288 lines
10 KiB
Python
|
|
from appTool import *
|
|
|
|
fcTranslate.apply_language('strings')
|
|
if '_' not in builtins.__dict__:
|
|
_ = gettext.gettext
|
|
|
|
|
|
class CircleEditorTool(AppTool):
|
|
"""
|
|
Simple input for buffer distance.
|
|
"""
|
|
|
|
def __init__(self, app, draw_app, plugin_name):
|
|
AppTool.__init__(self, app)
|
|
|
|
self.draw_app = draw_app
|
|
self.decimals = app.decimals
|
|
self._mode = 'add'
|
|
|
|
self.ui = CircleEditorUI(layout=self.layout, circle_class=self)
|
|
self.ui.pluginName = plugin_name
|
|
|
|
self.connect_signals_at_init()
|
|
self.set_tool_ui()
|
|
|
|
def connect_signals_at_init(self):
|
|
# Signals
|
|
self.ui.add_button.clicked.connect(self.on_execute)
|
|
|
|
def run(self):
|
|
self.app.defaults.report_usage("Geo Editor CircleTool()")
|
|
AppTool.run(self)
|
|
|
|
# if the splitter us hidden, display it
|
|
if self.app.ui.splitter.sizes()[0] == 0:
|
|
self.app.ui.splitter.setSizes([1, 1])
|
|
|
|
# if the Tool Tab is hidden display it, else hide it but only if the objectName is the same
|
|
found_idx = None
|
|
for idx in range(self.app.ui.notebook.count()):
|
|
if self.app.ui.notebook.widget(idx).objectName() == "plugin_tab":
|
|
found_idx = idx
|
|
break
|
|
# show the Tab
|
|
if not found_idx:
|
|
try:
|
|
self.app.ui.notebook.addTab(self.app.ui.plugin_tab, self.ui.pluginName)
|
|
except RuntimeError:
|
|
self.app.ui.plugin_tab = QtWidgets.QWidget()
|
|
self.app.ui.plugin_tab.setObjectName("plugin_tab")
|
|
self.app.ui.plugin_tab_layout = QtWidgets.QVBoxLayout(self.app.ui.plugin_tab)
|
|
self.app.ui.plugin_tab_layout.setContentsMargins(2, 2, 2, 2)
|
|
|
|
self.app.ui.plugin_scroll_area = VerticalScrollArea()
|
|
self.app.ui.plugin_tab_layout.addWidget(self.app.ui.plugin_scroll_area)
|
|
self.app.ui.notebook.addTab(self.app.ui.plugin_tab, _("Plugin"))
|
|
|
|
# focus on Tool Tab
|
|
self.app.ui.notebook.setCurrentWidget(self.app.ui.plugin_tab)
|
|
|
|
# self.app.ui.notebook.callback_on_close = self.on_tab_close
|
|
|
|
self.app.ui.notebook.setTabText(2, self.ui.pluginName)
|
|
|
|
def set_tool_ui(self):
|
|
# Init appGUI
|
|
self.ui.x_entry.set_value(0)
|
|
self.ui.y_entry.set_value(0)
|
|
self.ui.radius_x_entry.set_value(0)
|
|
self.ui.radius_y_entry.set_value(0)
|
|
self.ui.angle_entry.set_value(0)
|
|
self.ui.radius_link_btn.setChecked(True)
|
|
self.ui.on_link_checked(True)
|
|
|
|
def on_tab_close(self):
|
|
self.draw_app.select_tool("select")
|
|
self.app.ui.notebook.callback_on_close = lambda: None
|
|
|
|
def on_execute(self):
|
|
if self.mode == 'add':
|
|
self.app.log.info("CircleEditorTool.on_add() -> adding a Circle shape")
|
|
self.on_add()
|
|
else:
|
|
self.app.log.info("RectangleEditorTool.on_add() -> modifying a Circle shape")
|
|
self.draw_app.delete_selected()
|
|
self.on_add()
|
|
self.draw_app.app.inform.emit(_("Click on Center point ..."))
|
|
|
|
def on_add(self):
|
|
origin_x = self.ui.x_entry.get_value()
|
|
origin_y = self.ui.y_entry.get_value()
|
|
radius_x = self.ui.radius_x_entry.get_value()
|
|
radius_y = self.ui.radius_y_entry.get_value()
|
|
angle = self.ui.angle_entry.get_value()
|
|
is_circle = True if self.ui.radius_link_btn.isChecked() else False
|
|
|
|
if radius_x == 0.0 or radius_y == 0.0:
|
|
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed."))
|
|
return
|
|
|
|
if is_circle:
|
|
geo = Point((origin_x, origin_y)).buffer(radius_x)
|
|
else: # 'ellipse'
|
|
circle_geo = Point((origin_x, origin_y)).buffer(1)
|
|
geo = scale(circle_geo, radius_x, radius_y)
|
|
if angle != 0:
|
|
geo = rotate(geo, -angle)
|
|
|
|
added_shapes = self.draw_app.add_shape(geo.exterior)
|
|
for added_shape in added_shapes:
|
|
added_shape.data['type'] = _("Circle")
|
|
self.draw_app.plot_all()
|
|
|
|
def on_clear(self):
|
|
self.set_tool_ui()
|
|
|
|
@property
|
|
def mode(self):
|
|
return self._mode
|
|
|
|
@mode.setter
|
|
def mode(self, val):
|
|
self._mode = val
|
|
if self._mode == 'add':
|
|
# remove selections when adding a new rectangle
|
|
self.draw_app.selected = []
|
|
self.ui.add_button.set_value(_("Add"))
|
|
self.ui.add_button.setIcon(QtGui.QIcon(self.app.resource_location + '/plus16.png'))
|
|
else:
|
|
self.ui.add_button.set_value(_("Apply"))
|
|
self.ui.add_button.setIcon(QtGui.QIcon(self.app.resource_location + '/apply32.png'))
|
|
|
|
@property
|
|
def radius_x(self):
|
|
return self.ui.radius_x_entry.get_value()
|
|
|
|
@radius_x.setter
|
|
def radius_x(self, val):
|
|
self.ui.radius_x_entry.set_value(val)
|
|
|
|
@property
|
|
def radius_y(self):
|
|
return self.ui.radius_y_entry.get_value()
|
|
|
|
@radius_y.setter
|
|
def radius_y(self, val):
|
|
self.ui.radius_y_entry.set_value(val)
|
|
|
|
def hide_tool(self):
|
|
self.ui.circle_frame.hide()
|
|
self.app.ui.notebook.setCurrentWidget(self.app.ui.properties_tab)
|
|
if self.draw_app.active_tool.name != 'select':
|
|
self.draw_app.select_tool("select")
|
|
|
|
|
|
class CircleEditorUI:
|
|
pluginName = _("Circle")
|
|
|
|
def __init__(self, layout, circle_class):
|
|
self.circle_class = circle_class
|
|
self.decimals = self.circle_class.app.decimals
|
|
self.app = self.circle_class.app
|
|
self.layout = layout
|
|
|
|
# Title
|
|
title_label = FCLabel("%s" % ('Editor ' + self.pluginName), size=16, bold=True)
|
|
self.layout.addWidget(title_label)
|
|
|
|
# this way I can hide/show the frame
|
|
self.circle_frame = QtWidgets.QFrame()
|
|
self.circle_frame.setContentsMargins(0, 0, 0, 0)
|
|
self.layout.addWidget(self.circle_frame)
|
|
self.circle_tool_box = QtWidgets.QVBoxLayout()
|
|
self.circle_tool_box.setContentsMargins(0, 0, 0, 0)
|
|
self.circle_frame.setLayout(self.circle_tool_box)
|
|
|
|
# Grid Layout
|
|
grid0 = GLay(v_spacing=5, h_spacing=3)
|
|
self.circle_tool_box.addLayout(grid0)
|
|
|
|
# Position
|
|
self.pos_lbl = FCLabel('%s' % _("Position"), color='red', bold=True)
|
|
grid0.addWidget(self.pos_lbl, 0, 0, 1, 3)
|
|
|
|
# #############################################################################################################
|
|
# Position Frame
|
|
# #############################################################################################################
|
|
pos_frame = FCFrame()
|
|
grid0.addWidget(pos_frame, 2, 0, 1, 2)
|
|
|
|
pos_grid = GLay(v_spacing=5, h_spacing=3)
|
|
pos_frame.setLayout(pos_grid)
|
|
|
|
# X Pos
|
|
self.x_lbl = FCLabel('%s:' % _("X"))
|
|
self.x_entry = FCDoubleSpinner()
|
|
self.x_entry.set_precision(self.decimals)
|
|
self.x_entry.set_range(-10000.0000, 10000.0000)
|
|
pos_grid.addWidget(self.x_lbl, 0, 0)
|
|
pos_grid.addWidget(self.x_entry, 0, 1, 1, 2)
|
|
|
|
# Y Pos
|
|
self.y_lbl = FCLabel('%s:' % _("Y"))
|
|
self.y_entry = FCDoubleSpinner()
|
|
self.y_entry.set_precision(self.decimals)
|
|
self.y_entry.set_range(-10000.0000, 10000.0000)
|
|
pos_grid.addWidget(self.y_lbl, 2, 0)
|
|
pos_grid.addWidget(self.y_entry, 2, 1, 1, 2)
|
|
|
|
# Radius
|
|
self.radius_lbl = FCLabel('%s' % _("Radius"), bold=True, color='blue')
|
|
grid0.addWidget(self.radius_lbl, 4, 0)
|
|
|
|
# #############################################################################################################
|
|
# Radius Frame
|
|
# #############################################################################################################
|
|
rad_frame = FCFrame()
|
|
grid0.addWidget(rad_frame, 6, 0, 1, 2)
|
|
|
|
rad_grid = GLay(v_spacing=5, h_spacing=3)
|
|
rad_frame.setLayout(rad_grid)
|
|
|
|
# Radius X
|
|
self.radius_x_lbl = FCLabel('%s:' % "X")
|
|
self.radius_x_entry = FCDoubleSpinner()
|
|
self.radius_x_entry.set_precision(self.decimals)
|
|
self.radius_x_entry.set_range(0.0000, 10000.0000)
|
|
rad_grid.addWidget(self.radius_x_lbl, 0, 0)
|
|
rad_grid.addWidget(self.radius_x_entry, 0, 1)
|
|
|
|
# Radius Y
|
|
self.radius_y_lbl = FCLabel('%s:' % "Y")
|
|
self.radius_y_entry = FCDoubleSpinner()
|
|
self.radius_y_entry.set_precision(self.decimals)
|
|
self.radius_y_entry.set_range(0.0000, 10000.0000)
|
|
rad_grid.addWidget(self.radius_y_lbl, 1, 0)
|
|
rad_grid.addWidget(self.radius_y_entry, 1, 1)
|
|
|
|
# Angle
|
|
self.angle_lbl = FCLabel('%s:' % _("Angle"))
|
|
self.angle_entry = FCDoubleSpinner()
|
|
self.angle_entry.set_precision(self.decimals)
|
|
self.angle_entry.set_range(-360.0000, 360.0000)
|
|
rad_grid.addWidget(self.angle_lbl, 2, 0)
|
|
rad_grid.addWidget(self.angle_entry, 2, 1)
|
|
|
|
# Radius link
|
|
self.radius_link_btn = QtWidgets.QToolButton()
|
|
self.radius_link_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/link32.png'))
|
|
self.radius_link_btn.setSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding,
|
|
QtWidgets.QSizePolicy.Policy.Expanding)
|
|
self.radius_link_btn.setCheckable(True)
|
|
rad_grid.addWidget(self.radius_link_btn, 0, 2, 3, 1)
|
|
|
|
# Buttons
|
|
self.add_button = FCButton(_("Add"))
|
|
self.add_button.setIcon(QtGui.QIcon(self.app.resource_location + '/plus16.png'))
|
|
grid0.addWidget(self.add_button, 18, 0, 1, 3)
|
|
|
|
GLay.set_common_column_size([grid0, pos_grid, rad_grid], 0)
|
|
|
|
self.layout.addStretch(1)
|
|
|
|
# Note
|
|
self.note_lbl = FCLabel('%s' % _("Note"), bold=True)
|
|
self.layout.addWidget(self.note_lbl)
|
|
self.note_description_lbl = FCLabel('%s' % _("Shift + click to select a shape for modification."))
|
|
self.layout.addWidget(self.note_description_lbl)
|
|
|
|
# Signals
|
|
self.radius_link_btn.clicked.connect(self.on_link_checked)
|
|
|
|
def on_link_checked(self, checked):
|
|
if checked:
|
|
self.radius_x_lbl.set_value('%s:' % _("Value"))
|
|
self.radius_y_lbl.setDisabled(True)
|
|
self.radius_y_entry.setDisabled(True)
|
|
self.radius_y_entry.set_value(self.radius_x_entry.get_value())
|
|
self.angle_lbl.setDisabled(True)
|
|
self.angle_entry.setDisabled(True)
|
|
else:
|
|
self.radius_x_lbl.set_value('%s:' % "X")
|
|
self.radius_y_lbl.setDisabled(False)
|
|
self.radius_y_entry.setDisabled(False)
|
|
self.angle_lbl.setDisabled(False)
|
|
self.angle_entry.setDisabled(False)
|