Skip to content

Commit

Permalink
Issue #74: Contour [Panel] Redesign [Update] 3.7:
Browse files Browse the repository at this point in the history
- Implementation of reverse contour;
- Drag and drop ready, but not working. Actual drag and drop crashes FL;
  • Loading branch information
kateliev committed Mar 15, 2023
1 parent 5b64e62 commit 77e378c
Showing 1 changed file with 69 additions and 25 deletions.
94 changes: 69 additions & 25 deletions Scripts/TypeRig GUI/Panel/Contour.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
global pMode
pLayers = None
pMode = 0
app_name, app_version = 'TypeRig | Contour', '3.6'
app_name, app_version = 'TypeRig | Contour', '3.7'

TRToolFont_path = getTRIconFontPath()
font_loaded = QtGui.QFontDatabase.addApplicationFont(TRToolFont_path)
Expand All @@ -44,6 +44,46 @@ def get_modifier(keyboard_modifier=QtCore.Qt.AltModifier):
modifiers = QtGui.QApplication.keyboardModifiers()
return modifiers == keyboard_modifier

# - Classes ----------------------------
class TRContourClipboardItem(QtGui.QStandardItem):
def __init__(self, *args, **kwargs):
super(TRContourClipboardItem, self).__init__(*args, **kwargs)

# - Init
self.setDropEnabled(False)
self.setSelectable(True)

self._clipboard_data = {}
self._mode_path = False
self.__addon_reversed = ' (Reversed)'

def clone(self):
return self #!!! Ugly hack! But not working, proper clone still crashing the app!!!

def _reverse(self):
tmp_clipboard = {}

for layer, data in self._clipboard_data.items():
new_data = []

if self._mode_path:
tmp_clipboard[layer] = list(reversed(data))
else:
for contour in data:
contour_clone = contour.clone()
contour_clone.reverse()
new_data.append(contour_clone)
tmp_clipboard[layer] = new_data

self._clipboard_data = tmp_clipboard

if self.__addon_reversed in self.text():
new_caption = self.text().replace(self.__addon_reversed, '')
else:
new_caption = self.text() + self.__addon_reversed

self.setText(new_caption)

# - Sub widgets ------------------------
class TRContourBasics(QtGui.QWidget):
def __init__(self):
Expand Down Expand Up @@ -445,15 +485,18 @@ def __init__(self):
super(TRContourCopy, self).__init__()

# - Init
self.contourClipboard = []
lay_main = QtGui.QVBoxLayout()

# -- Listview
self.lst_contours = QtGui.QListView()
self.mod_contours = QtGui.QStandardItemModel(self.lst_contours)
self.mod_contours.setItemPrototype(TRContourClipboardItem())
self.lst_contours.setMinimumHeight(350)

self.lst_contours.setModel(self.mod_contours)
self.lst_contours.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
self.lst_contours.setMinimumHeight(350)
#self.lst_contours.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
self.lst_contours.setDefaultDropAction(QtCore.Qt.MoveAction)

# -- Quick Tool buttons
box_contour_copy = QtGui.QGroupBox()
Expand Down Expand Up @@ -481,9 +524,10 @@ def __init__(self):
lay_contour_copy.addWidget(self.btn_trace)
self.btn_trace.clicked.connect(self.paste_path)

tooltip_button = "Reverse nodes of selected path item"
self.btn_reverse = CustomPushButton("contour_reverse", enabled=False, tooltip=tooltip_button, obj_name='btn_panel')
tooltip_button = "Reverse contours/nodes for selected items"
self.btn_reverse = CustomPushButton("contour_reverse", tooltip=tooltip_button, obj_name='btn_panel')
lay_contour_copy.addWidget(self.btn_reverse)
self.btn_reverse.clicked.connect(self.__reverse_selected)

tooltip_button = "Auto close traced contour"
self.opt_trace_close = CustomPushButton("contour_close", checkable=True, checked=True, tooltip=tooltip_button, obj_name='btn_panel_opt')
Expand All @@ -502,7 +546,6 @@ def __init__(self):
self.setLayout(lay_main)

def __reset(self):
self.contourClipboard = []
self.mod_contours.removeRows(0, self.mod_contours.rowCount())

def __clear_selected(self):
Expand All @@ -511,8 +554,9 @@ def __clear_selected(self):
for idx in gallery_selection:
self.mod_contours.removeRow(idx)

self.contourClipboard = [self.contourClipboard[i] for i in range(len(self.contourClipboard)) if i not in gallery_selection]

def __reverse_selected(self):
for qidx in self.lst_contours.selectedIndexes():
self.lst_contours.model().itemFromIndex(qidx)._reverse()

def __drawIcon(self, contours, foreground='black', background='white'):
# - Init
Expand Down Expand Up @@ -552,7 +596,6 @@ def __drawFontIcon(self, text_string, foreground='black', background='white'):
new_painter = QtGui.QPainter()
new_pixmap = QtGui.QPixmap(draw_dimension, draw_dimension)


# - Paint
new_painter.begin(new_pixmap)
new_painter.setFont(TRFont)
Expand Down Expand Up @@ -606,20 +649,18 @@ def copy_contour(self):
conditional_color = 'blue'

# --- Prepare icon and bank entry

if not partial_path_mode:
draw_contours = [wGlyph.contours()[cid] for cid in selection.keys()]
draw_count = sum([contour.nodesCount for contour in draw_contours])
new_item = QtGui.QStandardItem('Contour: {} Nodes | Source: {}'.format(draw_count, wGlyph.name))
new_item = TRContourClipboardItem('Contour: {} Nodes | Source: {}'.format(draw_count, wGlyph.name))

new_icon = self.__drawIcon(draw_contours, conditional_color)
else:
draw_count = sum([len(value) for value in selection.values()])
new_item = QtGui.QStandardItem('Path: {} Nodes | Source: {}'.format(draw_count, wGlyph.name))
new_item = TRContourClipboardItem('Path: {} Nodes | Source: {}'.format(draw_count, wGlyph.name))
new_icon = self.__drawFontIcon('node_trace', conditional_color)

new_item.setIcon(new_icon)
new_item.setSelectable(True)
self.mod_contours.appendRow(new_item)

# -- Add to clipboard
Expand All @@ -637,17 +678,20 @@ def copy_contour(self):
contour_nodes = all_contours[cid].nodes()
new_nodes += [contour_nodes[nid].clone() for nid in node_list]

export_clipboard[layer_name].append(new_nodes)
export_clipboard[layer_name] = new_nodes


self.contourClipboard.append(export_clipboard)
# - Set clipboard data
new_item._clipboard_data = export_clipboard
new_item._mode_path = partial_path_mode

output(0, app_name, 'Copy contours; Glyph: %s; Layers: %s.' %(wGlyph.name, '; '.join(process_layers)))

def paste_contour(self):
# - Init
wGlyph = eGlyph()
wLayers = wGlyph._prepareLayers(pLayers)
gallery_selection = [qidx.row() for qidx in self.lst_contours.selectedIndexes()]
gallery_selection = [self.lst_contours.model().itemFromIndex(qidx) for qidx in self.lst_contours.selectedIndexes()]

# - Helper
def add_new_shape(layer, contours):
Expand All @@ -656,9 +700,9 @@ def add_new_shape(layer, contours):
layer.addShape(newShape)

# - Process
if len(self.contourClipboard) and len(gallery_selection):
for idx in gallery_selection:
paste_data = self.contourClipboard[idx]
if len(gallery_selection):
for clipboard_item in gallery_selection:
paste_data = clipboard_item._clipboard_data

for layerName, contours in paste_data.items():
wLayer = wGlyph.layer(layerName)
Expand Down Expand Up @@ -688,7 +732,7 @@ def paste_path(self):
# - Init
wGlyph = eGlyph()
wLayers = wGlyph._prepareLayers(pLayers)
gallery_selection = [qidx.row() for qidx in self.lst_contours.selectedIndexes()]
gallery_selection = [self.lst_contours.model().itemFromIndex(qidx) for qidx in self.lst_contours.selectedIndexes()]

# - Helper
def add_new_shape(layer, contours):
Expand All @@ -697,20 +741,20 @@ def add_new_shape(layer, contours):
layer.addShape(newShape)

# - Process
if len(self.contourClipboard) and len(gallery_selection):
if len(gallery_selection):
combined_data = {}

for idx in gallery_selection:
for layer_name, contours in self.contourClipboard[idx].items():
for clipboard_item in gallery_selection:
for layer_name, contours in clipboard_item._clipboard_data.items():
combined_data.setdefault(layer_name, []).extend(contours)

for layer_name, nodes in combined_data.items():
wLayer = wGlyph.layer(layer_name)

if wLayer is not None:
# - Process nodes
flat_nodes = [node.clone() for node in sum(nodes,[])]
new_contour = fl6.flContour(flat_nodes)
cloned_nodes = [node.clone() for node in nodes]
new_contour = fl6.flContour(cloned_nodes)
new_contour.closed = self.opt_trace_close.isChecked()

# - Insert contours into currently selected shape
Expand Down

0 comments on commit 77e378c

Please sign in to comment.