
| Current Path : /home/cgabriel/20_dev/12_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/cgabriel/20_dev/12_procpy/dataninja/arrow.py |
import os
import sys
import re
import tkinter
import procpy
try:
import tkinter.ttk,Pmw,xmltodict,pdb # ,tkintertable
except:
import pip
pip.main(["install","pyttk"])
pip.main(["install","Pmw"])
pip.main(["install","pdb"])
# pip.main(["install","tkintertable"])
pip.main(["install","xmltodict"])
import tkinter.ttk,Pmw,xmltodict # ,tkintertable
#************************************************************************
class Arrow (object):
def __init__ (self,mode,canvas,block,jump,cond_string="",cond_anchor="",cond_pos=None,arrow_points=[]):
self.mode = mode
self.canvas = canvas
self.source_block = block # starting block
self.target_block = jump # block where the arrow ends up
self.arrowlines = []
self.color = 'black'
c1 = self.canvas.coords(self.source_block.elems['SHAPE'])
c2 = self.canvas.coords(self.target_block.elems['SHAPE'])
arrow_points = [ (c1[0] + c1[2])/2, (c1[1] + c1[3])/2 ] + arrow_points + [ (c2[0] + c2[2])/2, (c2[1] + c2[3])/2 ]
zaehler = 0
p0 = None
while (0 == 0):
try:
p = [ arrow_points[zaehler], arrow_points[zaehler+1] ]
except:
break
if p0:
self.arrowlines.append(self.canvas.create_arrow_line(p0[0],
p0[1],p[0],p[1],fill='black',width=procpy.config.ARROWTHICKNESS))
zaehler = zaehler + 2
p0 = p[:]
self.anchorline = int(len(self.arrowlines)/2)
self.fit_block_connections()
self.canvas.itemconfig(self.arrowlines[-1],arrow="last",arrowshape="8 10 3")
c = self.canvas.coords(self.arrowlines[self.anchorline])
self.text = tkinter.Text(self.canvas,wrap=tkinter.CHAR,font=("Courier",int(procpy.config.ARROW_DESCRIPTION_SIZE)),
borderwidth=0,insertborderwidth=0, height = 1, width = len(str(cond_string)))
#,bg="pink",highlightbackground="pink")
self.text.config(state=tkinter.NORMAL)
self.text.insert(tkinter.END,str(cond_string))
self.text.config(state=tkinter.DISABLED)
if not cond_pos:
cond_pos = [(c[0]+c[2])/2,(c[1]+c[3])/2]
cond_anchor = self.text_anchor(c)
self.window = self.canvas.create_window(cond_pos[0],cond_pos[1],anchor=cond_anchor,
window=self.text)
if not cond_string: # hides the text window if empty
self.canvas.itemconfig(self.window,state=tkinter.HIDDEN)
self.source_block.arrows_out.append(self)
self.target_block.arrows_in.append(self)
self.elem_bindings()
#***********************************************************************
def elem_bindings (self):
self.text.bind("<ButtonRelease-1>", self.release_button_event)
self.text.bind("<Key>",self.update_text_size)
for line in self.arrowlines:
for line1 in line:
self.canvas.tag_bind(line1, "<ButtonRelease-1>", self.release_button_event)
#***********************************************************************
def release_button_event (self,event):
print("arrow.release_button_event")
self.canvas.highlight_block(self.source_block)
self.target_block.release_button_event()
self.text.config(state=tkinter.NORMAL) # text widget
print("arrow.release_button_event.text widget")
self.text.focus_set()
self.text.mark_set("insert",tkinter.END)
#***********************************************************************
def dump (self):
coords = []
for line in self.arrowlines[:-1]:
coords.append(self.canvas.coords(line)[2:])
source_index = self.canvas.blocks.index(self.source_block)
target_index = self.canvas.blocks.index(self.target_block)
textpos = self.canvas.coords(self.window)
anchor = self.canvas.itemcget(self.window, "anchor")
return [source_index, target_index, self.text.get("1.0","end-1c"), textpos, anchor, coords]
#***********************************************************************
def update_text_size (self,event):
if event.keysym == "Delete":
return()
widget_width = 0
widget_height = float(event.widget.index(tkinter.END))-1
for line in event.widget.get("1.0", tkinter.END).split("\n"):
if len(line) > widget_width:
widget_width = len(line)+1
self.text.config(width=widget_width, height=widget_height)
#************************************************************************************
def check_logic(self):
if len(self.source_block.arrows_out)>1:
for arrow in self.source_block.arrows_out:
if not arrow.text.get("1.0",tkinter.END).isspace():
arrow.source_block.destroy(destroy_arrows=False) # clear old shape
arrow.source_block.generate_shape("i") # create new shape
return()
#***********************************************************************
def scale (self,fac):
for line in self.arrowlines:
coords = self.canvas.coords(line)
self.canvas.coords(line,coords[0]*fac,coords[1]*fac,coords[2]*fac,coords[3]*fac)
coords = self.canvas.coords(self.window)
self.canvas.coords(self.window,coords[0]*fac,coords[1]*fac)
self.text.config(font=('Courier',
int(self.canvas.zoom_factor*procpy.config.ARROW_DESCRIPTION_SIZE)))
#***********************************************************************
def destroy (self):
self.canvas.focus()
for line in self.arrowlines:
self.canvas.delete(line)
# self.canvas.delete(self.text)
self.canvas.delete(self.window)
self.source_block.arrows_out.remove(self)
self.target_block.arrows_in.remove(self)
#***********************************************************************
def highlight (self,color=None):
if color == None:
color = self.color
for line in self.arrowlines:
self.canvas.itemconfig(line,fill=color)
self.text.config(foreground=color)
self.canvas.itemconfig(self.window,state=tkinter.NORMAL)
#***********************************************************************
def text_anchor (self,coords):
if abs(coords[0] - coords[2]) < 3:
if coords[1] < coords[3]:
return(tkinter.W)
else:
return(tkinter.E)
elif coords[0] < coords[2]:
if abs(coords[1] - coords[3]) < 3:
return(tkinter.S)
elif coords[1] < coords[3]:
return(tkinter.SE)
else:
return(tkinter.SW)
else:
if abs(coords[1] - coords[3]) < 3:
return(tkinter.N)
elif coords[1] < coords[3]:
return(tkinter.NE)
else:
return(tkinter.NW)
#************************************************************************
# def shift (self,mode,dx,dy): # mode = 0/1: startline/lastline of the arrow will be shifted
# coords = self.canvas.coords(self.arrowlines[-mode]) # positioning of the endline
# coords[2*mode] = coords[2*mode] + dx
# coords[2*mode+1] = coords[2*mode+1] + dy
# self.canvas.coords(self.arrowlines[-mode],tuple(coords))
# self.fit_block_connections()
#************************************************************************
def fit_description (self,griddata=None):
c = self.canvas.coords(self.arrowlines[self.anchorline])
anchor = self.text_anchor(c)
p = [float(c[0]+c[2])/2,float(c[1]+c[3])/2]
self.canvas.coords(self.window,p[0],p[1])
self.canvas.itemconfig(self.window,anchor=anchor)
#************************************************************************
def fit_block_connections (self):
'''
Computes the (moveable) end-lines of the arrow
'''
if len(self.arrowlines) > 1: # two different endlines
source_point = self.canvas.coords(self.arrowlines[1])[:2] # getting the interpolation points
target_point = self.canvas.coords(self.arrowlines[-2])[-2:] # of both endlines
else: # if there is no extra interpolation point, then there is only one line, we have
source_point = target_point = self.get_shapes_mid_point() # to get an artificial interpolation point
source_coords = self.canvas.coords(self.arrowlines[0])[:]
source_coords[:2] = self.source_block.get_shape_connection_point(source_point)
self.canvas.coords(self.arrowlines[0], tuple(source_coords))
target_coords = self.canvas.coords(self.arrowlines[-1])[:]
target_coords[-2:] = self.target_block.get_shape_connection_point(target_point)
self.canvas.coords(self.arrowlines[-1], tuple(target_coords))
#************************************************************************
def get_shapes_mid_point (self):
(x0,y0,x1,y1,x,y,w,h) = self.source_block.box_coord()
p = self.target_block.get_shape_connection_point( [x,y] )
(x0,y0,x1,y1,x,y,w,h) = self.target_block.box_coord()
q = self.source_block.get_shape_connection_point( [x,y] )
return ( [ (p[0]+q[0])/2, (p[1]+q[1])/2 ] )
#************************************************************************
# def get_block_connection_point(self, block_coordinates, x, y):
#
# cx1, cy1, cx2, cy2 = block_coordinates
# fit_to_bounds = lambda bound_lower, p, bound_upper: min(max(bound_lower, p), bound_upper)
# return fit_to_bounds(cx1, x, cx2), fit_to_bounds(cy1, y, cy2)
#
#************************************************************************
def bounding_box (self,extbox): # the bounding box of the arrow object
coords = self.canvas.coords(self.arrowlines[0])
if not extbox:
extbox.append(coords[0])
extbox.append(coords[1])
extbox.append(coords[0])
extbox.append(coords[1])
else:
extbox[0] = min(extbox[0],coords[0])
extbox[1] = min(extbox[1],coords[1])
extbox[2] = max(extbox[2],coords[0])
extbox[3] = max(extbox[3],coords[1])
for arrowline in self.arrowlines:
coords = self.canvas.coords(arrowline)
extbox[0] = min(extbox[0],coords[2])
extbox[1] = min(extbox[1],coords[3])
extbox[2] = max(extbox[2],coords[2])
extbox[3] = max(extbox[3],coords[3])
return(extbox)
#************************************************************************
def move (self,dx,dy): # Move the entire arrow
for arrowline in self.arrowlines[1:-1]:
coords = self.canvas.coords(arrowline)[:]
coords = (coords[0]+dx,coords[1]+dy,coords[2]+dx,coords[3]+dy)
self.canvas.coords(arrowline, tuple(coords))
coords = self.canvas.coords(self.arrowlines[0])[:]
coords = (coords[0],coords[1],coords[2]+dx,coords[3]+dy)
self.canvas.coords(self.arrowlines[0], tuple(coords))
coords = self.canvas.coords(self.arrowlines[-1])[:]
coords = (coords[0]+dx,coords[1]+dy,coords[2],coords[3])
self.canvas.coords(self.arrowlines[-1], tuple(coords))
coords = self.canvas.coords(self.text)
self.canvas.coords(self.text,coords[0]+dx,coords[1])
self.fit_block_connections()
#************************************************************************
def check_loop (self,arrow_to_test=None,arrows=None):
print("enter check loop",arrows)
if not arrow_to_test:
arrow_to_test = self
arrows = set()
else:
if self == arrow_to_test:
return(True)
arrows.add(self)
for arrow in self.target_block.arrows_out:
if not arrow in arrows:
if arrow.check_loop(arrow_to_test,arrows):
return(True)
return(False)