
| Current Path : /home/ift/52_procpy/dataninja/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : //home/ift/52_procpy/dataninja/gui_file.py |
import os,re,sys,time,math,tkinter,codecs,procpy
import procpy.block
import procpy.arrow
import procpy.rearr_grid
# import procpy.procobj
try:
import tkinter.ttk,Pmw,xmltodict,json,svgwrite # ,tkintertable
except:
import pip
pip.main(["install","pyttk"])
pip.main(["install","Pmw"])
pip.main(["install","tkintertable"])
pip.main(["install","xmltodict"])
pip.main(["install","json"])
pip.main(["install","svgwrite"])
import tkinter.ttk,Pmw,xmltodict,json,svgwrite # ,tkintertable
import tkinter.filedialog
#**************************************************************************
class Gui_file (tkinter.Frame):
def init (self,filename,gui):
self.filename = filename
self.gui = gui
self.loopobj = gui.loopobj
self.db = procpy.mysqlite.DBConn({'type':'sqlite','name':':memory:'})
self.saved_yet = 0
self.current_zoom_factor = 1.0
self.moffset = 1
self.fontsize_buttons = 8
self.griddata = { "SHOW": False, "SNAP": False,"OFFSETX": 0.0,"OFFSETY": 0.0,
"X": procpy.config.STARTGRIDX,
"Y": procpy.config.STARTGRIDY } # the grid for blocks
self.hl_block_0 = None
self.hl_block = None
self.hl1 = None
self.hl2 = None
self.color_blocks = "#96C7E8"# light blue # wenn leer, Farbe aus dem gml-File
self.color_startbl = "#ff00ff"# rosa
self.color_endbl = "#00ffff"# cyan
self.color_highlight_column = "#0069AF"# navy blue
self.color_reportbar = "#6DA5D5"# light blue
self.snap = { 'OBJX': 0, 'OBJY': 0, 'GRIDX': 0, 'GRIDY': 0 }
self.groupby = "PATH"
self.sortfield = "COUNT"
self.sortupper = 0
self.blocks = [] # key-values: function : block
self.colors = {}
self.loopobj.app.bind("<Delete>",self.delete_highlighted_element)
self.mainframe = tkinter.PanedWindow(self,orient=tkinter.VERTICAL)
self.mainframe.pack(expand=tkinter.TRUE,fill=tkinter.BOTH)
self.main_h = self.mainframe.winfo_height()
self.main_w = self.mainframe.winfo_width()
self.upperframe = tkinter.Frame(self.mainframe,height=self.main_h*0.672, width=self.main_w)
self.lowerframe = tkinter.Frame(self.mainframe,height=self.main_h*(1-0.672),width=self.main_w)
self.upperframe.pack()
self.lowerframe.pack()
return()
# self.mainframe.add(self.upperframe)
# self.mainframe.add(self.lowerframe)
self.buttonframe = tkinter.Frame(self.upperframe,width=120)
self.buttonframe_top = tkinter.Frame(self.buttonframe)
self.buttonframe_bottom = tkinter.Frame(self.buttonframe)
self.buttonframe_top.pack(side=tkinter.TOP,expand=tkinter.TRUE,fill=tkinter.Y)
self.buttonframe_bottom.pack(side=tkinter.BOTTOM)
self.buttonframe_left = tkinter.Frame(self.buttonframe_top)
self.buttonframe_right = tkinter.Frame(self.buttonframe_top)
self.buttonframe_left.pack(side=tkinter.LEFT,expand=tkinter.TRUE,fill=tkinter.Y)
self.buttonframe_right.pack(side=tkinter.LEFT,expand=tkinter.TRUE,fill=tkinter.Y)
self.runcounter = tkinter.Entry(self.buttonframe_left,width=6)
self.runcounter.insert(0,"1")
self.runcounter.pack()
self.startbutton = tkinter.Button(self.buttonframe_left,text="Start",width=6,
command=self.start_process,font=("Arial",self.fontsize_buttons))
self.startbutton.pack()
self.stopbutton = tkinter.Button(self.buttonframe_left,text="Stop",width=6,
command=self.stop_process,font=("Arial",self.fontsize_buttons))
self.stopbutton.pack()
self.resetbutton = tkinter.Button(self.buttonframe_left,text="0",width=6,bg="yellow",
command=self.reset_process_data,font=("Arial",self.fontsize_buttons))
self.resetbutton.pack()
tkinter.Frame(self.buttonframe_left).pack(expand=tkinter.TRUE,fill=tkinter.Y)
self.speedbutton = tkinter.Button(self.buttonframe_left,text="Speed",width=6,
command=self.reset_speed,font=("Arial",self.fontsize_buttons))
self.speedbutton.pack()
self.miniview_w = 120
self.miniview_h = 100
self.miniview = tkinter.Canvas(self.buttonframe_bottom,width=self.miniview_w,height=self.miniview_h)
self.miniview.pack()
self.speedruler_h = 200
self.speedruler = tkinter.Scale(self.buttonframe_right,from_=1000,to=1,length=self.speedruler_h)
self.reset_speed()
self.speedruler.pack(expand=tkinter.TRUE,fill=tkinter.Y)
self.graphframe = tkinter.Frame(self.upperframe)
self.graphframe.pack(side=tkinter.LEFT,expand=tkinter.TRUE,fill=tkinter.BOTH)
self.buttonframe.pack(side=tkinter.LEFT,fill=tkinter.Y)
self.width_scrollbars = 8
self.graphcanvas = tkinter.Canvas(self.graphframe, width=self.gui.app_w-120, height=self.main_h*0.672, bg="white")
self.xscroll = tkinter.Scrollbar(self.graphframe,orient=tkinter.HORIZONTAL)
self.yscroll = tkinter.Scrollbar(self.graphframe,orient=tkinter.VERTICAL)
self.xscroll.config(command=self.graphcanvas.xview,width=self.width_scrollbars)
self.yscroll.config(command=self.graphcanvas.yview,width=self.width_scrollbars)
self.graphcanvas.config(xscrollcommand=self.xscroll.set)
self.graphcanvas.config(yscrollcommand=self.yscroll.set)
self.xscroll.pack(side=tkinter.BOTTOM,fill=tkinter.X)
self.yscroll.pack(side=tkinter.RIGHT,fill=tkinter.Y)
self.graphcanvas.pack(side=tkinter.LEFT,expand=tkinter.TRUE,fill=tkinter.BOTH)
# self.blockeditframe = Tkinter.Frame(self.upperframe,width=120)
self.reportcanvas = tkinter.Canvas(self.lowerframe)
self.uscroll = tkinter.Scrollbar(self.lowerframe,orient=tkinter.HORIZONTAL)
self.vscroll = tkinter.Scrollbar(self.lowerframe,orient=tkinter.VERTICAL)
self.uscroll.config(command=self.reportcanvas.xview,width=self.width_scrollbars)
self.vscroll.config(command=self.reportcanvas.yview,width=self.width_scrollbars)
self.reportcanvas.config(xscrollcommand=self.uscroll.set)
self.reportcanvas.config(yscrollcommand=self.vscroll.set)
self.uscroll.pack(side=tkinter.BOTTOM,fill=tkinter.X)
self.vscroll.pack(side=tkinter.RIGHT,fill=tkinter.Y)
self.reportcanvas.pack(side=tkinter.LEFT,expand=True,fill=tkinter.BOTH)
# self.reportcanvas.config(scrollregion=(0,0,100,800)) # len(self.header_comboboxes)*200))
self.actual_report_columns = []
self.header_comboboxes = []
self.click_target = None
def set_click_target(type):
self.click_target = type
text = ""
if os.path.isfile(self.filename):
text = open(self.filename).read()
else:
text = self.save_graphics()
self.load_graphics(text,0)
self.reset_drawdata()
self.mouse_x = 0 # mouse event coords
self.mouse_y = 0
self.allow_context_menu = True
self.current_zoom_level = 1.0
self.graphcanvas.pack()
self.fit_scrollbar()
return(self.mainframe)
#************************************************************************************
#Task: swim lanes ovelapping with blocks
# Issue and Solution
def load_graphics (self,text,mode):
#self.graphcanvas.delete("all")
self.saved_yet = 1
#-------------------------------
#Issue: The mouse events to create swim lanes and blocks was bound on the background
#of the rectangle item/tag inside the Canvas. Therefore the swin lanes was moved
#behind rectangle rather than behind the blocks, when the method tag_lower was use on them inside the module Block.
#--------------------------------
#self.background = self.graphcanvas.create_rectangle(0,0,999999,999999,fill='white')
#self.background="yellow"
#self.graphcanvas.create_rectangle(0,0,99,99,fill='white')
#self.graphcanvas.tag_bind(self.background,"<ButtonRelease-1>", self.release_button)
#self.graphcanvas.tag_bind(self.background,"<Double-Button-1>", self.create_block)
#self.graphcanvas.tag_bind(self.background,"<B1-Motion>", self.move_mouse)
#----------------------------------
#Solution part 1: I have bound the mouse events on the Canvas, Part 2 in the module Block.
self.graphcanvas.config(background="white")
self.graphcanvas.bind("<ButtonRelease-1>", self.release_button)
self.graphcanvas.bind("<Double-Button-1>", self.create_block)
self.graphcanvas.bind("<B1-Motion>", self.move_mouse)
#---------------------------------------------------------------
exec(text) # here the program code of the process file is read
exec(self.__module__ + ".PROC = PROC") # new definition of the class PROC in gui_file
obj = PROC() # generate an object of the new class
self.vars = {}
funcs = {}
jumps = {}
for fkt in PROC.__dict__: # draw blocks
try:
obj.__dict__ = { '_FKT_': fkt } # make a new obj.__dict__ , and store the fkt in _FKT_
PROC.__dict__[fkt](obj) # execution of the next funtion in the __dict__ of the class
obj.BLOCK # check whether BLOCK variable exists
except Exception as e: # otherwise do not proceed
continue
block = procpy.block.Block(mode,self,obj)
block.fit_content()
self.blocks.append(block)
for var in block.vars:
self.vars[var] = 1
# Standard format for JUMP: { 'fkt1' : [ 'condition', bend1_x, bend1_y, bend2_x, .... ] }
if not 'JUMP' in vars(obj) or obj.JUMP == '': # conversions to the JUMP-variable
obj.JUMP = {} # no jump # to enable lazy coding of the process files
elif type(obj.JUMP) == type(''): # JUMP = 'fkt1' -> { 'fkt1' : [0] }
obj.JUMP = { obj.JUMP : [0] }
elif type(obj.JUMP) == type([]):
obj.JUMP = { obj.JUMP[0] : [0] + obj.JUMP[1:] } # JUMP = ['fkt1',x1,y1,...] ->
jumps[block] = obj.__dict__ # { 'fkt1' : [0,x1,y1,....] }
funcs[fkt] = block
for block in jumps: # draw arrows
for jump in jumps[block]['JUMP']:
arrdata = jumps[block]['JUMP'][jump]
if not type(arrdata) == type([]): # 'lazy' issue: see above
arrdata = [ arrdata ]
procpy.arrow.Arrow(mode,self,block,funcs[jump],arrdata)
self.vars = list(self.vars.keys()) # all variables for reporting section
self.vars.sort()
for block in self.blocks: #final adjustment of block shape to all the arrows
if not block.shape == 'a':
block.fit_content('x')
self.fit_scrollbar()
#************************************************************************************
def fit_scrollbar(self):
'''
guarantees a minimal size of scrollregion and
includes all blocks in the scrollregion
'''
max_X = 1000
max_Y = 300
for block in self.blocks:
max_X = max(max_X, max(block.bbox[0],block.bbox[2]))
max_Y = max(max_Y, max(block.bbox[1],block.bbox[3]))
self.graphcanvas.config(scrollregion = (0,0,max_X+100,max_Y+100))
#************************************************************************************
def hl_block_ok (self):
if not self.hl_block == None:
if self.hl_block.sync_content_to_fkt_and_text() == -1:
self.hl_block.syntax_error = 1
return(False)
return(True)
#************************************************************************************
def save_graphics (self):
if not self.hl_block_ok():
return()
self.saved_yet = 1
# text = '''# -*- coding: utf-8 -*- this causes problems with exec
text = '''
import procpy
class PROC (object):
def __init__ (self,*pars):
self.pars = list(pars)
self.JUMP = ''' + "'---FUNC---'" + '''
'''
blocks_data = []
max_varlen = 0
self.blocks.sort(key=lambda block: block.nr)
for block in self.blocks: # First run through the blocks
varlen = block.get_varlen()
max_varlen = max(max_varlen,abs(varlen))
if block.nr == 0 and block.shape is not 'a': # if the block has no predecessor, then it is a starting block, dont include swimlanes
text = re.sub(r"---FUNC---",block.fkt,text)
for block in self.blocks: # Second run through the blocks
text = text + '''
def ''' + block.fkt + ''' (self):
'''
block.fit_content() # necessary because the content of the blocks have to be written into header and text
for item in block.get_vars():
if item[0] == 'JUMP': # replace block object refs in arrow to fkt names
jumpval = {}
for jump in item[1]:
jumpval[jump.fkt] = item[1][jump]
item[1] = jumpval
if item[0] == 'JUMP' and not bool(jumpval): # only write down if jump-block exists
text = text+ "\n"
else:
text = text + " self." + (item[0]+" "*max_varlen)[0:max_varlen] + " = " + json.dumps(item[1]) + "\n"
text = re.sub(r"\"([\d\.]+)\"","\\1",text,999999)
exec(text)
exec(self.__module__ + ".PROC = PROC")
# self.gui.filemenu.entryconfig("Save",state="disabled")
return(text)
#************************************************************************************
def check_whether_point_is_inside_of_a_block (self,x=-1,y=-1):
'''
Returns the maximal width and height of all blocks,
if the point (x,y) is not inside of any block.
Otherwise it returns the fkt of the block.
'''
bbox_w = 0
bbox_h = 0
for block in self.blocks:
if block.bbox[0] < x and x < block.bbox[2] and block.bbox[1] < y and y < block.bbox[3]:
return(None,block)
bbox_w = max(bbox_w,block.bbox[2]-block.bbox[0])
bbox_h = max(bbox_h,block.bbox[3]-block.bbox[1])
return(bbox_w,bbox_h)
#************************************************************************************
def create_block (self,event):
### get the real canvas position, not the window position of the event
try:
x = self.graphcanvas.canvasx(event.x)
y = self.graphcanvas.canvasy(event.y)
except: # for testing, event is only a list object
x = event[0]
y = event[1]
self.saved_yet = 0
if not self.hl_block_ok():
return()
self.after(250,self.create_block_1)
(bbox_w,bbox_h) = procpy.config.CREATE_BLOCK_SIZE
bbox_w = bbox_w * self.current_zoom_factor
bbox_h = bbox_h * self.current_zoom_factor
obj = PROC()
obj.JUMP = {}
zaehler = -1
for block in self.blocks:
m = re.search(r"^t(\d+)$",block.fkt)
if m:
zaehler = max(zaehler,int(m.group(1)))
newfkt = "t" + ("%02u" % (zaehler+1)) # commented in prod2 -> error: global name 'newfkt' is not defined, newfkt replaced with t00; switched back in task_runprocess
if type(event) == type([]): # Test-Interface
if len(event) == 2:
event.append(bbox_w)
if len(event) == 3:
event.append(bbox_h)
obj.BLOCK = [newfkt, event[0],event[1],event[2],event[3]]
else:
obj.BLOCK = [newfkt,x,y,bbox_w,bbox_h]
obj._FKT_ = newfkt # 't00'
if obj.BLOCK[1] < obj.BLOCK[3]/2:
obj._FKT_ = "LANE0"
block = procpy.block.Block(0,self,obj)
if 'not_valid' in vars(block):
return()
self.blocks.append(block)
self.graphcanvas.pack()
self.fit_scrollbar()
if self.griddata['SNAP']:
# self.rearr_sugiyama(0.5)
self.rearr_grid(0.2)
self.last_event = None
#***************************************************************************************
def create_block_1 (self):
if self.hl2:
self.hl_block = self.hl2
self.hl2 = None
self.hl_block.highlight_block(0)
#************************************************************************************
def create_arrow (self):
self.saved_yet = 0
if not self.hl_block_ok(): # highlighted block has to carry valid python code
return()
if self.hl_block and self.hl_block.shape == "a" or self.hl_block_0 and self.hl_block_0.shape == "a":
return() # do not draw arrows to and from swimlane blocks
fkt = None
jump = None
for block in self.blocks:
if not fkt and block == self.hl_block_0:
fkt = block
if not jump and block == self.hl_block:
jump = block
if fkt and jump:
break
if not fkt:
fkt = jump
if jump:
if fkt:
create_the_arrow = True
if fkt == jump: # don t create the arrow if source and target are identical
create_the_arrow = False
# count = 1
for arrow in fkt.arrows_out: # check all the out arrows from fkt whether there
if arrow.target_block == jump: # is already an arrow between fkt and jump. in case
create_the_arrow = False # don t provide any new arrow
break
# count +=1 # count the arrows of this block for calculation of condition-string for creating the arrow
# # this is not needed anymore as soon as the user can chose the condition manually (editable arrows)
if create_the_arrow:
condition = 50 #round(100/count)
jump.hl_arrow = procpy.arrow.Arrow(0,self,fkt,jump,[condition])
fkt.fit_content("x")
jump.fit_content("x")
else:
self.hl_block_0 = self.hl_block
self.hl_block = None
return()
self.rearr_grid(0.2,1)
#************************************************************************************
def press_button (self,event):
self.x0 = event.x
self.y0 = event.y
self.i0 = int((self.x0-self.griddata['OFFSETX']+3)/self.griddata['X'])
self.j0 = int((self.y0-self.griddata['OFFSETY']+3)/self.griddata['Y'])
if self.i0 == 0 or self.j0 == 0:
self.i0 = 0
self.j0 = 0
#************************************************************************************
def move_mouse (self,event):
if 'x0' in vars(self):
(dx,dy) = (event.x-self.x0,event.y-self.y0)
if self.i0 > 0: # changing of the grid dimensions
(xquot,yquot) = (1.0/(self.x0-self.griddata['OFFSETX']),1.0/(self.y0-self.griddata['OFFSETY']))
else: # changing of the offstes
(dx_rel,dy_rel) = (dx,dy)
for line in self.grid_lines:
coords = self.graphcanvas.coords(line)
if coords[0] == coords[2]: # vertical line
if self.i0 > 0:
dx_rel = dx * (coords[2]-self.griddata['OFFSETX']) * xquot
self.graphcanvas.coords(line,coords[0]+dx_rel,coords[1],coords[2]+dx_rel,coords[3])
elif coords[1] == coords[3]: # horizontal line
if self.j0 > 0:
dy_rel = dy * (coords[3]-self.griddata['OFFSETY']) * yquot
self.graphcanvas.coords(line,coords[0],coords[1]+dy_rel,coords[2],coords[3]+dy_rel)
(self.x0,self.y0) = (event.x,event.y)
#************************************************************************************
def release_button (self,event):
if not self.hl_block_ok():
return()
self.hl2 = self.hl1
self.hl1 = self.hl_block
self.hl_block = None
self.hl_block_0 = None
#************************************************************************************
def release_line (self,event):
if self.i0 == 0:
self.griddata['OFFSETX'] = event.x
self.griddata['OFFSETY'] = event.y
else:
self.griddata['X'] = (event.x - self.griddata['OFFSETX'])/self.i0
self.griddata['Y'] = (event.y - self.griddata['OFFSETY'])/self.j0
del self.x0
del self.i0
del self.y0
del self.j0
#************************************************************************************
def delete_highlighted_element (self,event):
if not self.hl_block_ok():
return()
self.saved_yet = 0
if self.hl_block:
arrow = self.hl_block.hl_arrow
if arrow: # delete arrow
block = arrow.source_block
jump = arrow.target_block
block.arrows_out.remove(arrow)
jump.arrows_in.remove(arrow)
arrow.destroy()
self.hl_block.hl_arrow = None
self.num_blocks(jump)
self.hl_block = None
self.hl_block_0 = None
else: # delete block
self.hl_block.destroy()
for arrow in self.hl_block.arrows_out:
self.num_blocks(arrow.target_block)
self.blocks.remove(self.hl_block)
self.hl_block = None
self.hl_block_0 = None
#************************************************************************************
def num_blocks (self,jump): # numerate a block
self.num_blocks_0(jump,999999) # 1. set the block and all ancestors to highest level
self.num_blocks_0(jump,0) # 2. now compute lower levels by arrows
if jump.nr == 999999:
self.num_blocks_0(jump,1) # 3. if jump.nr remains highest level, then number it with 1.
#************************************************************************************
def num_blocks_0 (self,block,nr,touched_blocks=None): # determines the minimum level of a block
if touched_blocks == None:
touched_blocks = {}
for arrow in block.arrows_in:
if nr == 0:
nr = 999999
nr = min(arrow.source_block.nr+1,nr)
if not block in touched_blocks:
touched_blocks[block] = block.nr
block.nr = nr
block.fit_content("x")
for arrow in block.arrows_out:
jump = arrow.target_block
self.num_blocks_0(jump,min(nr+1,999999),touched_blocks)
#************************************************************************************
def toggle_show_grid (self):
if self.griddata['SHOW']:
for line in self.grid_lines:
self.graphcanvas.delete(line)
self.grid_lines = []
self.griddata['SHOW'] = False
else:
bbox = self.get_bounding_box()
maxx = max(bbox[2],self.graphcanvas.winfo_width())
maxy = max(bbox[3],self.graphcanvas.winfo_width())
self.grid_lines = []
x = self.griddata['X']
while x < maxx:
self.grid_lines.append(self.graphcanvas.create_line(x,0,x,maxy,width=1,fill="magenta",dash=(2,5)))
x = x + self.griddata['X']
y = self.griddata['Y']
while y < maxy:
self.grid_lines.append(self.graphcanvas.create_line(0,y,maxx,y,width=1,fill="magenta",dash=(2,5)))
y = y + self.griddata['Y']
for line in self.grid_lines:
self.graphcanvas.tag_bind(line,"<ButtonPress-1>", self.press_button)
self.graphcanvas.tag_bind(line,"<B1-Motion>", self.move_mouse)
self.graphcanvas.tag_bind(line,"<ButtonRelease-1>", self.release_line)
self.griddata['SHOW'] = True
self.gui.switch_tab()
#************************************************************************************
def grid_select (self,l,event):
(x,y) = self.check_whether_point_is_inside_of_a_block()
if x:
(self.gx,self.gy) = (event.x,event.y)
else:
self.gx = None
#************************************************************************************
def grid_move (self,event):
dx = event.x - self.gx
dy = event.y - self.gy
#************************************************************************************
def toggle_snap_grid (self):
if self.griddata['SNAP']:
self.griddata['SNAP'] = False
else:
self.griddata['SNAP'] = True
self.gui.switch_tab()
#************************************************************************************
def fit_blocks_to_grid (self):
g = self.griddata
for block in self.blocks:
x = g['X'] * int((block.bbox[0] - g['OFFSETX'] + 0.5*g['X'])/g['X'])
y = g['Y'] * int((block.bbox[1] - g['OFFSETY'] + 0.5*g['Y'])/g['Y'])
dx = block.bbox[0] - x - g['OFFSETX']
dy = block.bbox[1] - y - g['OFFSETY']
block.newbbox = [ block.bbox[0] - dx, block.bbox[1] - dy,
block.bbox[2] - dx, block.bbox[3] - dy ]
#************************************************************************************
def rearrange_blocks(self): # arranges block without overlap
block_coordinates = []
for block in self.blocks:
i,j = block.gridpos()
while self.check_gridpos_empty(i,j,block_coordinates)==False:
i,j = block.gridpos(i,j+1)
block_coordinates.append([i,j])
#************************************************************************************
def check_gridpos_empty(self,coord1,coord2,block_coordinates):
i = coord1
j = coord2
return not([i,j] in block_coordinates or [i+1,j] in block_coordinates or [i-1,j] in block_coordinates)
#************************************************************************************
def rearr_grid (self,move_interval,b=0):
self.rearrange_blocks()
procpy.rearr_grid.Rearr_grid(self).newbends_for_arrows()
self.positioning(move_interval)
self.fit_scrollbar()
#************************************************************************************
def rearr_grid_arrows_with_sugiyama (self,move_interval):
for block in self.blocks:
block.gridpos()
procpy.rearr_sugiyama.Rearr_sugiyama(self,0).arrows_sugiyama_fit()
self.positioning(move_interval)
#************************************************************************************
def rearr_sugiyama (self,move_interval):
procpy.rearr_sugiyama.Rearr_sugiyama(self,0).blocks_sugiyama_fit()
procpy.rearr_sugiyama.Rearr_sugiyama(self,0).arrows_sugiyama_fit()
self.positioning(move_interval)
#************************************************************************************
def rearr_circle (self,move_interval):
(maxw,maxh) = (0,0)
for block in self.blocks:
(maxw,maxh) = (max(maxw,block.bbox[2]-block.bbox[0]),
max(maxh,block.bbox[3]-block.bbox[1]))
anzahl = float(len(self.blocks))
radiusx = maxw * math.log(anzahl) * 1.5
radiusy = maxh * math.log(anzahl) * 1.5
zaehler = anzahl
self.blocks.sort(key=lambda block: block.nr)
for block in self.blocks:
block.newbbox = [0,0,0,0]
block.newbbox[0] = radiusx * (1.1+math.cos(math.pi*zaehler/anzahl))
block.newbbox[1] = radiusy * (1.1+math.sin(math.pi*zaehler/anzahl))
block.newbbox[2] = block.newbbox[0] + block.bbox[2] - block.bbox[0]
block.newbbox[3] = block.newbbox[1] + block.bbox[3] - block.bbox[1]
zaehler = zaehler + 2
for arrow in block.arrows_out:
arrow.newbends = []
arrow.anchorline = 0
self.positioning(move_interval)
#************************************************************************************
def rearr_swimlane (self,move_interval):
swimlanes = {} # Collecting and sorting the swimlanes
for swimlane in self.blocks:
if swimlane.shape == "a":
swimlanes[ ("%09.4f" % swimlane.bbox[1]) + "-" + ("%09.4f" % swimlane.bbox[3]) ] = swimlane
swkeys = list(swimlanes.keys())
swkeys.sort()
dy = 0 # shift to down
miny = 0 # limit in height for swimlane
all_arrows = []
for block in self.blocks:
block.newbbox = block.bbox[:]
for arrow in block.arrows_in:
all_arrows.append(arrow)
arrow.newbends = []
for arrowline in arrow.arrowlines[:-1]:
coords = self.graphcanvas.coords(arrowline)
arrow.newbends.append([coords[2],coords[3]])
for swkey in swkeys:
swimlane = swimlanes[swkey]
dy = max(0,miny - swimlane.bbox[1])
swimlane.newbbox = [0,0,0,0,0]
swimlane.newbbox[1] = swimlane.bbox[1] + dy
swimlane.newbbox[2] = swimlane.bbox[2] - swimlane.bbox[0]
swimlane.newbbox[3] = swimlane.bbox[3] + dy
miny = swimlane.newbbox[3]
# (blocks,arrows,singlepoints) = swimlane.blocks_and_arrows_in_swimlane()
(blocks,arrows,singlepoints) = (swimlane.move_blocks,swimlane.move_arrows,swimlane.move_singlepoints)
for block in blocks:
block.newbbox[1] = block.bbox[1] + dy
block.newbbox[3] = block.bbox[3] + dy
for arrow in arrows:
all_arrows.remove(arrow)
zaehler = 0
for arrowline in arrow.arrowlines[:-1]:
arrow.newbends[zaehler][1] = arrow.newbends[zaehler][1] + dy
zaehler = zaehler + 1
for point in singlepoints:
if point[2] == 0 and point[1] > 0:
arrow = point[0]
arrow.newbends[point[1]-1][1] = arrow.newbends[point[1]-1][1] + dy
self.positioning(move_interval)
#************************************************************************************
#************************************************************************************
def positioning (self,move_interval=3.0,max_rounds=100):
duetime = time.clock() + move_interval
zaehler = 0
gesamt_time = 0
nr = max_rounds
if 'semaphore_positioning_in_progress' in vars(self):
return()
self.semaphore_positioning_in_progress = True
# 1. Preparation: Absolute to relative values, extend arrows if necessary
maxshift = 0
for block in self.blocks: # shift the absolute coordinates to relative
fkt = block.fkt
bbox = block.bounding_box() # and add - if needed - helper bends in arrows
if 'newbbox' in vars(block):
block.newbbox = [block.newbbox[0]-block.bbox[0],block.newbbox[1]-block.bbox[1],
block.newbbox[2]-block.bbox[2],block.newbbox[3]-block.bbox[3]]
else:
block.newbbox = [0,0,0,0]
maxshift = max(maxshift,abs(block.newbbox[0]),abs(block.newbbox[1]),
abs(block.newbbox[2]),abs(block.newbbox[3]))
for arrow in block.arrows_out:
if not 'newbends' in vars(arrow):
continue
# jump = arrow.target_block
bends = arrow.newbends
lines = arrow.arrowlines
zaehler = 1
for bend in bends:
if len(lines) == 1: # if no bend is in arrow
(x,y) = arrow.get_shapes_mid_point()
coords = self.graphcanvas.coords(lines[0])
self.graphcanvas.coords(lines[0],x,y,coords[2],coords[3])
lines.insert(-1,self.graphcanvas.create_line(coords[0],coords[1],x,y,
fill='black',width=procpy.config.ARROWTHICKNESS))
while len(lines) < zaehler+1: # extend arrow bends to match the count of new bends
coords = self.graphcanvas.coords(lines[-1])
lines.insert(-1,self.graphcanvas.create_line(coords[0],coords[1],coords[0],coords[1],
fill='black',width=procpy.config.ARROWTHICKNESS))
coords = self.graphcanvas.coords(lines[zaehler])
bend[0] = bend[0] - coords[0]
bend[1] = bend[1] - coords[1]
maxshift = max(maxshift,abs(bend[0]),abs(bend[1]))
zaehler = zaehler + 1
# self.gui.mark("B")
# 2. Morphing arrows in a loop step by step
while nr > 0:
time0 = time.clock()
for block in self.blocks:
if 'newbbox'in vars(block):
(dx0,dy0,dx1,dy1) = ( block.newbbox[0]/nr, block.newbbox[1]/nr, block.newbbox[2]/nr, block.newbbox[3]/nr )
block.newbbox = [ block.newbbox[0] - dx0, block.newbbox[1] - dy0,
block.newbbox[2] - dx1, block.newbbox[3] - dy1 ]
block.bbox = [ block.bbox[0] + dx0, block.bbox[1] + dy0, block.bbox[2] + dx1, block.bbox[3] + dy1 ]
block.fit_content()
for block in self.blocks:
for arrow in block.arrows_out:
if not 'newbends' in vars(arrow):
continue
zaehler1 = 0
while (0 == 0):
px = None
try:
c_line1 = self.graphcanvas.coords(arrow.arrowlines[zaehler1+1])
except:
break
c_line0 = self.graphcanvas.coords(arrow.arrowlines[zaehler1])
try:
bend = arrow.newbends[zaehler1]
(dx,dy) = ( bend[0]/nr, bend[1]/nr )
bend[0] = bend[0] - dx
bend[1] = bend[1] - dy
(px,py) = ( c_line1[0], c_line1[1] )
except Exception as e: # if no new bend definition is available anymore
if not px:
(px,py) = arrow.get_shapes_mid_point()
(dx,dy) = ( (px-c_line0[2])/nr, (py-c_line0[3])/nr )
self.graphcanvas.coords(arrow.arrowlines[zaehler1],
c_line0[0], c_line0[1], c_line0[2]+dx, c_line0[3]+dy)
self.graphcanvas.coords(arrow.arrowlines[zaehler1+1],
c_line1[0]+dx, c_line1[1]+dy, c_line1[2], c_line1[3] )
zaehler1 = zaehler1 + 1
bbox = self.get_bounding_box()
arrow.fit_block_connections()
arrow.fit_description() # self.griddata)
self.graphcanvas.update()
bbox = self.get_bounding_box()
xdim = self.graphcanvas.winfo_width()
ydim = self.graphcanvas.winfo_height()
# self.gui.mark(str(nr))
zaehler = zaehler + 1 # count runs
time0 = time.clock() - time0 # time for this loop run
gesamt_time = gesamt_time + time0
rest_time = duetime - time.clock() # Computing runs /waittime to match
avg_time = gesamt_time/zaehler # the interval for this action
if rest_time > 0 :
wait_time = rest_time/nr - avg_time
if wait_time > 0:
time.sleep(wait_time)
nr = nr-1
else:
nr = min( int(rest_time/avg_time), nr-1 )
nr = max(1,nr)
else:
nr = min(2,nr-1)
# self.gui.mark("C")
bbox = self.get_bounding_box()
xdim = self.graphcanvas.winfo_width()
ydim = self.graphcanvas.winfo_height()
self.graphcanvas.config(scrollregion=(0,0,max(xdim,bbox[2]),max(ydim,bbox[3])))
# 3. Deleting superfluous bends in arrows at end of moving
for block in self.blocks:
for arrow in block.arrows_out:
if not 'newbends' in vars(arrow):
continue
lines = arrow.arrowlines
try:
soll_len = len(arrow.newbends) + 1
except:
continue
c_line0 = None
while soll_len < len(lines):
c_line0 = self.graphcanvas.coords(lines[-2])
self.graphcanvas.delete(lines.pop(-2))
if c_line0:
c_line1 = self.graphcanvas.coords(lines[-1])
self.graphcanvas.coords(lines[-1],c_line0[0],c_line0[1],c_line1[2],c_line1[3])
arrow.fit_description(self.griddata)
del arrow.newbends
try:
del block.newbbox
except:
pass
# 4. now at last a re-fitting is necessary
for block in self.blocks:
for arrow in block.arrows_out:
arrow.fit_block_connections()
self.graphcanvas.update()
del self.semaphore_positioning_in_progress
return(True)
#************************************************************************************
def reset_speed (self):
self.speedruler.set(950)
#************************************************************************************
def get_bounding_box (self):
bbox = []
for block in self.blocks:
block.bounding_box(bbox)
for jump in block.arrows_in:
jump.bounding_box(bbox)
return(bbox)
#************************************************************************************
def set_zoomfaktor (self,fac): # fac: factor to zoom, if = -1/ -2/ -3: fit to width, height resp. canvas
xdim = self.graphcanvas.winfo_width()
ydim = self.graphcanvas.winfo_height()
if fac < 0 and fac > -4: # fit to page width resp. height resp. canvas
self.graphcanvas.update()
bbox = self.get_bounding_box()
fakx = float(xdim) / float(bbox[2]) # - bbox[0])
faky = float(ydim) / float(bbox[3]) # - bbox[1])
if fac == -3 and fakx < faky:
fac = -1
elif fac == -3:
fac = -2
fac = 0.96 * [fakx,faky][-fac-1]
elif self.hl_block and not self.hl_block.shape == "a":
self.hl_block.zoom_text(fac)
return()
self.current_zoom_factor = self.current_zoom_factor * fac
for block in self.blocks:
block.scale(fac)
bbox = self.get_bounding_box()
self.graphcanvas.config(scrollregion=(0,0,max(xdim,bbox[2]/0.96),max(ydim,bbox[3]/0.96)))
self.griddata['X'] = fac * self.griddata['X']
self.griddata['Y'] = fac * self.griddata['Y']
if self.griddata['SHOW']:
self.toggle_show_grid()
self.toggle_show_grid()
#************************************************************************************
def sortcols (self,event):
canvas = event.widget
x = canvas.canvasx(event.x)
y = canvas.canvasy(event.y)
fieldnr = int(x)/160
field = self.actual_report_columns[fieldnr]
if self.sortfield == field:
self.sortupper = (self.sortupper + 1) % 4
else:
self.sortupper = 0
self.sortfield = field
self.draw_report_bars()
#**************************************************************************
def compute_report_data (self,entry):
try:
group0 = entry.SUMVALUES[self.groupby]
except:
pass #group0 =
try:
group0 = str(float(group))
except:
pass
for group in [group0,"__gesamt__"]:
try:
self.counts[group] += 1
except:
self.counts[group] = 1
self.sumvalues[group] = {}
if not group == "__gesamt__":
self.maxcount = max(self.counts[group],self.maxcount)
for field in self.report_fields:
if field == "COUNT":
continue
if field == "":
continue
try:
self.sumvalues[group]
except:
self.sumvalues[group] = {}
try:
self.sumvalues[group][field]
except:
self.sumvalues[group][field] = 0
try:
self.maxvalues[field]
except:
self.maxvalues[field] = 0
try:
val = entry.SUMVALUES[field]
except:
val = "0"
try:
val = float(val)
self.sumvalues[group][field] += val
if not group == "__gesamt__":
self.maxvalues[field] = max(self.maxvalues[field],val)
except:
self.sumvalues[group][field] = val
self.draw_data = []
for group in self.sumvalues:
data_row = {}
for field in self.report_fields:
if field == "COUNT":
data_row[field] = [self.counts[group],self.maxcount]
else:
val = self.sumvalues[group][field]
try:
val = float(val) / self.counts[group]
except Exception as e:
pass
data_row[field] = [val,self.maxvalues[field]]
if group == "__gesamt__":
self.draw_data_gesamt = data_row
else:
self.draw_data.append(data_row)
#****************************************************
def draw_report_headers (self,reason_for_call=1):
new_columns = []
for header_combobox in self.header_comboboxes:
header_text = header_combobox.get()
if not header_text == "":
new_columns.append(header_text)
new_columns.append("")
if not self.actual_report_columns == new_columns:
o1 = len(self.actual_report_columns)
o2 = len(new_columns)
if not o2 == o1:
if o2 < o1:
while o2 < len(self.header_comboboxes):
self.header_comboboxes[-1].destroy()
del self.header_comboboxes[-1]
else:
newcombo = tkinter.ttk.Combobox(self.reportcanvas,width=12,font=("Arial",8))
self.reportcanvas.create_window((o2-1)*160+20,5,anchor=tkinter.NW,window=newcombo)
if o1 == 0:
newcombo.insert(0,'PATH')
newcombo.config(state='readonly')
if o1 == 1:
newcombo.insert(0,'COUNT')
newcombo.config(state='readonly')
else:
newcombo.config(postcommand=self.draw_report_headers)
# newcombo.config(validatecommand=self.draw_report,validate='all')
self.header_comboboxes.append(newcombo)
self.reportcanvas.config(scrollregion=(0,0,len(self.header_comboboxes)*160,10))
self.actual_report_columns = new_columns
zaehler = 0
option_values = self.vars + [""]
for column_text in self.actual_report_columns:
self.header_comboboxes[zaehler].delete(0,9999)
self.header_comboboxes[zaehler].insert(0,column_text)
if column_text in ['PATH','COUNT']:
self.header_comboboxes[zaehler].config(values=[])
else:
self.header_comboboxes[zaehler].config(values=option_values)
zaehler = zaehler + 1
if 'draw_data' in vars(self):
self.draw_report_bars()
self.reportcanvas.config(scrollregion=(0,0,len(self.header_comboboxes)*160,10))
if len(self.actual_report_columns) < 3:
return(self.draw_report_headers())
#****************************************************
def draw_report_bars (self):
# nr = self.report_fields_nr[self.sortfield]
if self.sortfield == 'COUNT':
self.draw_data.sort(key=lambda x: x['COUNT']+x['PATH'], reverse=(self.sortupper%2==0))
else:
self.draw_data.sort(key=lambda x: x[self.sortfield], reverse=(self.sortupper%2==0))
self.draw_data1 = [self.draw_data_gesamt] + self.draw_data
self.reportcanvas.delete("reportbar")
row = 1
cellh = 12
cellw = 160
x0 = 0
y0 = 2*cellh
y0 = 3*cellh
gesamtzeile = True # first line is the total/average data line
for ergrow in self.draw_data1:
x0 = 0
y0 = y0 + cellh
for field in self.actual_report_columns[0:-1]:
if gesamtzeile and field == self.sortfield:
xpos = x0+2
ypos = y0-int(2.7*cellh)
color_sort = "yellow"
if self.sortupper%2 == 0: # compute and draw sort marker
ypos = ypos - 10
color_sort = "red"
self.reportcanvas.create_oval(xpos,ypos,xpos+4,ypos+4,fill=color_sort,tag='reportbar')
fillcolor = procpy.config.COLOR_REPORTBAR
val = ergrow[field][0]
gval = ergrow[field][1]
if gesamtzeile:
fillcolor = 'grey'
if field == 'PATH':
val = "TOTAL / AVERAGE"
try:
val1 = float(val)/float(gval)
if not (gesamtzeile and field == "COUNT"):
o = self.reportcanvas.create_rectangle(x0+5,
y0-12,
x0+5+val1*(cellw-40),
y0-2,
fill=fillcolor,tag='reportbar')
self.reportcanvas.tag_bind(o,'<ButtonPress-1>',lambda event: self.sortcols(event) )
val = int(val)
except:
pass
if field == 'COUNT' and self.sortupper > 1:
if gesamtzeile:
relative_val = val
else:
val = '%3.1f' % (100 * float(val) / float(relative_val) ) + '%'
o = self.reportcanvas.create_text(x0+6,y0,text=str(val),anchor='sw',font=("Arial",8),
tag=['reportbar',field])
self.reportcanvas.tag_bind(o,'<ButtonPress-1>',lambda event: self.sortcols(event) )
x0 = x0 + cellw
gesamtzeile = False
self.reportcanvas.config(scrollregion=(0,0,len(self.header_comboboxes)*160,y0+15))
#***************************************************************************************
def start_process(self):
if self.saved_yet == 0:
self.save_graphics()
self.startbutton.config(state='disable')
self.hl_block = None
o = self.runcounter.get()
self.runcounter.delete(0,10)
if int(o) < 1:
self.runcounter.insert(0,"1")
self.startbutton.config(state='normal')
return(0)
self.runcounter.insert(0,str(int(o)-1))
o = self.resetbutton.config('text')[-1]
self.resetbutton.config(text=str(int(o)+1))
self.block_list = {}
self.hl_blocks = {}
self.steps = {}
for block in self.blocks:
self.graphcanvas.itemconfig(block.elems['SHAPE'],fill=self.color_blocks)
if block.shape == 'a':# swimlanes are not counted in block_list
pass
else:
self.block_list[block.fkt] = block
if not self.block_list: # if there are no blocks, stop process
self.stop_process()
return()
self.loopobj.after(0,self.proceed_process,self.__module__+".PROC")
#***************************************************************************************
def proceed_process (self,mode="START",pars=[]):
proc_instance = procpy.prcmanager.Prcmanager(self.db).run_process(mode,pars)
speedfactor = 5**(int(self.speedruler.get())/100-1)
if proc_instance:
self.entry = proc_instance
obj = proc_instance.OBJID
fkt = proc_instance.__func__
sleeptime = str(proc_instance.TIME)
if obj in self.hl_blocks:
id = self.hl_blocks[obj]
self.block_list[id].content.config(bg=self.color_blocks,highlightcolor=self.color_blocks)
self.block_list[id].contentframe.config(background=self.color_blocks,bg=self.color_blocks,
highlightcolor=self.color_blocks)
self.graphcanvas.itemconfig(self.block_list[id].elems['SHAPE'],fill=self.color_blocks) # <----
try:
fillcolor1 = "red"
self.block_list[fkt].content.config(bg=fillcolor1,highlightcolor=fillcolor1) # color the content
self.block_list[fkt].contentframe.config(background=fillcolor1,bg=fillcolor1,
highlightcolor=fillcolor1) # color the contentframe
self.graphcanvas.itemconfig(self.block_list[fkt].elems['SHAPE'],fill=fillcolor1) # color the outer rectangle
self.hl_blocks[obj] = fkt
except Exception as e:
pass
print(str(e))
if int(sleeptime) < 9999999900: # Prozess laeuft weiter
self.loopobj.after(max( 50,int(sleeptime)*1000/speedfactor),self.proceed_process,'___dryrun___')
return()
self.compute_report_data(self.entry) # Daten des beendeten Prozesses gehen
self.draw_report_headers() # in das Reporting ein
self.draw_report_bars()
# self.runobj = procpy.caller.Scripts()
self.loopobj.after(max(35,int(1000/speedfactor)),self.del_all_highlighting)
self.loopobj.after(max(70,int(2000/speedfactor)),self.start_process)
#****************************************************
def stop_process (self):
o = self.runcounter.get()
self.runcounter.delete(0,10)
self.runcounter.insert(0,"1")
self.del_all_highlighting()
self.startbutton.config(state='normal')
#****************************************************
def reset_process_data (self):
self.reset_drawdata()
self.reportcanvas.delete('reportbar')
#****************************************************
def reset_drawdata (self):
self.resetbutton.config(text='0')
self.report_fields = ['PATH','COUNT'] + self.vars
self.counts = {}
self.maxcount = 0
self.sumvalues = {}
self.maxvalues = {}
self.draw_report_headers()
# self.field_expression = {}
# for field in self.report_fields:
# if re.search(r"[^A-Za-z0-9\_]",field):
# self.field_expression[field] = re.sub(r"([A-Z][A-Za-z0-9\_]*)","float(entry.\\1)",field,99999999)
# else:
# self.field_expression[field] = "entry." +field
#
#****************************************************
def del_all_highlighting (self):
self.saved_yet = 0
fillcolor1 = self.color_blocks
for block in self.blocks:
block.content.config(bg=fillcolor1,highlightcolor=fillcolor1) # color the content
block.contentframe.config(background=fillcolor1,bg=fillcolor1,highlightcolor=fillcolor1) # color the contentframe
self.graphcanvas.itemconfig(block.elems['SHAPE'],fill=fillcolor1) # color the outer rectangle
#****************************************************
def show_menu(self, event,):
if self.allow_context_menu:
type = self.graphcanvas.type(event.widget.find_withtag("current"))
if self.click_target == None or type == None:
background_menu = tkinter.Menu(self.graphcanvas, tearoff=0)
background_menu.add_command(label="New block", command= lambda :self.create_block(event.x_root, event.y_root))
background_menu.post(event.x_root, event.y_root)
elif self.click_target.__class__ is procpy.block.Block:
block_menu = tkinter.Menu(self.graphcanvas, tearoff=0)
block_menu.add_command(label="New arrow", command=lambda : self.create_arrow(self.click_target))
block_menu.post(event.x_root, event.y_root)
#************************************************************************************
#************************************************************************************
def xxscale_texts (self,fac): # scale texts
for block in self.blocks:
block.scale_texts(fac)
for arrow in block.arrows_out:
arrow.scale_texts(fac)
self.current_zoom_factor = self.current_zoom_factor * fac
#************************************************************************************
def xxset_zoomfaktor (self,fac,draw_new=True):
xdim = self.graphcanvas.winfo_width()
ydim = self.graphcanvas.winfo_height()
if fac < 0 and fac > -4: # fit to page width resp. height resp. canvas
self.graphcanvas.update()
bbox = self.get_bounding_box()
fakx = xdim / (bbox[2] - bbox[0])
faky = ydim / (bbox[3] - bbox[1])
if fac == -1:
fak = fakx
elif fac == -2:
fak = faky
else:
fak = min(fakx,faky)
self.graphcanvas.scale("all",0,0,fak,fak)
"""for fkt in self.blocks[fkt]:
block = self.blocks[fkt]
old_size = self.graphcanvas.itemcget(block.text,'text')
new_size = self.graphcanvas.itemconfig(block.text,font=('Arial',old_size*fak)
for fkt in self.arrows:
for jump in self.arrows[fkt][jump]"""
bbox = self.get_bounding_box()
self.graphcanvas.config(scrollregion=(bbox[0],bbox[1],max(bbox[2],bbox[0]+xdim)+1,max(bbox[3],bbox[1]+ydim)+1))
# for fkt in self.blocks[fkt]:
# block = self.blocks[fkt]
# old_size = self.graphcanvas.itemcget(block.text,'text')
# new_size = self.graphcanvas.itemconfig(block.text,font=('Arial',old_size*fak)
# for fkt in self.arrows:
# for jump in self.arrows[fkt][jump]
# elif fac == -5:
# if self.fak == -1:
# fac = -7
# else:
# fac = -9
## if fac == -7: # toggle back to graph view
# self.fak = self.fit
#
# elif fac == -9: # presentation as a textfield for the pycode
# self.fak = -1
#
elif fac > 0:
bbox = self.get_bounding_box()
self.graphcanvas.scale("all",0,0,fac,fac)
bbox = self.get_bounding_box()
# bx = bbox[2] - bbox[0] + 20
# by = bbox[3] - bbox[1] + 20
# bbox = self.get_bounding_box()
# print (bbox[0],bbox[1],max(bbox[2],bbox[0]+xdim),max(bbox[3],bbox[1]+ydim))
self.graphcanvas.config(scrollregion=(bbox[0],bbox[1],max(bbox[2],bbox[0]+xdim)-1,max(bbox[3],bbox[1]+ydim)-1))
# self.graphcanvas.config(scrollregion=(0,0,bbox[2]+20,bbox[3]+15))
# faknew = self.fak * fac
# if True:
## if (faknew > fakx or faknew > faky) and faknew < 10*max(fakx,faky):
# self.fak = faknew
# self.fit = faknew
# else:
# return()
#
# try:
# if self.fak < self.fak0 * (1 + 0.00001) and self.fak > self.fak0 * (1 - 0.00001):
# return
# except:
# pass
# self.fak0 = self.fak
# self.draw_bpm()
#************************************************************************************
def xxdraw_miniview (self):
fakx = self.miniview_w / (self.pd.w())
faky = self.miniview_h / (self.pd.h())
self.draw_graphics(self.miniview,min(fakx,faky),self.moffset,False)
#************************************************************************************
def xxdraw_bpm (self):
if self.fak < 0:
pycode = self.pd.text
else:
self.graphcanvas_w = self.fak * (self.pd.w())
self.graphcanvas_h = self.fak * (self.pd.h())
print(self.graphcanvas_w)
print(self.graphcanvas_h)
try:
self.graphcanvas.destroy()
except:
pass
try:
self.xscroll.destroy()
except:
pass
try:
self.yscroll.destroy()
except:
pass
if self.fak < 0:
self.graphcanvas = tkinter.Frame(self.graphframe)
self.graphcanvas.pack(expand=tkinter.TRUE,fill=tkinter.BOTH)
self.graphtext = tkinter.Text(self.graphcanvas,wrap=tkinter.NONE,width=10,height=10)
self.graphtext.pack(expand=True,fill=tkinter.BOTH)
self.graphtext.insert(tkinter.END,pycode)
else:
self.graphcanvas = tkinter.Canvas(self.graphframe)
self.graphcanvas.config(scrollregion=(0,0,self.graphcanvas_w,self.graphcanvas_h))
self.xscroll = tkinter.Scrollbar(self.graphframe,orient=tkinter.HORIZONTAL)
self.yscroll = tkinter.Scrollbar(self.graphframe,orient=tkinter.VERTICAL)
self.xscroll.config(command=self.graphcanvas.xview,width=8)
self.yscroll.config(command=self.graphcanvas.yview,width=8)
self.graphcanvas.config(xscrollcommand=self.xscroll.set)
self.graphcanvas.config(yscrollcommand=self.yscroll.set)
self.xscroll.pack(side=tkinter.BOTTOM,fill=tkinter.X)
self.yscroll.pack(side=tkinter.RIGHT,fill=tkinter.Y)
self.graphcanvas.pack(side=tkinter.LEFT,expand=True,fill=tkinter.BOTH)
# create a menu
#self.initUI()
#Moving canvas with mouse not working at the moment with moving with items
#self.graphcanvas.bind("<ButtonPress-1>", self.move_start)
#self.graphcanvas.bind("<B1-Motion>", self.move_move)
#Add zoom function with mousewheel
# linux
self.graphcanvas.bind("<Button-4>", self.zoomerP)
self.graphcanvas.bind("<Button-5>", self.zoomerM)
# windows
self.graphcanvas.bind("<MouseWheel>", self.zoomer)
if self.fak > 0:
self.draw_graphics(self.graphcanvas,self.fak,self.offset,True)
#************************************************************************************
def xxdraw_graphics (self,graph_widget,fak,offset,with_text=False):
graph_widget.config(background='white')
self.sources = {} # The arrow lists of the blocks where the arrows are sources
self.targets = {} # The arrow lists of the blocks where the arrows are targets
for fkt in self.pd.funcs: # process all the blocks
self.sources[fkt] = []
self.targets[fkt] = []
x = fak * ( self.pd.x(fkt) - self.pd.x0() ) + offset
y = fak * ( self.pd.y(fkt) - self.pd.y0() ) + offset
w = fak * self.pd.w(fkt)
h = fak * self.pd.h(fkt)
# self.blocks[fkt] = graph_widget.create_rectangle(
# int(x-w/2),int(y-h/2),
# int(x+w/2),int(y+h/2),fill=self.color_blocks)
block_size = (int(x-w/2),int(y-h/2),int(x + w / 2),int(y+h/2))
self.blocks[fkt] = Box(graph_widget,fkt,self.color_blocks,block_size)
if with_text:
#o1 = self.graphcanvas.create_text(int(x-w/2),int(y-h/2),anchor=Tkinter.NW,
# text=fkt,font=("ARIAL",6))
#o2 = self.graphcanvas.create_text(int(x),int(y),anchor=Tkinter.CENTER,
# text=self.pd.prg(fkt),font=("ARIAL",7))
self.blocks[fkt].create_text((int(x-w/2),int(y-h/2)),tkinter.NW,fkt,6)
self.blocks[fkt].create_text((int(x),int(y)), tkinter.CENTER, self.pd.prg(fkt), 7)
# self.graphcanvas.tag_bind(o,'<ButtonPress-1>',self.make_text_fkt(node) )
self.colors[fkt] = self.color_blocks
for fkt in self.pd.funcs: # draw the arrows:
for ziel in self.pd.data[fkt]['JUMP']: # process all the edges
self.pd.data[fkt]['JUMP'][ziel][1:]
arrow = [self.pd.x(fkt),self.pd.y(fkt)] + self.pd.data[fkt]['JUMP'][ziel][1:] + [self.pd.x(ziel),self.pd.y(ziel)]
p0 = None
zaehler = 0
while (0 == 0):
try:
p = [ arrow[zaehler], arrow[zaehler+1] ]
except:
break
zaehler = zaehler + 2
x = fak * ( p[0] - self.pd.x0() ) + offset
y = fak * ( p[1] - self.pd.y0() ) + offset
if p0:
#o = graph_widget.create_line(int(p0[0]),int(p0[1]),int(x),int(y),fill='black')
arrow_size = (int(p0[0]),int(p0[1]),int(x),int(y))
self.blocks[fkt].create_arrow(arrow_size,"black",ziel)
self.blocks[ziel].set_arrow_from(fkt+":"+ziel)
#self.sources[fkt].append(o)
#self.targets[fkt].append(o)
p0 = [x,y]
#if with_text:
#graph_widget.create_oval(x-1.5,y-1.5,x+1.5,y+1.5,fill="black")