summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/asymptote/GUI/xasyMainWin.py
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/asymptote/GUI/xasyMainWin.py')
-rwxr-xr-xMaster/texmf-dist/asymptote/GUI/xasyMainWin.py1748
1 files changed, 0 insertions, 1748 deletions
diff --git a/Master/texmf-dist/asymptote/GUI/xasyMainWin.py b/Master/texmf-dist/asymptote/GUI/xasyMainWin.py
deleted file mode 100755
index b0549e72f9c..00000000000
--- a/Master/texmf-dist/asymptote/GUI/xasyMainWin.py
+++ /dev/null
@@ -1,1748 +0,0 @@
-#!/usr/bin/env python
-###########################################################################
-#
-# xasyMainWin implements the functionality of the GUI. It depends on
-# xasy2asy for its interaction with Asymptote.
-#
-#
-# Author: Orest Shardt
-# Created: June 29, 2007
-#
-###########################################################################
-
-import os
-import sys
-from string import *
-import subprocess
-import math
-import copy
-
-if sys.version_info >= (3, 0):
- # python3
- from tkinter import *
- from tkinter import filedialog, messagebox, simpledialog
-else:
- # python2
- # from Tkinter import *
- import tkFileDialog as filedialog
- import tkMessageBox as messagebox
- import tkSimpleDialog as simpledialog
-
-import threading
-import time
-
-from xasyVersion import xasyVersion
-import xasyCodeEditor
-from xasy2asy import *
-import xasyFile
-import xasyOptions
-import xasyOptionsDialog
-import CubicBezier
-from xasyBezierEditor import xasyBezierEditor
-from xasyGUIIcons import iconB64
-from xasyColorPicker import *
-
-from UndoRedoStack import *
-from xasyActions import *
-
-import string
-
-try:
- from PIL import ImageTk
- from PIL import Image
- PILAvailable = True
-except:
- PILAvailable = False
-
-class xasyMainWin:
- def __init__(self,master,file=None,magnification=1.0):
- self.opLock = threading.Lock()
- self.parent = master
- self.magnification = magnification
- self.previousZoom = self.magnification
- self.magList = [0.1,0.25,1.0/3,0.5,1,2,3,4,5,10]
- self.bindGlobalEvents()
- self.createWidgets()
- self.resetGUI()
- site=""
- if not PILAvailable:
- messagebox.showerror("Failed Dependencies","An error occurred loading the required PIL library. Please install Pillow from http://pypi.python.org/pypi/Pillow")
- self.parent.destroy()
- sys.exit(1)
- if file != None:
- self.loadFile(file)
- self.parent.after(100,self.tickHandler)
-
- def testOrAcquireLock(self):
- val = self.opLock.acquire(False)
- if val:
- self.closeDisplayLock()
- return val
-
- def acquireLock(self):
- self.closeDisplayLock()
- self.opLock.acquire()
-
- def releaseLock(self):
- self.opLock.release()
- self.openDisplayLock()
-
- def tickHandler(self):
- self.tickCount += 1
- self.mainCanvas.itemconfigure("outlineBox",dashoffset=self.tickCount%9)
- self.parent.after(100,self.tickHandler)
-
- def closeDisplayLock(self):
- self.status.config(text="Busy")
- self.parent.update_idletasks()
-
- def openDisplayLock(self):
- self.status.config(text="Ready")
-
- def bindGlobalEvents(self):
- #global bindings
- self.parent.bind_all("<Control-z>",lambda q:self.editUndoCmd())# z -> no shift
- self.parent.bind_all("<Control-Z>",lambda q:self.editRedoCmd())# Z -> with shift
- self.parent.bind_all("<Control-o>",lambda q:self.fileOpenCmd())
- self.parent.bind_all("<Control-n>",lambda q:self.fileNewCmd())
- self.parent.bind_all("<Control-s>",lambda q:self.fileSaveCmd())
- self.parent.bind_all("<Control-q>",lambda q:self.fileExitCmd())
- self.parent.bind_all("<F1>",lambda q:self.helpHelpCmd())
-
- def unbindGlobalEvents(self):
- #global bindings
- self.parent.unbind("<Control-z>")
- self.parent.unbind("<Control-Z>")
- self.parent.unbind("<Control-o>")
- self.parent.unbind("<Control-n>")
- self.parent.unbind("<Control-s>")
- self.parent.unbind("<Control-q>")
- self.parent.unbind("<F1>")
-
- def createWidgets(self):
- #first some configuration
- self.parent.geometry("800x600")
- self.parent.title("Xasy")
- self.parent.resizable(True,True)
-
- #try to capture the closing of the window
- #find a better way to do this since the widgets may
- #already be destroyed when this is called
- self.parent.protocol("WM_DELETE_WINDOW",self.canQuit)
-
- #the main menu
- self.mainMenu = Menu(self.parent)
- self.parent.config(menu=self.mainMenu)
-
- #the file menu
- self.fileMenu = Menu(self.mainMenu,tearoff=0)
- self.fileMenu.add_command(label="New",command=self.fileNewCmd,accelerator="Ctrl+N",underline=0)
- self.fileMenu.add_command(label="Open",command=self.fileOpenCmd,accelerator="Ctrl+O",underline=0)
- self.fileMenu.add_separator()
- self.fileMenu.add_command(label="Save",command=self.fileSaveCmd,accelerator="Ctrl+S",underline=0)
- self.fileMenu.add_command(label="Save As",command=self.fileSaveAsCmd,underline=5)
- self.fileMenu.add_separator()
-
- #an export menu
- self.exportMenu = Menu(self.fileMenu,tearoff=0)
- self.exportMenu.add_command(label="EPS...",command=self.exportEPS,underline=0)
- self.exportMenu.add_command(label="PDF...",command=self.exportPDF,underline=0)
- self.exportMenu.add_command(label="GIF...",command=self.exportGIF,underline=0)
- self.exportMenu.add_command(label="PNG...",command=self.exportPNG,underline=1)
- self.exportMenu.add_command(label="SVG...",command=self.exportSVG,underline=0)
- self.fileMenu.add_cascade(label="Export",menu=self.exportMenu,underline=1)
- self.fileMenu.add_separator()
-
- self.fileMenu.add_command(label="Quit",command=self.fileExitCmd,accelerator="Ctrl+Q",underline=0)
-
- self.mainMenu.add_cascade(label="File",menu=self.fileMenu,underline=0)
-
- #the edit menu
- self.editMenu = Menu(self.mainMenu,tearoff=0)
- self.editMenu.add_command(label="Undo",command=self.editUndoCmd,accelerator="Ctrl+Z",underline=0)
- self.editMenu.add_command(label="Redo",command=self.editRedoCmd,accelerator="Shift+Ctrl+Z",underline=0)
- self.mainMenu.add_cascade(label="Edit",menu=self.editMenu,underline=0)
-
- #the tools menu
- self.toolsMenu = Menu(self.mainMenu,tearoff=0)
- self.mainMenu.add_cascade(label="Tools",menu=self.toolsMenu,underline=0)
-
- #the options menu
- self.optionsMenu = Menu(self.toolsMenu,tearoff=0)
- self.toolsMenu.add_cascade(label="Options",menu=self.optionsMenu,underline=0)
- self.optionsMenu.add_command(label="Edit...",command=self.editOptions,underline=0)
- self.optionsMenu.add_command(label="Reset defaults",command=self.resetOptions,underline=6)
-
- #the help menu
- self.helpMenu = Menu(self.mainMenu,tearoff=0)
- self.helpMenu.add_command(label="Help",command=self.helpHelpCmd,state=DISABLED,accelerator="F1",underline=0)
- self.helpMenu.add_command(label="Asymptote Documentation",command=self.helpAsyDocCmd,underline=10)
- self.helpMenu.add_separator()
- self.helpMenu.add_command(label="About xasy",command=self.helpAboutCmd,underline=0)
- self.mainMenu.add_cascade(label="Help",menu=self.helpMenu,underline=0)
-
- #status bar
- self.statusBar = Frame(self.parent,relief=FLAT)
-
- self.magVal = DoubleVar()
- self.magVal.set(round(100*self.magnification,1))
- self.magVal.trace('w',self.zoomViewCmd)
- zoomList = self.magList
- if self.magnification not in zoomList:
- zoomList.append(self.magnification)
- zoomList.sort()
- zoomList = [round(100*i,1) for i in zoomList]
- self.zoomMenu = OptionMenu(self.statusBar,self.magVal,*zoomList)
- self.zoomMenu.pack(side=RIGHT)
- Label(self.statusBar,text="Zoom:",anchor=E,width=7).pack(side=RIGHT)
-
- self.coords = Label(self.statusBar,text="(0,0)",relief=SUNKEN,anchor=W)
- self.coords.pack(side=RIGHT,anchor=S)
- self.status = Label(self.statusBar,text="Ready",relief=SUNKEN,anchor=W)
- self.status.pack(side=RIGHT,fill=X,expand=1,anchor=SW)
- self.statusBar.pack(side=BOTTOM,fill=X)
-
- #toolbar for transformation, drawing, and adjustment commands
- self.toolBar = Frame(self.parent,relief=FLAT,borderwidth=3)
-
- #let's load some images
- self.toolIcons = {}
- for x in iconB64.keys():
- self.toolIcons[x] = PhotoImage(data=iconB64[x])
-
- self.transformLbl = Label(self.toolBar,text="",anchor=W)
- self.transformLbl.grid(row=0,column=0,columnspan=2,sticky=W)
- self.toolSelectButton = Button(self.toolBar,command=self.toolSelectCmd,image=self.toolIcons["select"])
- self.toolSelectButton.grid(row=1,column=0,sticky=N+S+E+W)
- self.toolMoveButton = Button(self.toolBar,command=self.toolMoveCmd,image=self.toolIcons["move"])
- self.toolMoveButton.grid(row=2,column=0,sticky=N+S+E+W)
- self.toolRotateButton = Button(self.toolBar,command=self.toolRotateCmd,image=self.toolIcons["rotate"])
- self.toolRotateButton.grid(row=2,column=1,sticky=N+S+E+W)
- self.toolVertiMoveButton = Button(self.toolBar,command=self.toolVertiMoveCmd,image=self.toolIcons["vertiMove"])
- self.toolVertiMoveButton.grid(row=3,column=0,sticky=N+S+E+W)
- self.toolHorizMoveButton = Button(self.toolBar,command=self.toolHorizMoveCmd,image=self.toolIcons["horizMove"])
- self.toolHorizMoveButton.grid(row=3,column=1,sticky=N+S+E+W)
-
- self.drawLbl = Label(self.toolBar,text="",anchor=W)
- self.drawLbl.grid(row=4,column=0,columnspan=2,sticky=W)
- self.toolDrawLinesButton = Button(self.toolBar,command=self.toolDrawLinesCmd,image=self.toolIcons["drawLines"])
- self.toolDrawLinesButton.grid(row=5,column=0,sticky=N+S+E+W)
- self.toolDrawBeziButton = Button(self.toolBar,command=self.toolDrawBeziCmd,image=self.toolIcons["drawBezi"])
- self.toolDrawBeziButton.grid(row=5,column=1,sticky=N+S+E+W)
- self.toolDrawPolyButton = Button(self.toolBar,command=self.toolDrawPolyCmd,image=self.toolIcons["drawPoly"])
- self.toolDrawPolyButton.grid(row=6,column=0,sticky=N+S+E+W)
- self.toolFillPolyButton = Button(self.toolBar,command=self.toolFillPolyCmd,image=self.toolIcons["fillPoly"])
- self.toolFillPolyButton.grid(row=6,column=1,sticky=N+S+E+W)
- self.toolDrawEllipButton = Button(self.toolBar,command=self.toolDrawEllipCmd,image=self.toolIcons["drawEllip"],state=DISABLED,relief=FLAT)
- #self.toolDrawEllipButton.grid(row=7,column=0,sticky=N+S+E+W)
- self.toolFillEllipButton = Button(self.toolBar,command=self.toolFillEllipCmd,image=self.toolIcons["fillEllip"],state=DISABLED,relief=FLAT)
- #self.toolFillEllipButton.grid(row=7,column=1,sticky=N+S+E+W)
- self.toolDrawShapeButton = Button(self.toolBar,command=self.toolDrawShapeCmd,image=self.toolIcons["drawShape"])
- self.toolDrawShapeButton.grid(row=8,column=0,sticky=N+S+E+W)
- self.toolFillShapeButton = Button(self.toolBar,command=self.toolFillShapeCmd,image=self.toolIcons["fillShape"])
- self.toolFillShapeButton.grid(row=8,column=1,sticky=N+S+E+W)
- self.toolTextButton = Button(self.toolBar,command=self.toolTextCmd,image=self.toolIcons["text"])
- self.toolTextButton.grid(row=9,column=0,sticky=N+S+E+W)
- self.toolAsyButton = Button(self.toolBar,command=self.toolAsyCmd,image=self.toolIcons["asy"])
- self.toolAsyButton.grid(row=9,column=1,sticky=N+S+E+W)
-
- self.adjLbl = Label(self.toolBar,text="",anchor=W)
- self.adjLbl.grid(row=10,column=0,columnspan=2,sticky=W)
- self.toolRaiseButton = Button(self.toolBar,command=self.toolRaiseCmd,image=self.toolIcons["raise"])
- self.toolRaiseButton.grid(row=11,column=0,sticky=N+S+E+W)
- self.toolLowerButton = Button(self.toolBar,command=self.toolLowerCmd,image=self.toolIcons["lower"])
- self.toolLowerButton.grid(row=11,column=1,sticky=N+S+E+W)
-
- self.toolBar.pack(side=LEFT,anchor=NW)
-
- #documentation for the tool bar buttons
- self.toolDocs = {
- self.toolSelectButton : "Click an item to select it. Control-Click will select/deselect additional items. Use mouse scroller (or Up/Down keys) to raise/lower highlighted items.",
- self.toolMoveButton : "Drag a selected item.",
- self.toolHorizMoveButton : "Drag a selected item. Only horizontal translation will be applied.",
- self.toolVertiMoveButton : "Drag a selected item. Only vertical translation will be applied.",
- self.toolRotateButton : "Drag a selected item to rotate it.",
- self.toolDrawLinesButton : "Click to draw line segments. Double click to place last point.",
- self.toolDrawBeziButton : "Click to place points. Double click to place last point.",
- self.toolDrawPolyButton : "Click to place vertices. Double click to place last point.",
- self.toolFillPolyButton : "Click to place vertices. Double click to place last point.",
- self.toolDrawEllipButton : "(UNIMPLEMENTED)Click to place center. Move mouse to achieve correct shape and double click.",
- self.toolFillEllipButton : "(UNIMPLEMENTED)Click to place center. Move mouse to achieve correct shape and double click.",
- self.toolDrawShapeButton : "Click to place points. Double click to place last point.",
- self.toolFillShapeButton : "Click to place points. Double click to place last point.",
- self.toolTextButton : "Click location of top left label position and enter text in dialog.",
- self.toolRaiseButton : "Raise selected items to top.",
- self.toolLowerButton : "Lower selected items to bottom.",
- self.toolAsyButton : "Insert/Edit Asymptote code."
- }
-
- #Current pen settings
- self.optionsBar = Frame(self.parent,height=100,relief=FLAT,borderwidth=3)
- self.penDisp = Canvas(self.optionsBar,width=100,height=25,bg="white",relief=SUNKEN,borderwidth=3)
- self.penDisp.grid(row=0,column=0,padx=3,pady=3)
- self.penDisp.create_line(10,25,30,10,60,20,80,10,smooth=True,tags="penDisp")
- self.penDisp.create_text(100,30,text="x1",tags="penMag",anchor=SE,font=("times","8"))
- self.penColButton = Button(self.optionsBar,text="Color...",width=5,command=self.setPenColCmd,relief=FLAT)
- self.penColButton.grid(row=0,column=1,padx=3,pady=3)
- Label(self.optionsBar,text="Width",anchor=E).grid(row=0,column=2)
- self.penWidthEntry = Entry(self.optionsBar,width=5)
- self.penWidthEntry.bind("<KeyRelease>",self.penWidthChanged)
- self.penWidthEntry.bind("<FocusOut>",self.applyPenWidthEvt)
- self.penWidthEntry.bind("<Return>",self.applyPenWidthEvt)
- self.penWidthEntry.grid(row=0,column=3)
- Label(self.optionsBar,text="Options",anchor=E).grid(row=0,column=4)
- self.penOptEntry = Entry(self.optionsBar)
- self.penOptEntry.bind("<FocusOut>",self.applyPenOptEvt)
- self.penOptEntry.bind("<Return>",self.applyPenOptEvt)
- self.penOptEntry.grid(row=0,column=5)
- self.optionsBar.pack(side=BOTTOM,anchor=NW)
-
- #a paned window for the canvas and propert explorer
- self.windowPane = PanedWindow(self.parent)
-
- #a property explorer
- self.propFrame = Frame(self.parent)
- self.propFrame.rowconfigure(1,weight=1)
- self.propFrame.columnconfigure(0,weight=1)
- Label(self.propFrame,text="Item List").grid(row=0,column=0,columnspan=2)
- self.itemScroll = Scrollbar(self.propFrame,orient=VERTICAL)
- self.propList = Listbox(self.propFrame, yscrollcommand=self.itemScroll.set)
- self.itemScroll.config(command=self.propList.yview)
- self.itemScroll.grid(row=1,column=1,sticky=N+S)
- self.propList.grid(row=1,column=0,sticky=N+S+E+W)
- self.propList.bind("<Double-Button-1>",self.propSelect)
- self.propList.bind("<Button-3>",self.itemPropMenuPopup)
-
- #the canvas's frame
- self.canvFrame = Frame(self.parent,relief=FLAT,borderwidth=0)
- self.canvFrame.rowconfigure(0,weight=1)
- self.canvFrame.columnconfigure(0,weight=1)
- self.canvVScroll = Scrollbar(self.canvFrame,orient=VERTICAL)
- self.canvHScroll = Scrollbar(self.canvFrame,orient=HORIZONTAL)
- self.canvHScroll.grid(row=1,column=0,sticky=E+W)
- self.canvVScroll.grid(row=0,column=1,sticky=N+S)
-
- #add the frames to the window pane
- self.windowPane.pack(side=RIGHT,fill=BOTH,expand=True)
- self.windowPane.add(self.canvFrame)
- self.windowPane.add(self.propFrame)
- self.windowPane.paneconfigure(self.propFrame,minsize=50,sticky=N+S+E+W)
- self.windowPane.bind("<Double-Button-1>",self.togglePaneEvt)
-
- #the highly important canvas!
- self.mainCanvas = Canvas(self.canvFrame,relief=SUNKEN,background="white",borderwidth=3,
- highlightthickness=0,closeenough=1.0,yscrollcommand=self.canvVScroll.set,
- xscrollcommand=self.canvHScroll.set)
- self.mainCanvas.grid(row=0,column=0,sticky=N+S+E+W)
-
- self.canvVScroll.config(command=self.mainCanvas.yview)
- self.canvHScroll.config(command=self.mainCanvas.xview)
-
- self.mainCanvas.bind("<Motion>",self.canvMotion)
- self.mainCanvas.bind("<Button-1>",self.canvLeftDown)
- self.mainCanvas.bind("<Double-Button-1>",self.endDraw)
- self.mainCanvas.bind("<ButtonRelease-1>",self.canvLeftUp)
- self.mainCanvas.bind("<B1-Motion>",self.canvDrag)
-
- self.mainCanvas.bind("<Enter>",self.canvEnter)
- self.mainCanvas.bind("<Leave>",self.canvLeave)
- self.mainCanvas.bind("<Delete>",self.itemDelete)
- #self.mainCanvas.bind("<Button-3>",self.canvRightDown)
- #self.mainCanvas.bind("<ButtonRelease-3>",self.canvRightUp)
- self.mainCanvas.bind("<Button-4>",self.itemRaise)
- self.mainCanvas.bind("<Button-5>",self.itemLower)
- self.mainCanvas.bind("<Up>",self.itemRaise)
- self.mainCanvas.bind("<Down>",self.itemLower)
- self.mainCanvas.bind("<Configure>",self.configEvt)
-
- def foregroundPenColor(self,hex):
- hex = hex[1:]
- rgb = max(hex[0:2], hex[2:4], hex[4:6])
- if(rgb >= "80"):
- return "black"
- else:
- return "white"
-
- def resetGUI(self):
- #set up the main window
- self.filename = None
- self.fileToOpen = None
- self.retitle()
-
- #set up the paned window
- self.paneVisible = True
-
- #setup the pen entries
- self.pendingPenWidthChange = None
- self.pendingPenOptChange = None
-
- #load one-time configs
- xasyOptions.load()
- self.tkPenColor = xasyOptions.options['defPenColor']
- self.penColor = makeRGBfromTkColor(self.tkPenColor)
- self.penColButton.config(activebackground=self.tkPenColor,
- activeforeground=self.foregroundPenColor(self.tkPenColor))
- self.penWidth = xasyOptions.options['defPenWidth']
- self.penWidthEntry.select_range(0,END)
- self.penWidthEntry.delete(0,END)
- self.penWidthEntry.insert(END,str(self.penWidth))
- self.penOptions = xasyOptions.options['defPenOptions']
- self.penOptEntry.select_range(0,END)
- self.penOptEntry.delete(0,END)
- self.penOptEntry.insert(END,str(self.penOptions))
- self.showCurrentPen()
-
- #load modifiable configs
- self.applyOptions()
-
- #set up editing
- self.editor = None
-
- #set up drawing
- self.pathInProgress = asyPath()
- self.currentIDTag = -1
- self.inDrawingMode = False
- self.freeMouseDown = True
- self.dragSelecting = False
- self.itemsBeingRotated = []
- self.inRotatingMode = False
-
- #set up the toolbar
- try:
- self.updateSelectedButton(self.toolSelectButton)
- except:
- self.selectedButton = self.toolSelectButton
- self.updateSelectedButton(self.toolSelectButton)
-
- #set up the canvas
- self.mainCanvas.delete(ALL)
- self.mainCanvas.create_rectangle(0,0,0,0,tags="outlineBox",width=0,outline="#801111",dash=(3,6))
- self.backColor = "white" #in future, load this from an options file. Or, should this really be an option?
- self.mainCanvas.configure(background=self.backColor)
-
- #set up the xasy item list
- self.fileItems = []
- self.propList.delete(0,END)
- self.updateCanvasSize()
-
- #setup timer
- self.tickCount = 0
-
- #setup undo/redo!
- self.undoRedoStack = actionStack()
- self.amDragging = False
-
- def retitle(self):
- if self.filename == None:
- self.parent.title("Xasy - New File")
- else:
- name = os.path.abspath(self.filename)
- name = os.path.basename(name)
- self.parent.title("Xasy - %s"%name)
-
- def applyOptions(self):
- self.gridcolor = xasyOptions.options['gridColor']
- self.tickcolor = xasyOptions.options['tickColor']
- self.axiscolor = xasyOptions.options['axesColor']
- self.gridVisible = xasyOptions.options['showGrid']
- self.gridxspace = xasyOptions.options['gridX']
- self.gridyspace = xasyOptions.options['gridY']
- self.axesVisible = xasyOptions.options['showAxes']
- self.axisxspace = xasyOptions.options['axisX']
- self.axisyspace = xasyOptions.options['axisY']
- self.updateCanvasSize()
- #test the asyProcess
- startQuickAsy()
- if not quickAsyRunning():
- if messagebox.askyesno("Xasy Error","Asymptote could not be executed.\r\nTry to find Asymptote automatically?"):
- xasyOptions.setAsyPathFromWindowsRegistry()
- xasyOptions.save()
- startQuickAsy()
- while not quickAsyRunning():
- if messagebox.askyesno("Xasy Error","Asymptote could not be executed.\r\nEdit settings?"):
- xasyOptionsDialog.xasyOptionsDlg(self.parent)
- xasyOptions.save()
- startQuickAsy()
- else:
- self.parent.destroy()
- sys.exit(1)
-
- def drawGrid(self):
- self.mainCanvas.delete("grid")
- if not self.gridVisible:
- return
- left,top,right,bottom = [int(float(a)) for a in self.mainCanvas.cget("scrollregion").split()]
- gridyspace = int(self.magnification*self.gridyspace)
- gridxspace = int(self.magnification*self.gridxspace)
- if gridxspace >= 3 and gridyspace >= 3:
- for i in range(0,right,gridxspace):
- self.mainCanvas.create_line(i,top,i,bottom,tags=("grid","vertical"),fill=self.gridcolor)
- for i in range(-gridxspace,left,-gridxspace):
- self.mainCanvas.create_line(i,top,i,bottom,tags=("grid","vertical"),fill=self.gridcolor)
- for i in range(-gridyspace,top,-gridyspace):
- self.mainCanvas.create_line(left,i,right,i,tags=("grid","horizontal"),fill=self.gridcolor)
- for i in range(0,bottom,gridyspace):
- self.mainCanvas.create_line(left,i,right,i,tags=("grid","horizontal"),fill=self.gridcolor)
- self.mainCanvas.tag_lower("grid")
-
- def drawAxes(self):
- self.mainCanvas.delete("axes")
- if not self.axesVisible:
- return
- left,top,right,bottom = [int(float(a)) for a in self.mainCanvas.cget("scrollregion").split()]
- self.mainCanvas.create_line(0,top,0,bottom,tags=("axes","yaxis"),fill=self.axiscolor)
- self.mainCanvas.create_line(left,0,right,0,tags=("axes","xaxis"),fill=self.axiscolor)
- axisxspace = int(self.magnification*self.axisxspace)
- axisyspace = int(self.magnification*self.axisyspace)
- if axisxspace >= 3 and axisyspace >= 3:
- for i in range(axisxspace,right,axisxspace):
- self.mainCanvas.create_line(i,-5,i,5,tags=("axes","xaxis-ticks"),fill=self.tickcolor)
- for i in range(-axisxspace,left,-axisxspace):
- self.mainCanvas.create_line(i,-5,i,5,tags=("axes","xaxis-ticks"),fill=self.tickcolor)
- for i in range(-axisyspace,top,-axisyspace):
- self.mainCanvas.create_line(-5,i,5,i,tags=("axes","yaxis-ticks"),fill=self.tickcolor)
- for i in range(axisyspace,bottom,axisyspace):
- self.mainCanvas.create_line(-5,i,5,i,tags=("axes","yaxis-ticks"),fill=self.tickcolor)
- self.mainCanvas.tag_lower("axes")
-
- def updateCanvasSize(self,left=-200,top=-200,right=200,bottom=200):
- self.parent.update_idletasks()
- bbox = self.mainCanvas.bbox("drawn || image || node || precontrol || postcontrol")
- if bbox == None:
- bbox = (0,0,0,0)
- #(topleft, bottomright)
- left = min(bbox[0],left)
- top = min(bbox[1],top)
- right = max(bbox[2],right)
- bottom = max(bbox[3],bottom)
- w,h = self.mainCanvas.winfo_width(),self.mainCanvas.winfo_height()
- if right-left < w:
- extraw = w-(right-left)
- right += extraw//2
- left -= extraw//2
- if bottom-top < h:
- extrah = h-(bottom-top)
- bottom += extrah//2
- top -= extrah//2
- self.mainCanvas.config(scrollregion=(left,top,right,bottom))
- #self.mainCanvas.xview(MOVETO,float(split(self.mainCanvas["scrollregion"])[0]))
- #self.mainCanvas.yview(MOVETO,float(split(self.mainCanvas["scrollregion"])[1]))
- #self.mainCanvas.xview(MOVETO,(left+right)/2)
- #self.mainCanvas.yview(MOVETO,(top+bottom)/2)
- self.drawAxes()
- self.drawGrid()
-
- def bindEvents(self,tagorID):
- if tagorID == None:
- return
- self.mainCanvas.tag_bind(tagorID,"<Control-Button-1>",self.itemToggleSelect)
- self.mainCanvas.tag_bind(tagorID,"<Button-1>",self.itemSelect)
- self.mainCanvas.tag_bind(tagorID,"<ButtonRelease-1>",self.itemMouseUp)
- self.mainCanvas.tag_bind(tagorID,"<Double-Button-1>",self.itemEditEvt)
- self.mainCanvas.tag_bind(tagorID,"<B1-Motion>",self.itemDrag)
- self.mainCanvas.tag_bind(tagorID,"<Delete>",self.itemDelete)
- self.mainCanvas.tag_bind(tagorID,"<Enter>",self.itemHighlight)
- self.mainCanvas.tag_bind(tagorID,"<Button-3>",self.itemCanvasMenuPopup)
-
- def bindItemEvents(self,item):
- if item == None:
- return
- if isinstance(item,xasyScript) or isinstance(item,xasyText):
- for image in item.imageList:
- self.bindEvents(image.IDTag)
- else:
- self.bindEvents(item.IDTag)
-
- def canQuit(self,force=False):
- #print ("Quitting")
- if not force and not self.testOrAcquireLock():
- return
- try:
- self.releaseLock()
- except:
- pass
- if self.undoRedoStack.changesMade():
- result = messagebox._show("xasy","File has been modified.\nSave changes?",icon=messagebox.QUESTION,type=messagebox.YESNOCANCEL)
- if str(result) == messagebox.CANCEL:
- return
- elif result == messagebox.YES:
- self.fileSaveCmd()
- try:
- os.rmdir(getAsyTempDir())
- except:
- pass
-
- stopQuickAsy()
- self.parent.destroy()
-
- def openFile(self,name):
- if(not self.testOrAcquireLock()):
- return
- self.releaseLock() #release the lock for loadFile
- self.resetGUI()
- self.loadFile(name)
-
- def loadFile(self,name):
- self.status.config(text="Loading "+name)
- self.filename = os.path.abspath(name)
- startQuickAsy()
- self.retitle()
- try:
- try:
- f = open(self.filename,'rt')
- except:
- if self.filename[-4:] == ".asy":
- raise
- else:
- f = open(self.filename+".asy",'rt')
- self.filename += ".asy"
- self.retitle()
- self.fileItems = xasyFile.parseFile(f)
- f.close()
- except IOError:
- messagebox.showerror("File Opening Failed.","File could not be opened.")
- self.fileItems = []
- except:
- self.fileItems = []
- self.autoMakeScript = True
- if self.autoMakeScript or messagebox.askyesno("Error Opening File", "File was not recognized as an xasy file.\nLoad as a script item?"):
- try:
- item = xasyScript(self.mainCanvas)
- f.seek(0)
- item.setScript(f.read())
- self.addItemToFile(item)
- except:
- messagebox.showerror("File Opening Failed.","Could not load as a script item.")
- self.fileItems = []
- self.populateCanvasWithItems()
- self.populatePropertyList()
- self.updateCanvasSize()
-
- def populateCanvasWithItems(self):
- if(not self.testOrAcquireLock()):
- return
- self.mainCanvas.delete("drawn || image")
- self.itemCount = 0
- for item in self.fileItems:
- item.drawOnCanvas(self.mainCanvas,self.magnification,forceAddition=True)
- self.bindItemEvents(item)
- self.releaseLock()
-
- def propListCountItem(self,item):
- plist = self.propList.get(0,END)
- count = 1
- for text in plist:
- if text.startswith(item):
- count += 1
- return count
-
- def describeItem(self,item):
- if isinstance(item,xasyScript):
- return "Code Module "+str(self.propListCountItem("Code Module"))
- elif isinstance(item,xasyText):
- return "Text Label "+str(self.propListCountItem("Text Label"))
- elif isinstance(item,xasyFilledShape):
- return "Filled Shape "+str(self.propListCountItem("Filled Shape"))
- elif isinstance(item,xasyShape):
- return "Outline "+str(self.propListCountItem("Outline"))
- else:
- return "If this happened, the program is corrupt!"
-
- def populatePropertyList(self):
- self.propList.delete(0,END)
- for item in self.fileItems:
- self.propList.insert(0,self.describeItem(item))
-
- def saveFile(self,name):
- if(not self.testOrAcquireLock()):
- return
- f = open(name,"wt")
- xasyFile.saveFile(f,self.fileItems)
- f.close()
- self.undoRedoStack.setCommitLevel()
- self.retitle()
- self.releaseLock()
-
- #menu commands
- def fileNewCmd(self):
- if(not self.testOrAcquireLock()):
- return
- self.releaseLock()
- #print ("Create New File")
- if self.undoRedoStack.changesMade():
- result = messagebox._show("xasy","File has been modified.\nSave changes?",icon=messagebox.QUESTION,type=messagebox.YESNOCANCEL)
- if str(result) == messagebox.CANCEL:
- return
- elif result == messagebox.YES:
- self.fileSaveCmd()
- self.resetGUI()
-
- def fileOpenCmd(self):
- if(not self.testOrAcquireLock()):
- return
- self.releaseLock()
- #print ("Open a file")
- if self.undoRedoStack.changesMade():
- result = messagebox._show("xasy","File has been modified.\nSave changes?",icon=messagebox.QUESTION,type=messagebox.YESNOCANCEL)
- if str(result) == messagebox.CANCEL:
- return
- elif result == messagebox.YES:
- self.fileSaveCmd()
- filename=filedialog.askopenfilename(filetypes=[("asy files","*.asy"),("All files","*")],title="Open File",parent=self.parent)
- if type(filename) != type((0,)) and filename != None and filename != '':
- self.filename = filename
- self.openFile(self.filename)
-
- def fileSaveCmd(self):
- #print ("Save current file")
- if(not self.testOrAcquireLock()):
- return
- self.releaseLock()
- if self.filename == None:
- filename=filedialog.asksaveasfilename(defaultextension=".asy",filetypes=[("asy files","*.asy")],initialfile="newDrawing.asy",parent=self.parent,title="Save File")
- if type(filename) != type((0,)) and filename != None and filename != '':
- self.filename = filename
- if self.filename != None:
- self.saveFile(self.filename)
-
- def fileSaveAsCmd(self):
- if(not self.testOrAcquireLock()):
- return
- self.releaseLock()
- #print ("Save current file as")
- filename=filedialog.asksaveasfilename(defaultextension=".asy",filetypes=[("asy files","*.asy")],initialfile="newDrawing.asy",parent=self.parent,title="Save File")
- if type(filename) != type((0,)) and filename != None and filename != '':
- self.filename = filename
- self.saveFile(self.filename)
-
- #export the file
- def exportEPS(self):
- self.exportFile(self.filename,"eps")
-
- def exportPDF(self):
- self.exportFile(self.filename,"pdf")
-
- def exportGIF(self):
- self.exportFile(self.filename,"gif")
-
- def exportPNG(self):
- self.exportFile(self.filename,"png")
-
- def exportSVG(self):
- self.exportFile(self.filename,"svg")
-
- def exportFile(self,inFile, outFormat):
- if(not self.testOrAcquireLock()):
- return
- self.releaseLock()
- if inFile == None:
- if messagebox.askyesno("xasy","File has not been saved.\nSave?"):
- self.fileSaveAsCmd()
- inFile = self.filename
- else:
- return
- elif self.undoRedoStack.changesMade():
- choice = messagebox._show("xasy","File has been modified.\nOnly saved changes can be exported.\nDo you want to save changes?",icon=messagebox.QUESTION,type=messagebox.YESNOCANCEL)
- choice = str(choice)
- if choice != messagebox.YES:
- return
- else:
- self.fileSaveCmd()
- name = os.path.splitext(os.path.basename(self.filename))[0]+'.'+outFormat
- outfilename = filedialog.asksaveasfilename(defaultextension = '.'+outFormat,filetypes=[(outFormat+" files","*."+outFormat)],initialfile=name,parent=self.parent,title="Choose output file")
- if type(outfilename)==type((0,)) or not outfilename or outfilename == '':
- return
- fullname = os.path.abspath(outfilename)
- outName = os.path.basename(outfilename)
- command=[xasyOptions.options['asyPath'],"-f"+outFormat,"-o"+fullname,inFile]
- saver = subprocess.Popen(command,stdin=PIPE,stdout=PIPE,stderr=PIPE)
- saver.wait()
- if saver.returncode != 0:
- messagebox.showerror("Export Error","Export Error:\n"+saver.stdout.read()+saver.stderr.read())
- self.status.config(text="Error exporting file")
- else:
- self.status.config(text="File exported successfully")
-
- def fileExitCmd(self):
- #print ("Exit xasy")
- self.canQuit()
-
- def editUndoCmd(self):
- if not self.editor == None:
- return
- if(not self.testOrAcquireLock()):
- return
- self.undoOperation()
- self.releaseLock()
-
- def editRedoCmd(self):
- if not self.editor == None:
- return
- if(not self.testOrAcquireLock()):
- return
- self.redoOperation()
- self.releaseLock()
-
- def helpHelpCmd(self):
- print ("Get help on xasy")
-
- def helpAsyDocCmd(self):
- #print ("Open documentation about Asymptote")
- asyExecute("help;\n")
-
- def helpAboutCmd(self):
- messagebox.showinfo("About xasy","A graphical interface for Asymptote "+xasyVersion)
-
- def updateSelectedButton(self,newB):
- if(not self.testOrAcquireLock()):
- return
- self.releaseLock()
- #disable switching modes during an incomplete drawing operation
- if self.inDrawingMode:
- return
- self.selectedButton.config(relief = RAISED)
- if newB == self.toolSelectButton or self.selectedButton == self.toolSelectButton:
- self.mainCanvas.delete("highlightBox")
- if self.editor != None:
- self.editor.endEdit()
- if self.editor.modified:
- self.undoRedoStack.add(editDrawnItemAction(self,self.itemBeingEdited,copy.deepcopy(self.editor.shape),self.fileItems.index(self.editor.shape)))
- if newB not in (self.toolSelectButton,self.toolMoveButton,self.toolHorizMoveButton,self.toolVertiMoveButton,self.toolRotateButton):
- self.clearSelection()
- self.selectedButton = newB
- self.selectedButton.config(relief = SUNKEN)
- self.status.config(text=self.toolDocs[newB])
-
- #toolbar commands
- def toolSelectCmd(self):
- self.updateSelectedButton(self.toolSelectButton)
- def toolMoveCmd(self):
- self.updateSelectedButton(self.toolMoveButton)
- def toolRotateCmd(self):
- self.updateSelectedButton(self.toolRotateButton)
- def toolVertiMoveCmd(self):
- self.updateSelectedButton(self.toolVertiMoveButton)
- def toolHorizMoveCmd(self):
- self.updateSelectedButton(self.toolHorizMoveButton)
- def toolDrawLinesCmd(self):
- self.updateSelectedButton(self.toolDrawLinesButton)
- def toolDrawBeziCmd(self):
- self.updateSelectedButton(self.toolDrawBeziButton)
- def toolDrawPolyCmd(self):
- self.updateSelectedButton(self.toolDrawPolyButton)
- def toolFillPolyCmd(self):
- self.updateSelectedButton(self.toolFillPolyButton)
- def toolDrawEllipCmd(self):
- self.updateSelectedButton(self.toolDrawEllipButton)
- def toolFillEllipCmd(self):
- self.updateSelectedButton(self.toolFillEllipButton)
- def toolDrawShapeCmd(self):
- self.updateSelectedButton(self.toolDrawShapeButton)
- def toolFillShapeCmd(self):
- self.updateSelectedButton(self.toolFillShapeButton)
- def toolTextCmd(self):
- self.updateSelectedButton(self.toolTextButton)
- def toolAsyCmd(self):
- # ignore the command if we are too busy to process it
- if not self.testOrAcquireLock():
- return
- self.updateSelectedButton(self.toolSelectButton)
- self.clearSelection()
- self.clearHighlight()
- self.unbindGlobalEvents()
- try:
- self.getNewText("// enter your code here")
- except Exception as e:
- messagebox.showerror('xasy Error',e.message)
- else:
- self.addItemToFile(xasyScript(self.mainCanvas))
- text = self.newText
- self.undoRedoStack.add(addScriptAction(self,self.fileItems[-1]))
- self.fileItems[-1].setScript(text)
- self.fileItems[-1].drawOnCanvas(self.mainCanvas,self.magnification)
- self.bindItemEvents(self.fileItems[-1])
- self.bindGlobalEvents()
- self.releaseLock()
- def toolRaiseCmd(self):
- if(not self.testOrAcquireLock()):
- return
- self.releaseLock()
- if not self.inDrawingMode and self.editor == None:
- itemList = []
- indexList = []
- for ID in self.mainCanvas.find_withtag("selectedItem"):
- item = self.findItem(ID)
- if item not in itemList:
- itemList.append(item)
- indexList.append(self.fileItems.index(item))
- self.raiseSomething(item)
- self.undoRedoStack.add(itemRaiseAction(self,itemList,indexList))
- def toolLowerCmd(self):
- if(not self.testOrAcquireLock()):
- return
- self.releaseLock()
- if not self.inDrawingMode and self.editor == None:
- itemList = []
- indexList = []
- for ID in self.mainCanvas.find_withtag("selectedItem"):
- item = self.findItem(ID)
- if item not in itemList:
- itemList.append(item)
- indexList.append(self.fileItems.index(item))
- self.lowerSomething(item)
- self.undoRedoStack.add(itemLowerAction(self,itemList,indexList))
- def itemRaise(self,event):
- self.mainCanvas.tag_raise(CURRENT)
- def itemLower(self,event):
- self.mainCanvas.tag_lower(CURRENT)
-
- #options bar commands
- def setPenColCmd(self):
- if not self.testOrAcquireLock():
- return
- old = self.penColor
- self.penColor = xasyColorDlg(self.parent).getColor(self.penColor)
- if self.penColor != old:
- self.tkPenColor = RGB255hex(RGBreal255(self.penColor))
- self.penColButton.config(activebackground=self.tkPenColor,
- activeforeground=self.foregroundPenColor(self.tkPenColor))
- self.showCurrentPen()
- self.releaseLock()
-
- def clearSelection(self):
- self.hideSelectionBox()
- self.mainCanvas.dtag("selectedItem","selectedItem")
-
- def hideSelectionBox(self):
- self.mainCanvas.itemconfigure("outlineBox",width=1,outline=self.backColor)
- self.mainCanvas.tag_lower("outlineBox")
- self.mainCanvas.coords("outlineBox",self.mainCanvas.bbox(ALL))
-
- def showSelectionBox(self):
- self.mainCanvas.itemconfigure("outlineBox",width=2,outline="#801111")
- self.mainCanvas.tag_raise("outlineBox")
-
- def setSelection(self,what):
- self.mainCanvas.addtag_withtag("selectedItem",what)
- self.updateSelection()
- if self.selectedButton == self.toolSelectButton and len(self.mainCanvas.find_withtag("selectedItem")) > 0:
- self.updateSelectedButton(self.toolMoveButton)
-
- def unSelect(self,what):
- self.mainCanvas.dtag(what,"selectedItem")
- self.updateSelection()
-
- def updateSelection(self):
- self.clearHighlight()
- theBbox = self.mainCanvas.bbox("selectedItem")
- if theBbox != None:
- theBbox = (theBbox[0]-2,theBbox[1]-2,theBbox[2]+2,theBbox[3]+2)
- self.mainCanvas.coords("outlineBox",theBbox)
- self.showSelectionBox()
- else:
- self.clearSelection()
-
- #event handlers
- def updateZoom(self):
- self.zoomMenu.config(state=DISABLED)
- self.magnification = self.magVal.get()/100.0
- if self.magnification != self.previousZoom:
- self.populateCanvasWithItems()
- self.updateCanvasSize()
- self.updateSelection()
- self.drawAxes()
- self.drawGrid()
- self.previousZoom = self.magnification
- self.zoomMenu.config(state=NORMAL)
-
- def zoomViewCmd(self,*args):
- magnification = self.magVal.get()/100.0
- self.updateZoom();
-
- def selectItem(self,item):
- self.clearSelection()
- if isinstance(item,xasyScript) or isinstance(item,xasyText):
- for image in item.imageList:
- self.setSelection(image.IDTag)
- else:
- self.setSelection(item.IDTag)
-
- def propSelect(self,event):
- items = [int(a) for a in self.propList.curselection()]
- if len(items)>0:
- try:
- self.selectItem(self.fileItems[len(self.fileItems)-items[0]-1])
- except:
- raise
-
- def findItem(self,ID):
- for item in self.fileItems:
- if isinstance(item,xasyScript) or isinstance(item,xasyText):
- for image in item.imageList:
- if image.IDTag == ID:
- return item
- else:
- if item.IDTag == ID:
- return item
- raise Exception("Illegal operation: Item with matching ID could not be found.")
-
- def findItemImageIndex(self,item,ID):
- count = 0
- for image in item.imageList:
- if image.IDTag == ID:
- return count
- else:
- count += 1
- raise Exception("Illegal operation: Image with matching ID could not be found.")
- return None
-
- def raiseSomething(self,item,force=False):
- if self.fileItems[-1] != item or force:
- index = len(self.fileItems)-self.fileItems.index(item)-1
- text = self.propList.get(index)
- self.propList.delete(index)
- self.propList.insert(0,text)
- for i in range(self.fileItems.index(item),len(self.fileItems)-1):
- self.fileItems[i] = self.fileItems[i+1]
- self.fileItems[-1] = item
- if isinstance(item,xasyScript) or isinstance(item,xasyText):
- for im in item.imageList:
- if im.IDTag != None:
- self.mainCanvas.tag_raise(im.IDTag)
- else:
- if item.IDTag != None:
- self.mainCanvas.tag_raise(item.IDTag)
-
- def lowerSomething(self,item):
- if self.fileItems[0] != item:
- index = len(self.fileItems)-self.fileItems.index(item)-1
- text = self.propList.get(index)
- self.propList.delete(index)
- self.propList.insert(END,text)
- indices = range(self.fileItems.index(item))
- indices.reverse()
- for i in indices:
- self.fileItems[i+1] = self.fileItems[i]
- self.fileItems[0] = item
- if isinstance(item,xasyScript) or isinstance(item,xasyText):
- item.imageList.reverse()
- for im in item.imageList:
- if im.IDTag != None:
- self.mainCanvas.tag_lower(im.IDTag)
- item.imageList.reverse()
- else:
- if item.IDTag != None:
- self.mainCanvas.tag_lower(item.IDTag)
- self.mainCanvas.tag_lower("axes || grid")
-
- def translateSomething(self,ID,translation,specificItem=None,specificIndex=None):
- transform = asyTransform((translation[0],translation[1],1,0,0,1))
- if ID == -1:
- item = specificItem
- else:
- item = self.findItem(ID)
- if isinstance(item,xasyText) or isinstance(item,xasyScript):
- if ID == -1:
- index = specificIndex
- else:
- index = self.findItemImageIndex(item,ID)
- try:
- original = item.transform[index]
- except:
- original = identity()
- item.transform[index] = transform*original
- bbox = item.imageList[index].originalImage.bbox
- item.imageList[index].originalImage.bbox = bbox[0]+translation[0],bbox[1]+translation[1],bbox[2]+translation[0],bbox[3]+translation[1]
- else:
- item.transform = [transform*item.transform[0]]
-
- def makeRotationMatrix(self,theta,origin):
- rotMat = (math.cos(theta),-math.sin(theta),math.sin(theta),math.cos(theta))
- shift = asyTransform((0,0,1-rotMat[0],-rotMat[1],-rotMat[2],1-rotMat[3]))*origin
- return asyTransform((shift[0],shift[1],rotMat[0],rotMat[1],rotMat[2],rotMat[3]))
-
- def rotateSomething(self,ID,theta,origin,specificItem=None,specificIndex=None):
- #print ("Rotating by {} around {}".format(theta*180.0/math.pi,origin))
- rotMat = self.makeRotationMatrix(theta,(origin[0]/self.magnification,origin[1]/self.magnification))
- #print (rotMat)
- if ID == -1:
- item = specificItem
- else:
- item = self.findItem(ID)
- if isinstance(item,xasyText) or isinstance(item,xasyScript):
- #transform the image
- if ID == -1:
- index = specificIndex
- else:
- index = self.findItemImageIndex(item,ID)
- try:
- original = item.transform[index]
- except:
- original = identity()
- oldBbox = item.imageList[index].originalImage.bbox
- oldBbox = (oldBbox[0],-oldBbox[1],oldBbox[2],-oldBbox[3])
- item.transform[index] = rotMat*item.transform[index]
- item.transform[index] = rotMat*original
- item.imageList[index].originalImage.theta += theta
- item.imageList[index].image = item.imageList[index].originalImage.rotate(item.imageList[index].originalImage.theta*180.0/math.pi,expand=True,resample=Image.BICUBIC)
- item.imageList[index].itk = ImageTk.PhotoImage(item.imageList[index].image)
- self.mainCanvas.itemconfigure(ID,image=item.imageList[index].itk)
- #the image has been rotated in place
- #now, compensate for any resizing and shift to the correct location
- #
- # p0 --- p1 p1
- # | | ---> / \
- # p2 --- p3 p0 p3
- # \ /
- # p2
- #
- rotMat2 = self.makeRotationMatrix(item.imageList[index].originalImage.theta,origin)
- p0 = rotMat2*(oldBbox[0],-oldBbox[3])#switch to usual coordinates
- p1 = rotMat2*(oldBbox[2],-oldBbox[3])
- p2 = rotMat2*(oldBbox[0],-oldBbox[1])
- p3 = rotMat2*(oldBbox[2],-oldBbox[1])
- newTopLeft = (min(p0[0],p1[0],p2[0],p3[0]),-max(p0[1],p1[1],p2[1],p3[1]))#switch back to screen coords
- shift = (newTopLeft[0]-oldBbox[0],newTopLeft[1]-oldBbox[3])
- #print (theta*180.0/math.pi,origin,oldBbox,newTopLeft,shift)
- #print (item.imageList[index].originalImage.size)
- #print (item.imageList[index].image.size)
- #print
- self.mainCanvas.coords(ID,oldBbox[0]+shift[0],oldBbox[3]+shift[1])
- else:
- #transform each point of the object
- xform = rotMat*item.transform[0]
- item.transform = [identity()]
- for i in range(len(item.path.nodeSet)):
- if item.path.nodeSet[i] != 'cycle':
- item.path.nodeSet[i] = xform*item.path.nodeSet[i]
- for i in range(len(item.path.controlSet)):
- item.path.controlSet[i][0] = xform*item.path.controlSet[i][0]
- item.path.controlSet[i][1] = xform*item.path.controlSet[i][1]
- item.drawOnCanvas(self.mainCanvas,self.magnification)
-
- def deleteItem(self,item):
- if isinstance(item,xasyScript) or isinstance(item,xasyText):
- if isinstance(item,xasyScript):
- self.undoRedoStack.add(deleteScriptAction(self,item,self.fileItems.index(item)))
- else:
- self.undoRedoStack.add(deleteLabelAction(self,item,self.fileItems.index(item)))
- for image in item.imageList:
- self.mainCanvas.delete(image.IDTag)
- else:
- if isinstance(item,xasyDrawnItem):
- self.undoRedoStack.add(deleteDrawnItemAction(self,item,self.fileItems.index(item)))
- self.mainCanvas.delete(item.IDTag)
- self.fileItems.remove(item)
- self.populatePropertyList()
- self.clearSelection()
-
- def deleteSomething(self,ID):
- self.clearSelection()
- self.clearHighlight()
- if self.editor != None:
- self.editor.endEdit()
- if self.editor.modified:
- self.undoRedoStack.add(editDrawnItemAction(self,self.itemBeingEdited,copy.deepcopy(self.editor.shape),self.fileItems.index(self.editor.shape)))
- item = self.findItem(ID)
- #save an event on the undoredo stack
- if isinstance(item,xasyScript):
- index = self.findItemImageIndex(item,ID)
- item.transform[index].deleted = True
- else:
- if isinstance(item,xasyText):
- self.undoRedoStack.add(deleteLabelAction(self,item,self.fileItems.index(item)))
- elif isinstance(item,xasyDrawnItem):
- self.undoRedoStack.add(deleteDrawnItemAction(self,item,self.fileItems.index(item)))
- self.fileItems.remove(item)
- self.mainCanvas.delete(ID)
- self.populatePropertyList()
-
- def scriptEditThread(self,oldText):
- try:
- self.newText = xasyCodeEditor.getText(oldText)
- except:
- self.newText = -1
-
- def getNewText(self,oldText):
- editThread = threading.Thread(target=self.scriptEditThread,args=(oldText,))
- editThread.start()
- while editThread.isAlive():
- time.sleep(0.05)
- self.parent.update()
- editThread.join()
- if type(self.newText)==type(-1):
- self.newText = ''
- raise Exception('Error launching external editor. Please check xasy options.')
-
- def itemEdit(self,item):
- # are we too busy?
- if not self.testOrAcquireLock():
- return
- self.updateSelectedButton(self.toolSelectButton)
- if isinstance(item,xasyScript):
- self.unbindGlobalEvents()
- oldText = item.script
- try:
- self.getNewText(oldText)
- except Exception as e:
- messagebox.showerror('xasy Error',e.message)
- else:
- if self.newText != oldText:
- self.undoRedoStack.add(editScriptAction(self,item,self.newText,oldText))
- item.setScript(self.newText)
- item.drawOnCanvas(self.mainCanvas,self.magnification)
- self.bindItemEvents(item)
- self.bindGlobalEvents()
- elif isinstance(item,xasyText):
- theText = simpledialog.askstring(title="Xasy - Text",prompt="Enter text to display:",initialvalue=item.label.text,parent=self.parent)
- if theText != None and theText != "":
- self.undoRedoStack.add(editLabelTextAction(self,item,theText,item.label.text))
- item.label.text = theText
- item.drawOnCanvas(self.mainCanvas,self.magnification)
- self.bindItemEvents(item)
- elif isinstance(item,xasyShape):
- self.clearSelection()
- self.clearHighlight()
- self.itemBeingEdited = copy.deepcopy(item)
- self.editor = xasyBezierEditor(self,item,self.mainCanvas)
- self.updateSelection()
- self.releaseLock()
-
- def itemEditEvt(self,event):
- if not self.inDrawingMode:
- ID = self.mainCanvas.find_withtag(CURRENT)[0]
- item = self.findItem(ID)
- self.itemEdit(item)
-
- def itemDrag(self,event):
- x0,y0 = self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y)
- x = x0/self.magnification
- y = y0/self.magnification
- if self.selectedButton not in [self.toolMoveButton,self.toolVertiMoveButton,self.toolHorizMoveButton]:
- return
- if "selectedItem" in self.mainCanvas.gettags(CURRENT):
- self.amDragging = True
- for ID in self.mainCanvas.find_withtag("selectedItem"):
- transform = identity()
- if self.selectedButton == self.toolMoveButton:
- translation = (x0-self.dragStartx,-(y0-self.dragStarty))
- elif self.selectedButton == self.toolVertiMoveButton:
- translation = (0,-(y0-self.dragStarty))
- elif self.selectedButton == self.toolHorizMoveButton:
- translation = (x0-self.dragStartx,0)
- self.translateSomething(ID,(translation[0]/self.magnification,translation[1]/self.magnification))
- self.mainCanvas.move(ID,translation[0],-translation[1])
- self.updateSelection()
- self.updateCanvasSize()
- self.distanceDragged = (self.distanceDragged[0]+translation[0],self.distanceDragged[1]-translation[1])
- self.dragStartx,self.dragStarty = x0,y0
-
- def itemMouseUp(self,event):
- self.freeMouseDown = True
- if self.amDragging:
- IDList = self.mainCanvas.find_withtag("selectedItem")
- itemList = []
- indexList = []
- for ID in IDList:
- item = self.findItem(ID)
- if item not in itemList:
- itemList.append(item)
- try:
- indexList.append([self.findItemImageIndex(item,ID)])
- except:
- indexList.append([None])
- else:
- indexList[itemList.index(item)].append(self.findItemImageIndex(item,ID))
- self.undoRedoStack.add(translationAction(self,itemList,indexList,(self.distanceDragged[0],-self.distanceDragged[1])))
- self.amDragging = False
-
- def itemSelect(self,event):
- x0,y0 = self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y)
- x = x0/self.magnification
- y = y0/self.magnification
- self.dragStartx,self.dragStarty = x0,y0
- self.distanceDragged = (0,0)
- if self.selectedButton in [self.toolSelectButton,self.toolMoveButton,self.toolVertiMoveButton,self.toolHorizMoveButton,self.toolRotateButton]:
- self.freeMouseDown = False
- if self.selectedButton == self.toolSelectButton or (len(self.mainCanvas.find_withtag("selectedItem"))<=1 and self.selectedButton in [self.toolMoveButton,self.toolVertiMoveButton,self.toolHorizMoveButton,self.toolRotateButton]):
- self.clearSelection()
- self.setSelection(CURRENT)
-
- def itemToggleSelect(self,event):
- #print ("control click")
- x0,y0 = self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y)
- x = x0/self.magnification
- y = y0/self.magnification
- if self.selectedButton in [self.toolSelectButton,self.toolMoveButton,self.toolVertiMoveButton,self.toolHorizMoveButton,self.toolRotateButton]:
- self.freeMouseDown = False
- self.dragStartx,self.dragStarty = x0,y0
- if "selectedItem" in self.mainCanvas.gettags(CURRENT):
- self.unSelect(CURRENT)
- else:
- self.setSelection(CURRENT)
-
- def itemDelete(self,event):
- if(not self.testOrAcquireLock()):
- return
- itemList = []
- self.undoRedoStack.add(endActionGroup)
- for ID in self.mainCanvas.find_withtag("selectedItem"):
- item = self.findItem(ID)
- if isinstance(item,xasyScript):
- index = self.findItemImageIndex(item,ID)
- if item not in itemList:
- itemList.append([item,[index],[item.transform[index]]])
- else:
- x = None
- for i in itemList:
- if i[0] == item:
- x = i
- x[1].append(index)
- x[2].append(item.transform[index])
- self.deleteSomething(ID)
- for entry in itemList:
- self.undoRedoStack.add(deleteScriptItemAction(self,entry[0],entry[1],entry[2]))
- self.undoRedoStack.add(beginActionGroup)
- self.clearSelection()
- self.releaseLock()
-
- def itemMotion(self,event):
- pass
-
- def itemHighlight(self,event):
- if self.selectedButton in [self.toolSelectButton] and self.editor == None:
- box = self.mainCanvas.bbox(CURRENT)
- box = (box[0]-2,box[1]-2,box[2]+2,box[3]+2)
- if len(self.mainCanvas.find_withtag("highlightBox"))==0:
- self.mainCanvas.create_rectangle(box,tags="highlightBox",width=2,outline="red")
- else:
- self.mainCanvas.tag_raise("highlightBox")
- self.mainCanvas.coords("highlightBox",*box)
- self.mainCanvas.tag_bind("highlightBox","<Leave>",self.itemUnHighlight)
-
- def itemUnHighlight(self,event):
- self.clearHighlight()
-
- def clearHighlight(self):
- self.mainCanvas.delete("highlightBox")
-
- def itemLeftDown(self,event):
- pass
-
- def itemLeftUp(self,event):
- pass
-
- def itemRightDown(self,event):
- pass
-
- def itemRightUp(self,event):
- pass
-
- def canvMotion(self,event):
- self.coords.config(
- text="(%.3f,%.3f)"%(self.mainCanvas.canvasx(event.x)/self.magnification,-self.mainCanvas.canvasy(event.y)/self.magnification)
- )
-
- def addItemToFile(self,item):
- self.fileItems.append(item)
- self.propList.insert(0,self.describeItem(item))
- self.updateCanvasSize()
-
- def startDraw(self,event):
- # don't start if we can't finish
- if not self.testOrAcquireLock() and not self.inDrawingMode:
- return
- x0,y0 = self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y)
- x = x0/self.magnification
- y = y0/self.magnification
- #self.mainCanvas.create_oval(x,y,x,y,width=5)
- if self.selectedButton == self.toolDrawEllipButton:
- pass
- elif self.selectedButton == self.toolFillEllipButton:
- pass
- elif self.selectedButton == self.toolTextButton:
- theText = simpledialog.askstring(title="Xasy - Text",prompt="Enter text to display:",initialvalue="",parent=self.parent)
- if theText != None and theText != "":
- theItem = xasyText(theText,(x,-y),asyPen(self.penColor,self.penWidth,self.penOptions))
- theItem.drawOnCanvas(self.mainCanvas,self.magnification)
- self.bindItemEvents(theItem)
- self.addItemToFile(theItem)
- self.undoRedoStack.add(addLabelAction(self,theItem))
- self.releaseLock()
- self.updateSelectedButton(self.toolSelectButton)
- elif self.selectedButton in [self.toolDrawLinesButton,self.toolDrawBeziButton,self.toolDrawPolyButton,self.toolDrawShapeButton,self.toolFillPolyButton,self.toolFillShapeButton]:
- self.inDrawingMode = True
- try:
- if len(self.itemBeingDrawn.path.nodeSet) == 0:
- raise Exception
- else:
- if self.selectedButton in [self.toolDrawLinesButton,self.toolDrawPolyButton,self.toolFillPolyButton]:
- self.itemBeingDrawn.appendPoint((x,-y),'--')
- else:#drawBezi,drawShape,fillShape
- self.itemBeingDrawn.appendPoint((x,-y),'..')
- except:
- path = asyPath()
- if self.selectedButton == self.toolDrawLinesButton:
- path.initFromNodeList([(x,-y),(x,-y)],['--'])
- elif self.selectedButton == self.toolDrawBeziButton:
- path.initFromNodeList([(x,-y),(x,-y)],['..'])
- elif self.selectedButton == self.toolDrawPolyButton or self.selectedButton == self.toolFillPolyButton:
- path.initFromNodeList([(x,-y),(x,-y),'cycle'],['--','--'])
- elif self.selectedButton == self.toolDrawShapeButton or self.selectedButton == self.toolFillShapeButton:
- path.initFromNodeList([(x,-y),(x,-y),'cycle'],['..','..'])
- if self.selectedButton in [self.toolDrawLinesButton,self.toolDrawBeziButton,self.toolDrawPolyButton,self.toolDrawShapeButton]:
- self.itemBeingDrawn = xasyShape(path,pen=asyPen(self.penColor,self.penWidth,self.penOptions))
- else:
- if self.penOptions.find("fillrule") != -1 or self.penOptions.find("evenodd") != -1 or self.penOptions.find("zerowinding") != -1:
- options = self.penOptions
- else:
- options = "evenodd"
- self.itemBeingDrawn = xasyFilledShape(path,pen=asyPen(self.penColor,self.penWidth,options))
- self.itemBeingDrawn.drawOnCanvas(self.mainCanvas,self.magnification)
- self.bindItemEvents(self.itemBeingDrawn)
- self.mainCanvas.bind("<Motion>",self.extendDraw)
-
- def extendDraw(self,event):
- x0,y0 = self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y)
- x = x0/self.magnification
- y = y0/self.magnification
- tags = self.mainCanvas.gettags("itemBeingDrawn")
- self.itemBeingDrawn.setLastPoint((x,-y))
- self.itemBeingDrawn.drawOnCanvas(self.mainCanvas,self.magnification)
- self.canvMotion(event)
-
- def endDraw(self,event):
- if not self.inDrawingMode or self.itemBeingDrawn == None:
- return
- x0,y0 = self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y)
- x = x0/self.magnification
- y = y0/self.magnification
- #if self.selectedButton in [self.toolDrawLinesButton,self.toolDrawPolyButton,self.toolFillPolyButton]:
- #self.itemBeingDrawn.appendPoint((x,-y),'--')
- #else:
- #self.itemBeingDrawn.appendPoint((x,-y),'..')
-
- #only needed for certain key bindings when startDraw is triggered right before an endDraw
- #e.g.: single click: startDraw, double click: endDraw
- self.itemBeingDrawn.removeLastPoint()
- self.itemBeingDrawn.setLastPoint((x,-y))
- self.itemBeingDrawn.drawOnCanvas(self.mainCanvas,self.magnification)
- self.addItemToFile(self.itemBeingDrawn)
- self.undoRedoStack.add(addDrawnItemAction(self,self.itemBeingDrawn))
- self.itemBeingDrawn = None
- self.mainCanvas.dtag("itemBeingDrawn","itemBeingDrawn")
- self.mainCanvas.bind("<Motion>",self.canvMotion)
- self.inDrawingMode = False
- self.releaseLock()
-
- def canvLeftDown(self,event):
- #print ("Left Mouse Down")
- self.selectDragStart = (self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y))
- theBbox = self.mainCanvas.bbox("selectedItem")
- if theBbox != None:
- self.selectBboxMidpoint = (theBbox[0]+theBbox[2])/2.0,-(theBbox[1]+theBbox[3])/2.0
- if self.freeMouseDown and self.editor != None:
- self.editor.endEdit()
- if self.editor.modified:
- self.undoRedoStack.add(editDrawnItemAction(self,self.itemBeingEdited,copy.deepcopy(self.editor.shape),self.fileItems.index(self.editor.shape)))
- self.editor = None
- elif self.selectedButton in (self.toolSelectButton,self.toolMoveButton,self.toolVertiMoveButton,self.toolHorizMoveButton,self.toolRotateButton):
- if self.freeMouseDown:
- self.clearSelection()
- self.dragSelecting = False
- else:
- self.startDraw(event)
-
- def canvLeftUp(self,event):
- #print ("Left Mouse Up")
- # if we're busy, ignore it
- if not self.testOrAcquireLock():
- return
- self.freeMouseDown = True
- if self.inRotatingMode:
- for item in self.itemsBeingRotated:
- item.drawOnCanvas(self.mainCanvas,self.magnification)
- self.bindItemEvents(item)
- self.updateSelection()
- self.itemsBeingRotated = []
- self.inRotatingMode = False
- if self.dragSelecting:
- self.hideSelectionBox()
- self.dragSelecting = False
- self.mainCanvas.addtag_enclosed("enclosed",self.selectDragStart[0],self.selectDragStart[1],self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y))
- for item in self.mainCanvas.find_withtag("enclosed"):
- tags = self.mainCanvas.gettags(item)
- if "drawn" not in tags and "image" not in tags:
- self.mainCanvas.dtag(item,"enclosed")
- self.mainCanvas.addtag_withtag("selectedItem","enclosed")
- self.mainCanvas.dtag("enclosed","enclosed")
- if self.selectedButton == self.toolSelectButton and len(self.mainCanvas.find_withtag("selectedItem")) > 0:
- self.updateSelectedButton(self.toolMoveButton)
- self.updateSelection()
- self.releaseLock()
-
- def canvDrag(self,event):
- x0,y0 = self.mainCanvas.canvasx(event.x),self.mainCanvas.canvasy(event.y)
- x = x0/self.magnification
- y = y0/self.magnification
- if self.selectedButton == self.toolSelectButton and self.editor == None:
- self.mainCanvas.coords("outlineBox",self.selectDragStart[0],self.selectDragStart[1],x0,y0)
- self.showSelectionBox()
- self.dragSelecting = True
- elif self.selectedButton == self.toolRotateButton and self.editor == None:
- bbox = self.mainCanvas.bbox("selectedItem")
- if bbox != None:
- p1 = self.selectDragStart[0]-self.selectBboxMidpoint[0],-self.selectDragStart[1]-self.selectBboxMidpoint[1]
- mp1 = math.sqrt(p1[0]**2+p1[1]**2)
- p2 = x0-self.selectBboxMidpoint[0],-y0-self.selectBboxMidpoint[1]
- mp2 = math.sqrt(p2[0]**2+p2[1]**2)
- if mp1 != 0:
- t1 = math.acos(p1[0]/mp1)
- if p1[1] < 0:
- t1 *= -1
- else:
- t1 = 0
- if mp2 != 0:
- t2 = math.acos(p2[0]/mp2)
- if p2[1] < 0:
- t2 *= -1
- else:
- t2 = 0
- theta = t2-t1
- self.selectDragStart = x0,y0
- self.itemsBeingRotated = []
- for ID in self.mainCanvas.find_withtag("selectedItem"):
- self.rotateSomething(ID,theta,self.selectBboxMidpoint)
- item = self.findItem(ID)
- if not item in self.itemsBeingRotated:
- self.itemsBeingRotated.append(item)
- self.updateSelection()
- self.updateCanvasSize()
- if not self.inRotatingMode:
- self.currentRotationAngle = theta
- IDList = self.mainCanvas.find_withtag("selectedItem")
- itemList = []
- indexList = []
- for ID in IDList:
- item = self.findItem(ID)
- if item not in itemList:
- itemList.append(item)
- try:
- indexList.append([self.findItemImageIndex(item,ID)])
- except:
- indexList.append([None])
- else:
- indexList[itemList.index(item)].append(self.findItemImageIndex(item,ID))
- self.undoRedoStack.add(rotationAction(self,itemList,indexList,self.currentRotationAngle,self.selectBboxMidpoint))
- self.inRotatingMode = True
- else:
- self.currentRotationAngle += theta
- self.undoRedoStack.undoStack[-1].angle = self.currentRotationAngle
-
- def canvEnter(self,event):
- self.freeMouseDown = True
- event.widget.focus_set()
-
- def canvLeave(self,event):
- self.freeMouseDown = False
-
- def canvRightDown(self,event):
- pass
- #print ("Right Mouse Down")
-
- def canvRightUp(self,event):
- pass
- #print ("Right Mouse Up")
-
- def configEvt(self,event):
- self.updateCanvasSize()
- self.sizePane()
-
- def sizePane(self):
- width = self.windowPane.winfo_width()-10
- cwidth = min(int(0.87*self.windowPane.winfo_width()),width-75)
- if self.paneVisible:
- self.windowPane.paneconfigure(self.canvFrame,minsize=cwidth)
- else:
- self.windowPane.paneconfigure(self.canvFrame,minsize=width)
- self.windowPane.paneconfigure(self.propFrame,minsize=75)
-
- def togglePaneEvt(self,event):
- self.paneVisible = not self.paneVisible
- self.sizePane()
-
- def popupDelete(self):
- self.deleteItem(self.itemPopupMenu.item)
-
- def popupEdit(self):
- self.itemEdit(self.itemPopupMenu.item)
-
- def popupViewCode(self):
- messagebox.showinfo("Item Code",self.itemPopupMenu.item.getCode())
-
- def popupClearTransform(self):
- self.undoRedoStack.add(clearItemTransformsAction(self,self.itemPopupMenu.item,copy.deepcopy(self.itemPopupMenu.item.transform)))
- if isinstance(self.itemPopupMenu.item,xasyScript) or isinstance(self.itemPopupMenu.item,xasyText):
- for i in range(len(self.itemPopupMenu.item.transform)):
- self.itemPopupMenu.item.transform[i] = identity()
- else:
- self.itemPopupMenu.item.transform = [identity()]
- self.popupRedrawItem()
-
- def popupRedrawItem(self):
- if not self.testOrAcquireLock():
- return
- self.clearSelection()
- self.clearHighlight()
- self.itemPopupMenu.item.drawOnCanvas(self.mainCanvas,self.magnification)
- self.bindItemEvents(self.itemPopupMenu.item)
- self.updateCanvasSize()
- self.releaseLock()
-
- def hidePopupMenu(self):
- try:
- self.itemPopupMenu.unpost()
- except:
- pass
-
- def itemMenuPopup(self,parent,item,x,y):
- self.hidePopupMenu()
- self.itemPopupMenu = Menu(parent,tearoff=False)
- self.itemPopupMenu.add_command(label="Edit",command=self.popupEdit)
- self.itemPopupMenu.add_command(label="Clear Transforms",command=self.popupClearTransform)
- self.itemPopupMenu.add_command(label="Redraw",command=self.popupRedrawItem)
- self.itemPopupMenu.add_command(label="View code",command=self.popupViewCode)
- self.itemPopupMenu.add_separator()
- self.itemPopupMenu.add_command(label="Delete",command=self.popupDelete)
- self.itemPopupMenu.item = item
- #self.itemPopupMenu.bind("<Leave>",lambda a:self.itemPopupMenu.unpost())
- #self.itemPopupMenu.bind("<FocusOut>",lambda a:self.itemPopupMenu.unpost())
- self.itemPopupMenu.post(x,y)
-
- def itemPropMenuPopup(self,event):
- try:
- item = self.fileItems[len(self.fileItems)-int(self.propList.curselection()[0])-1]
- self.itemMenuPopup(self.propList,item,event.x_root,event.y_root)
- except:
- pass
-
- def itemCanvasMenuPopup(self,event):
- if self.selectedButton in (self.toolSelectButton,self.toolMoveButton,self.toolVertiMoveButton,self.toolHorizMoveButton,self.toolRotateButton):
- try:
- item = self.findItem(self.mainCanvas.find_withtag(CURRENT)[0])
- except:
- item = None
- if item != None:
- self.itemMenuPopup(self.mainCanvas,item,event.x_root,event.y_root)
-
- def editOptions(self):
- if(not self.testOrAcquireLock()):
- return
- self.releaseLock()
- xasyOptionsDialog.xasyOptionsDlg(self.parent)
- self.applyOptions()
-
- def resetOptions(self):
- xasyOptions.setDefaults()
- self.applyOptions()
-
- def applyPenWidth(self):
- self.pendingPenWidthChange = None
- if self.validatePenWidth():
- old = self.penWidth
- self.penWidth = float(self.penWidthEntry.get())
- if old != self.penWidth:
- self.showCurrentPen()
-
- def validatePenWidth(self):
- text = self.penWidthEntry.get()
- try:
- width = float(text)
- if width <= 0:
- return False
- else:
- return True
- except:
- return False
-
- def showCurrentPen(self):
- mag = 1
- width = self.penWidth
- while width > 10:
- width /= 2
- mag *= 2
- self.penDisp.itemconfigure("penDisp",width=width,fill=self.tkPenColor)
- self.penDisp.itemconfigure("penMag",text="x%d"%mag)
- #apply the new pen to any selected items
- IDs = self.mainCanvas.find_withtag("selectedItem")
- madeAChange = False
- for ID in IDs:
- item = self.findItem(ID)
- if not isinstance(item,xasyScript):
- if not madeAChange:
- self.undoRedoStack.add(endActionGroup)
- madeAChange = True
- if isinstance(item,xasyText):
- temp = item.label.pen
- item.label.pen = asyPen(self.penColor,self.penWidth,self.penOptions)
- item.drawOnCanvas(self.mainCanvas,self.magnification)
- self.bindItemEvents(item)
- self.setSelection(item.imageList[0].IDTag)
- self.undoRedoStack.add(editLabelPenAction(self,temp,asyPen(self.penColor,self.penWidth,self.penOptions),self.fileItems.index(item)))
- else:
- temp = copy.deepcopy(item)
- item.pen = asyPen(self.penColor,self.penWidth,self.penOptions)
- item.drawOnCanvas(self.mainCanvas,self.magnification)
- self.undoRedoStack.add(editDrawnItemAction(self,temp,copy.deepcopy(item),self.fileItems.index(item)))
- if madeAChange:
- self.undoRedoStack.add(beginActionGroup)
-
- def applyPenWidthEvt(self,event):
- if not self.testOrAcquireLock():
- return
- self.applyPenWidth()
- self.releaseLock()
-
- def penWidthChanged(self,event):
- if self.pendingPenWidthChange is not None:
- self.penWidthEntry.after_cancel(self.pendingPenWidthChange)
- self.pendingPenWidthChange = self.penWidthEntry.after(1000,self.applyPenWidth)
-
- def applyPenOptEvt(self,event):
- if not self.testOrAcquireLock():
- return
- self.applyPenOpt()
- self.releaseLock()
-
- def validatePenOpt(self):
- try:
- penTest = asyPen(self.penColor,self.penWidth,self.penOptEntry.get())
- return True
- except:
- self.penOptEntry.select_range(0,END)
- self.penOptEntry.delete(0,END)
- self.penOptEntry.insert(END,"Invalid Pen Options")
- self.penOptEntry.after(5000,self.clearInvalidOptEntry)
- self.penOptions = ""
- return False
-
- def clearInvalidOptEntry(self):
- self.penOptEntry.select_range(0,END)
- self.penOptEntry.delete(0,END)
-
- def applyPenOpt(self):
- if self.validatePenOpt():
- old = self.penOptions
- self.penOptions = self.penOptEntry.get()
- if old != self.penOptions:
- self.showCurrentPen()
-
- def undoOperation(self):
- self.undoRedoStack.undo()
-
- def redoOperation(self):
- self.undoRedoStack.redo()
-
- def resetStacking(self):
- for item in self.fileItems:
- self.raiseSomething(item,force=True)