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