#!/usr/bin/env python3 import PyQt5.QtWidgets as Qw import PyQt5.QtGui as Qg import PyQt5.QtCore as Qc import xasy2asy as x2a from xasyTransform import xasyTransform as xT class AnotherWindow(Qw.QWidget): def __init__(self, shape, parent): super().__init__() self.shape = shape self.parent = parent self.newShape = self.shape self.layout = Qw.QVBoxLayout(self) # Initialize tab screen self.tabs = Qw.QTabWidget() self.fillTab = Qw.QWidget() self.lineTab = Qw.QWidget() self.arrowTab = Qw.QWidget() self.othersTab = Qw.QWidget() self.tabs.resize(300,200) self.fillTab.layout = Qw.QVBoxLayout(self.fillTab) self.lineTab.layout = Qw.QVBoxLayout(self.lineTab) self.arrowTab.layout = Qw.QVBoxLayout(self.arrowTab) self.othersTab.layout = Qw.QVBoxLayout(self.othersTab) self.tabs.addTab(self.fillTab,"Fill Options") self.tabs.addTab(self.lineTab,"Line Options") self.tabs.addTab(self.arrowTab,"Arrow Options") self.tabs.addTab(self.othersTab,"Misc. Options") self.layout.addWidget(self.tabs) self.setLayout(self.layout) self.setWindowTitle("Shape Options Window") self.label = Qw.QLabel("Fill:") self.fillTab.layout.addWidget(self.label) self.fillButton = Qw.QComboBox() self.fillButton.addItem("Unfilled") self.fillButton.addItem("Filled") self.fillButton.currentIndexChanged.connect(self.fillChange) self.fillTab.layout.addWidget(self.fillButton) if isinstance(self.shape, x2a.asyArrow): self.colorButton = Qw.QPushButton("Set Line Colour") self.colorButton.clicked.connect(self.pickColor) self.fillTab.layout.addWidget(self.colorButton) self.colorButton = Qw.QPushButton("Set Fill Colour") self.colorButton.clicked.connect(self.pickFillColor) self.fillTab.layout.addWidget(self.colorButton) elif isinstance(self.shape, x2a.xasyShape): self.colorButton = Qw.QPushButton("Set Colour") self.colorButton.clicked.connect(self.pickColor) self.fillTab.layout.addWidget(self.colorButton) self.label = Qw.QLabel("Reflection:") self.othersTab.layout.addWidget(self.label) self.reflectionButton = Qw.QComboBox() self.reflectionButton.addItem("None") self.reflectionButton.addItem("Horizontal") self.reflectionButton.addItem("Vertical") self.reflectionButton.currentIndexChanged.connect(self.reflectionChange) self.othersTab.layout.addWidget(self.reflectionButton) self.label = Qw.QLabel("Opacity:") self.othersTab.layout.addWidget(self.label) self.opacityBox = Qw.QLineEdit() self.othersTab.layout.addWidget(self.opacityBox) self.opacityBox.setPlaceholderText(str(self.shape.pen.opacity)) self.label = Qw.QLabel("Arrowhead:") self.arrowTab.layout.addWidget(self.label) self.arrowheadButton = Qw.QComboBox() self.arrowList = ["None","Arrow","ArcArrow"] for arrowMode in self.arrowList: self.arrowheadButton.addItem(arrowMode) self.arrowheadButton.currentIndexChanged.connect(self.arrowheadChange) self.arrowTab.layout.addWidget(self.arrowheadButton) self.label = Qw.QLabel("Line Style:") self.lineTab.layout.addWidget(self.label) self.linestyleButton = Qw.QComboBox() self.lineList = ["solid","dashed","dotted","dashdotted"] for lineMode in self.lineList: self.linestyleButton.addItem(lineMode) self.linestyleButton.currentIndexChanged.connect(self.linestyleChange) self.lineTab.layout.addWidget(self.linestyleButton) self.linestyleButton.setCurrentIndex(self.lineList.index(self.shape.pen.style)) self.label = Qw.QLabel("Line Cap Style:") self.lineTab.layout.addWidget(self.label) self.lineCapStyleButton = Qw.QComboBox() self.lineCapListStrings = ["extendcap","flatcap","roundcap"] #Is there a way to pull these directly self.lineCapList = [Qc.Qt.PenCapStyle.SquareCap,Qc.Qt.PenCapStyle.FlatCap,Qc.Qt.PenCapStyle.RoundCap] for lineMode in self.lineCapListStrings: self.lineCapStyleButton.addItem(lineMode) self.lineCapStyleButton.currentIndexChanged.connect(self.lineCapStyleChange) self.lineTab.layout.addWidget(self.lineCapStyleButton) self.lineCapStyleButton.setCurrentIndex(self.lineCapList.index(self.shape.pen.capStyle)) #TODO: Make this a function. if not isinstance(self.shape, x2a.xasyShape): self.fillButton.setCurrentIndex(int(self.shape.arrowSettings["fill"])) if isinstance(self.shape, x2a.asyArrow): self.arrowheadButton.setCurrentIndex(int(self.shape.arrowSettings["active"])) else: self.arrowheadButton.setDisabled(True) else: self.fillButton.setCurrentIndex(int(self.shape.path.fill)) if isinstance(self.shape, x2a.asyArrow) and self.shape.arrowSettings["active"]: #Make these all a list or something. self.label = Qw.QLabel("Arrow Style:") self.arrowTab.layout.addWidget(self.label) self.arrowstyleButton = Qw.QComboBox() for arrowStyle in self.shape.arrowStyleList: self.arrowstyleButton.addItem(arrowStyle if arrowStyle else "(default)") self.arrowstyleButton.currentIndexChanged.connect(self.arrowstyleChange) self.arrowTab.layout.addWidget(self.arrowstyleButton) self.label = Qw.QLabel("Arrow Size:") self.arrowTab.layout.addWidget(self.label) self.arrowSizeBox = Qw.QLineEdit() self.arrowTab.layout.addWidget(self.arrowSizeBox) self.arrowSizeBox.setPlaceholderText(self.getInfo("DefaultHead.size(currentpen)")) self.label = Qw.QLabel("Arrow Angle:") self.arrowTab.layout.addWidget(self.label) self.arrowAngleBox = Qw.QLineEdit() self.arrowTab.layout.addWidget(self.arrowAngleBox) self.arrowAngleBox.setPlaceholderText(self.getInfo("arrowangle")) self.label = Qw.QLabel("Arrow Fill:") self.arrowTab.layout.addWidget(self.label) self.arrowFillButton = Qw.QComboBox() for arrowFillStyle in self.shape.arrowFillList: self.arrowFillButton.addItem(arrowFillStyle if arrowFillStyle else "(default)") self.arrowFillButton.currentIndexChanged.connect(self.arrowFillChange) self.arrowTab.layout.addWidget(self.arrowFillButton) self.arrowstyleButton.setCurrentIndex(int(self.shape.arrowSettings["style"])) self.arrowFillButton.setCurrentIndex(int(self.shape.arrowSettings["fill"])) self.fillTab.setLayout(self.fillTab.layout) self.lineTab.setLayout(self.lineTab.layout) self.arrowTab.setLayout(self.arrowTab.layout) self.othersTab.setLayout(self.othersTab.layout) self.confirmButton = Qw.QPushButton("Render") self.confirmButton.clicked.connect(self.renderChanges) self.layout.addWidget(self.confirmButton) def arrowheadChange(self, i): #None, {Arrow, ArcArrow} x {(),(SimpleHead),(HookHead),(TeXHead)} if isinstance(self.shape, x2a.xasyShape): if i != 0: if isinstance(self.newShape,x2a.asyArrow): self.newShape.arrowSettings["active"] = i else: self.newShape = self.shape.arrowify(arrowhead=i) else: self.newShape.arrowSettings["active"] = i #Simplify the logic def arrowstyleChange(self, i): self.newShape.arrowSettings["style"] = i def linestyleChange(self, i): #I think add an attribute to asyPen self.shape.pen.setStyle(self.lineList[i]) def lineCapStyleChange(self, i): #I think add an attribute to asyPen self.shape.pen.setCapStyle(self.lineCapList[i]) def fillChange(self, i): if isinstance(self.shape, x2a.asyArrow): self.shape.arrowSettings["fill"] = bool(i) elif (self.shape.path.fill != bool(i)) and not isinstance(self.newShape, x2a.asyArrow): if self.newShape: self.newShape = self.newShape.swapFill() if isinstance(self.newShape, x2a.asyArrow): self.newShape.arrowSettings["fill"] = bool(i) def reflectionChange(self, i): #TODO: Modernize this. reflectionList = [[1,1],[1,-1],[-1,1]] self.parent.newTransform = xT.makeScaleTransform(*reflectionList[i], self.parent.currentAnchor).toQTransform() self.parent.currentlySelectedObj['selectedIndex'] = self.parent.mostRecentObject self.parent.releaseTransform() self.parent.newTransform = Qg.QTransform() def sizeChange(self): try: newSize = self.arrowSizeBox.text() self.newShape.arrowSettings["size"] = float(newSize) except: return #TODO: Show error message. def angleChange(self): #Refactor this with the above. try: newAngle = self.arrowAngleBox.text() self.newShape.arrowSettings["angle"] = float(newAngle) except: return #TODO: Show error message. def arrowFillChange(self, i): #Can I lambda this? self.newShape.arrowSettings["fill"] = i def opacityChange(self): newOpacity = self.opacityBox.text() try: newOpacity = int(newOpacity) if newOpacity >= 0 and newOpacity <= 255: self.shape.pen.setOpacity(newOpacity) self.newShape.pen.setOpacity(newOpacity) except: pass def renderChanges(self): #Pull from text boxes here. self.opacityChange() if isinstance(self.shape, x2a.asyArrow) and self.shape.arrowSettings["active"]: self.sizeChange() self.angleChange() elif (not isinstance(self.shape, x2a.asyArrow)): self.renderLineStyle() if self.newShape: self.parent.replaceObject(self.parent.contextWindowObject,self.newShape) self.parent.terminateContextWindow() def getInfo(self,value): """ Find out the size of an arbitrary Asymptote pen """ self.asyEngine = self.parent.asyEngine assert isinstance(self.asyEngine, x2a.AsymptoteEngine) assert self.asyEngine.active fout = self.asyEngine.ostream fin = self.asyEngine.istream fout.write("write(_outpipe,{},endl);\n".format(value)) fout.write(self.asyEngine.xasy) fout.flush() return fin.readline() def getPattern(self,pattern,path): """ Find out the adjusted pattern of an Asymptote pen """ self.asyEngine = self.parent.asyEngine assert isinstance(self.asyEngine, x2a.AsymptoteEngine) assert self.asyEngine.active fout = self.asyEngine.ostream fin = self.asyEngine.istream #fout.write("pen p=adjust({pattern},arclength({path}),cyclic({path}));\n") #print(f"write(_outpipe,adjust({pattern},arclength({path}),cyclic({path})),endl);\n") fout.write(f"write(_outpipe,adjust({pattern},arclength({path}),cyclic({path})),endl);\n") fout.write(self.asyEngine.xasy) fout.flush() return fin.readline() def renderLineStyle(self): #Should only get called with asy shapes if not self.newShape: self.newShape=self.shape if not isinstance(self.newShape,x2a.asyArrow): rawPattern = self.getPattern(self.lineList[self.linestyleButton.currentIndex()],self.newShape.path.getCode()) else: #self.newShape.updateCode() #idk if this is necessary. rawPattern = self.getPattern(self.lineList[self.linestyleButton.currentIndex()],self.newShape.code) pattern = [] if len(rawPattern) == 5: pattern=[1,0] else: for value in rawPattern[2:-3].split(' '): pattern.append(float(value)+1) try: self.newShape.pen.setDashPattern(pattern) #pen is going to be a asyPen, add as an attribute except: print("Pen format error") def pickColor(self): self.colorDialog = Qw.QColorDialog(x2a.asyPen.convertToQColor(self.shape.pen.color), self) self.colorDialog.show() result = self.colorDialog.exec() if result == Qw.QDialog.Accepted: self.shape.pen.setColorFromQColor(self.colorDialog.selectedColor()) self.parent.updateFrameDispColor() def pickFillColor(self): #This is a copy of the above, how do you set the var as it is set? self.colorDialog = Qw.QColorDialog(x2a.asyPen.convertToQColor(self.shape.fillPen.color), self) self.colorDialog.show() result = self.colorDialog.exec() if result == Qw.QDialog.Accepted: self.shape.fillPen.setColorFromQColor(self.colorDialog.selectedColor()) self.parent.updateFrameDispColor() @Qc.pyqtSlot() def on_click(self): print("\n") for currentQTableWidgetItem in self.tableWidget.selectedItems(): print(currentQTableWidgetItem.row(), currentQTableWidgetItem.column(), currentQTableWidgetItem.text())