/[ascend]/trunk/pygtk/canvas/blocklist.py
ViewVC logotype

Contents of /trunk/pygtk/canvas/blocklist.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1940 - (show annotations) (download) (as text)
Thu Oct 30 05:51:17 2008 UTC (13 years, 8 months ago) by jpye
File MIME type: text/x-python
File size: 7579 byte(s)
Lines can be drawn by pressing 'L' now.
Double-click to re-enable placement tool (still a problem with multiple-placement of blocks).
1 from __future__ import with_statement
2 import os, sys
3
4 os.chdir(os.path.abspath(os.path.dirname(sys.argv[0])))
5 os.environ['ASCENDLIBRARY'] = "../../models"
6 os.environ['LD_LIBRARY_PATH'] = "../.."
7 sys.path.append("..")
8
9
10 if sys.platform.startswith("win"):
11 # Fetchs gtk2 path from registry
12 import _winreg
13 import msvcrt
14 try:
15 k = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "Software\\GTK\\2.0")
16 except EnvironmentError:
17 # use TkInter to report the error :-)
18 from TkInter import *
19 root = Tk()
20 w = Label(root,"You must install the Gtk+ 2.2 Runtime Environment to run this program")
21 w.pack()
22 root.mainloop()
23 sys.exit(1)
24 else:
25 gtkdir = _winreg.QueryValueEx(k, "Path")
26 import os
27 # we must make sure the gtk2 path is the first thing in the path
28 # otherwise, we can get errors if the system finds other libs with
29 # the same name in the path...
30 os.environ['PATH'] = "%s/lib;%s/bin;" % (gtkdir[0], gtkdir[0]) + os.environ['PATH']
31
32 import ascpy
33
34 L = ascpy.Library()
35
36 # FIXME need to add way to add/remove modules from the Library?
37 L.load('test/canvas/blocktypes.a4c')
38
39 D = L.getAnnotationDatabase()
40
41 M = L.getModules()
42
43 blocktypes = set()
44
45 class Block:
46 def __init__(self, typedesc, notesdb):
47 self.type = typedesc
48 self.notesdb = notesdb
49
50 nn = notesdb.getTypeRefinedNotesLang(self.type,ascpy.SymChar("inline"))
51
52 self.inputs = []
53 self.outputs = []
54 for n in nn:
55 t = n.getText()
56 if t[0:min(len(t),3)]=="in:":
57 self.inputs += [n]
58 elif t[0:min(len(t),4)]=="out:":
59 self.outputs += [n]
60
61 def get_icon(self, width, height):
62 return gtk.gdk.pixbuf_new_from_file_at_size("defaultblock.svg",width,height)
63
64
65 for m in M:
66 T = L.getModuleTypes(m)
67 for t in T:
68 # 'block' types must not be parametric, because they must be able to
69 # exist even without being connected, and parametric models impose
70 # restrictions on the use of ARE_THE_SAME and similar.
71 if t.hasParameters():
72 continue
73 x = D.getNotes(t,ascpy.SymChar("block"),ascpy.SymChar("SELF"))
74 if x:
75 blocktypes.add(t)
76
77 blocks = []
78
79 print "block types:"
80 if not blocktypes:
81 print "NONE FOUND"
82 for t in blocktypes:
83
84 b = Block(t,D)
85
86 blocks += [b]
87
88 # render icon table
89 import threading
90 import gtk
91 import os, os.path, re
92
93 import cairo
94 from gaphas import GtkView, View
95 from gaphas.tool import HoverTool, PlacementTool, HandleTool, ToolChain
96 from gaphas.tool import Tool, ItemTool, RubberbandTool
97 from port import *
98
99 gtk.gdk.threads_init()
100
101 class BlockIconView(gtk.IconView):
102 """
103 IconView containing the palette of Block available for use in the
104 canvas. The list of blocks is supplied currently as an initialisation
105 parameter, but it is intended that this would be dynamic in a final system.
106
107 It should be possible drag icons from the palette into the canvas, but
108 that is not yet implemented.
109 """
110 def __init__(self,blocks,app):
111 # the mode containing the icons themselves...
112 self.model = gtk.ListStore(str, gtk.gdk.Pixbuf)
113 self.app = app
114 self.otank = {}
115 thread = threading.RLock()
116 n = 0
117 with thread:
118 for b in blocks:
119 n += 1
120 pixbuf = b.get_icon(64,64)
121 iter = self.model.append([b.type.getName(), pixbuf])
122 path = self.model.get_path(iter)
123 self.otank[path] = b
124
125 gtk.IconView.__init__(self)
126 self.set_model(self.model)
127 self.set_text_column(0)
128 self.set_pixbuf_column(1)
129 self.set_columns(-1)
130 self.set_size_request(180,100)
131 self.connect("item-activated", self.item_activated)
132 self.connect("selection-changed", self.selection_changed)
133
134 def selection_changed(self,iconview):
135 s = self.get_selected_items()
136 if len(s)==1:
137 b = self.otank[s[0]]
138 self.app.set_placement_tool(b)
139
140 def item_activated(self,iconview, path):
141 self.app.set_placement_tool(self.otank[path])
142
143 class ContextMenuTool(Tool):
144 """
145 Context menu for blocks and connectors on the canvas, intended to be
146 the main mouse-based way by which interaction with blocks occurs (blocks
147 renamed, parameters specified, values examined, etc).
148 Code for performing these tasks should not be here; this should just
149 hook into the appropriate code in the Application layer.
150 """
151 def __init__(self):
152 pass
153 def on_button_press(self, context, event):
154 if event.button != 3:
155 return False
156 if context.view.hovered_item:
157 menu = gtk.Menu()
158 menurename = gtk.MenuItem("Re_name",True);
159 menurename.connect("activate",self.rename)
160 menu.add(menurename)
161 menu.show_all()
162 menu.popup( None, None, None, event.button, event.time)
163
164 def rename(self,widget):
165 print "RENAMING OBJECT"
166
167
168
169 def BlockToolChain():
170 """
171 The default tool chain build from HoverTool, ItemTool and HandleTool.
172 """
173 chain = ToolChain()
174 chain.append(HoverTool())
175 chain.append(PortConnectingHandleTool())
176 chain.append(ContextMenuTool())
177 chain.append(ItemTool())
178 chain.append(RubberbandTool())
179 return chain
180
181 class app(gtk.Window):
182 def __init__(self):
183 self.status = gtk.Statusbar()
184
185 # the Gaphas canvas
186 canvas = BlockCanvas()
187
188 # the main window
189 gtk.Window.__init__(self)
190 self.set_title("ASCEND Blocks")
191 self.set_default_size(400, 500)
192 self.connect("destroy", gtk.main_quit)
193 self.connect("key-press-event", self.key_press_event)
194
195 # vbox containing the main view and the status bar at the bottom
196 vbox = gtk.VBox()
197
198 # hbox occupies top part of vbox, with icons on left & canvas on right.
199 hbox = gtk.HBox()
200
201 # the 'view' widget implemented by Gaphas
202 self.view = GtkView()
203 self.view.tool = BlockToolChain()
204
205 # table containing scrollbars and main canvas
206 t = gtk.Table(2,2)
207 self.view.canvas = canvas
208 self.view.zoom(1)
209 self.view.set_size_request(600, 500)
210 hs = gtk.HScrollbar(self.view.hadjustment)
211 vs = gtk.VScrollbar(self.view.vadjustment)
212 t.attach(self.view, 0, 1, 0, 1)
213 t.attach(hs, 0, 1, 1, 2, xoptions=gtk.FILL, yoptions=gtk.FILL)
214 t.attach(vs, 1, 2, 0, 1, xoptions=gtk.FILL, yoptions=gtk.FILL)
215
216 # a scrolling window to contain the icon palette
217 scroll = gtk.ScrolledWindow()
218 scroll.set_border_width(2)
219 scroll.set_shadow_type(gtk.SHADOW_ETCHED_IN)
220 scroll.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
221
222 # icon palette
223 self.blockiconview = BlockIconView(blocks, self)
224 scroll.add(self.blockiconview)
225
226 hbox.pack_start(scroll, True, True)
227 hbox.pack_start(t, True, True)
228 vbox.pack_start(hbox, True, True)
229 vbox.pack_start(self.status, False, False)
230 self.add(vbox)
231 self.show_all()
232
233 # a message about the found blocks
234 self.status.push(0, "Found %d block types." % (len(blocks)))
235
236 def set_placement_tool(self,block):
237 # TODO: add undo handler
238 label = block.type.getName()
239 def my_block_factory():
240 def wrapper():
241 b = DefaultBlock(label,inputs=len(block.inputs),outputs=len(block.outputs))
242 self.view.canvas.add(b)
243 return b
244 return wrapper
245 self.view.tool.grab(PlacementTool(my_block_factory(), HandleTool(), 2))
246 self.status.push(0,"Selected '%s'..." % block.type.getName())
247
248 def set_connector_tool(self):
249 def my_line_factory():
250 def wrapper():
251 l = Line()
252 self.view.canvas.add(l)
253 return l
254 return wrapper
255 self.view.tool.grab(PlacementTool(my_line_factory(), HandleTool(), 1))
256
257 def key_press_event(self,widget,event):
258 # TODO: add undo handler
259 key = gtk.gdk.keyval_name(event.keyval)
260 if key == 'Delete' and self.view.focused_item:
261 self.view.canvas.remove(self.view.focused_item)
262 self.status.push(0,"Item deleted.")
263 elif key == 'l' or key == 'L':
264 self.set_connector_tool()
265 self.status.push(0,"Line draw mode...")
266
267 a = app()
268 gtk.main()
269

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22