1 |
import gi |
2 |
gi.require_version('Gtk', '3.0') |
3 |
from gi.repository import GdkPixbuf |
4 |
import ascpy |
5 |
import os.path |
6 |
import cairo |
7 |
|
8 |
|
9 |
class BlockType(): |
10 |
""" |
11 |
All data associated with the MODEL type that is represented by a block. |
12 |
This includes the actual ASCEND TypeDescription as well as the NOTES that |
13 |
are found to represent the inputs and outputs for this block, as well as |
14 |
some kind of graphical representation(s) for the block. In the canvas- |
15 |
based GUI, there will need to be a Cairo-based represention, for drawing |
16 |
on the canvas, as well as some other form, for creating the icon in the |
17 |
block palette. |
18 |
""" |
19 |
|
20 |
def __init__(self, typedesc, notesdb): |
21 |
self.type = typedesc |
22 |
self.notesdb = notesdb |
23 |
self.arrays = [] |
24 |
self.gr = [] # this data structure is for Graphical Representation for custom icons |
25 |
self.port_in = {} # this list is for location of input ports in custom icons |
26 |
self.port_out = {} # this list is for location of output ports in custom icons |
27 |
self.arrays = [] |
28 |
|
29 |
# FIXME BlockType should know what .a4c file to load in order to access |
30 |
# its type definition, for use in unpickling. |
31 |
self.sourcefile = None |
32 |
|
33 |
nn = notesdb.getTypeRefinedNotesLang(self.type, ascpy.SymChar("inline")) |
34 |
|
35 |
self.inputs = [] |
36 |
self.outputs = [] |
37 |
self.params = [] |
38 |
for n in nn: |
39 |
t = n.getText() |
40 |
if t[0:min(len(t),3)] == "in:": |
41 |
self.inputs += [[n.getId(), self.type.findMember(n.getId()), str(t)]] |
42 |
elif t[0:min(len(t),4)] == "out:": |
43 |
self.outputs += [[n.getId(), self.type.findMember(n.getId()), str(t)]] |
44 |
elif t[0:min(len(t),6)] == "param:": |
45 |
self.params += [[n.getId(), self.type.findMember(n.getId()), str(t)]] |
46 |
|
47 |
self.iconfile = None |
48 |
nn = notesdb.getTypeRefinedNotesLang(self.type, ascpy.SymChar("icon")) |
49 |
if nn: |
50 |
n = nn[0].getText() |
51 |
#if os.path.exists(os.path.join('.temp',n)): |
52 |
if os.path.exists(os.path.join('/~/.cache/ascend', n)): |
53 |
self.iconfile = n |
54 |
|
55 |
self.name = None |
56 |
nn = notesdb.getTypeRefinedNotesLang(self.type, ascpy.SymChar("block")) |
57 |
if nn: |
58 |
self.name = nn[0].getText() |
59 |
|
60 |
#fetching the graphic string from model file, string manipulating it and storing it in |
61 |
#list of list |
62 |
nn = notesdb.getTypeRefinedNotesLang(self.type, ascpy.SymChar("graphic")) |
63 |
if nn: |
64 |
t = nn[0].getText().split("\n") |
65 |
for n in t: |
66 |
temp = n.split("-") |
67 |
ll = [] |
68 |
for k in temp: |
69 |
tt = k.split(",") |
70 |
pp = [] |
71 |
for q in tt: |
72 |
q = q.strip("\t") |
73 |
pp.append(q) |
74 |
ll.append(pp) |
75 |
self.gr.append(ll) |
76 |
|
77 |
self.iconfile = self.create_icon(48,48) |
78 |
|
79 |
nn = notesdb.getTypeRefinedNotesLang(self.type, ascpy.SymChar("port_in")) |
80 |
if nn: |
81 |
n = nn[0].getText().split(" ") |
82 |
for m in n: |
83 |
tt = m.split("-") |
84 |
for k in tt: |
85 |
tpp = k.split(":") |
86 |
loc = tpp[1].split(",") |
87 |
xy = [] |
88 |
xy.append(loc[0]) |
89 |
xy.append(loc[1]) |
90 |
self.port_in[str(tpp[0])] = xy |
91 |
|
92 |
nn = notesdb.getTypeRefinedNotesLang(self.type, ascpy.SymChar("port_out")) |
93 |
if nn: |
94 |
n = nn[0].getText().split(" ") |
95 |
for m in n: |
96 |
tt = m.split("-") |
97 |
for k in tt: |
98 |
tpp = k.split(":") |
99 |
loc = tpp[1].split(",") |
100 |
xy = [] |
101 |
xy.append(loc[0]) |
102 |
xy.append(loc[1]) |
103 |
self.port_out[str(tpp[0])] = xy |
104 |
|
105 |
nn = notesdb.getTypeRefinedNotesLang(self.type, ascpy.SymChar("array")) |
106 |
for n in nn: |
107 |
if n: |
108 |
t = n.getText() |
109 |
self.arrays.append([t,self.type.findMember(t)]) |
110 |
#print self.arrays |
111 |
|
112 |
def get_icon(self, width, height): |
113 |
""" |
114 |
Get a pixbuf representation of the block for use in the block palette |
115 |
(or possibly elsewhere) |
116 |
""" |
117 |
f = self.iconfile |
118 |
if self.iconfile is None: |
119 |
f = "defaultblock.svg" |
120 |
return GdkPixbuf.Pixbuf.new_from_file_at_size(str(f), width, height) |
121 |
|
122 |
def create_icon(self, width, height): |
123 |
properties = self.gr |
124 |
if len(properties) == 0: |
125 |
return None |
126 |
# icon svg files are saved in .temp directory |
127 |
d = os.path.expanduser("~/.cache/ascend") |
128 |
if not os.path.exists(d): |
129 |
os.makedirs(d) |
130 |
#fo = file(".temp/%s.svg"%self.name,'w') |
131 |
fo = file(os.path.join(d,"%s.svg" % self.name), 'w') |
132 |
## Prepare a destination surface -> out to an SVG file! |
133 |
surface = cairo.SVGSurface(fo, width, height) |
134 |
c = cairo.Context(surface) |
135 |
for m in properties: |
136 |
c.move_to(float(m[0][0])*width*0.1, float(m[0][1])*height*0.1) |
137 |
for mm in m: |
138 |
c.line_to(float(mm[0])*width*0.1, float(mm[1])*height*0.1) |
139 |
c.stroke() |
140 |
surface.finish() |
141 |
return fo.name |
142 |
|
143 |
def __getstate__(self): |
144 |
state = self.__dict__.copy() |
145 |
state['type'] = str(self.type) |
146 |
state['notesdb'] = None |
147 |
state['inputs'] = [] |
148 |
state['outputs'] = [] |
149 |
state['params'] = [] |
150 |
#state['inputs'] = [[str(x) for x in self.inputs[i]] for i in range(len(self.inputs))] |
151 |
#state['outputs'] = [[str(x) for x in self.outputs[i]] for i in range(len(self.outputs))] |
152 |
#state['params'] = [[str(x) for x in self.params[i]] for i in range(len(self.params))] |
153 |
return (state) |
154 |
|
155 |
def __setstate__(self, state): |
156 |
self.__dict__ = state |
157 |
|
158 |
def reattach_ascend(self,library, notesdb): |
159 |
self.type = library.findType(self.type) |
160 |
|
161 |
nn = notesdb.getTypeRefinedNotesLang(self.type,ascpy.SymChar("inline")) |
162 |
|
163 |
self.inputs = [] |
164 |
self.outputs = [] |
165 |
self.params = [] |
166 |
for n in nn: |
167 |
t = n.getText() |
168 |
if t[0:min(len(t),3)] == "in:": |
169 |
self.inputs += [[n.getId(), self.type.findMember(n.getId()), str(t)]] |
170 |
elif t[0:min(len(t),4)] == "out:": |
171 |
self.outputs += [[n.getId(), self.type.findMember(n.getId()), str(t)]] |
172 |
elif t[0:min(len(t),6)] == "param:": |
173 |
self.params += [[n.getId(), self.type.findMember(n.getId()), str(t)]] |
174 |
|
175 |
print "Reattached type '%s', with %d inputs, %d outputs" % (self.type.getName(), len(self.inputs), len(self.outputs)) |
176 |
|
177 |
def get_input_name(self, index): |
178 |
return self.inputs[index].getText() |
179 |
|
180 |
def get_output_name(self, index): |
181 |
return self.outputs[index].getText() |