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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1939 - (show annotations) (download) (as text)
Thu Oct 30 02:38:43 2008 UTC (13 years, 8 months ago) by jpye
File MIME type: text/x-python
File size: 7337 byte(s)
Right-click context menu.
1 from __future__ import with_statement
2 import os, sys
3
4 os.chdir(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 print b.type.getName()
89
90 print "\t\tinputs:",[n.getId() for n in b.inputs]
91 for n in b.inputs:
92 print "\t\t\t%s: %s (type = %s)" % (n.getId(),n.getText(),n.getType())
93 print "\t\toutputs:",[n.getId() for n in b.outputs]
94 for n in b.outputs:
95 print "\t\t\t%s: %s" % (n.getId(),n.getText())
96
97
98 # render icon table
99 import threading
100 import gtk
101 import os, os.path, re
102
103 import cairo
104 from gaphas import GtkView, View
105 from gaphas.tool import HoverTool, PlacementTool, HandleTool, ToolChain
106 from gaphas.tool import Tool, ItemTool, RubberbandTool
107 from port import *
108
109 gtk.gdk.threads_init()
110
111 class BlockIconView(gtk.IconView):
112 def __init__(self,blocks,app):
113 # the mode containing the icons themselves...
114 self.model = gtk.ListStore(str, gtk.gdk.Pixbuf)
115 self.app = app
116 self.otank = {}
117 thread = threading.RLock()
118 n = 0
119 with thread:
120 for b in blocks:
121 n += 1
122 pixbuf = b.get_icon(64,64)
123 iter = self.model.append([b.type.getName(), pixbuf])
124 path = self.model.get_path(iter)
125 self.otank[path] = b
126
127 gtk.IconView.__init__(self)
128 self.set_model(self.model)
129 self.set_text_column(0)
130 self.set_pixbuf_column(1)
131 self.set_columns(-1)
132 self.set_size_request(180,100)
133 self.connect("item-activated", self.item_activated)
134 self.connect("selection-changed", self.selection_changed)
135 def item_activated(self,iconview,path):
136 b = self.otank[path]
137 self.app.status.push(0, "Activated '%s'..." % b.type.getName())
138 #view.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.CROSSHAIR))
139 self.app.set_placement_tool(b)
140
141 def selection_changed(self,iconview):
142 s = self.get_selected_items()
143 if len(s)==1:
144 b = self.otank[s[0]]
145 self.app.set_placement_tool(b)
146 self.app.status.push(0,"Selected '%s'..." % b.type.getName())
147
148 class ContextMenuTool(Tool):
149 """
150 Context menu for blocks and connectors on the canvas, intended to be
151 the main mouse-based way by which interaction with blocks occurs (blocks
152 renamed, parameters specified, values examined, etc).
153 Code for performing these tasks should not be here; this should just
154 hook into the appropriate code in the Application layer.
155 """
156 def __init__(self):
157 pass
158 def on_button_press(self, context, event):
159 if event.button != 3:
160 return False
161 if context.view.hovered_item:
162 menu = gtk.Menu()
163 menurename = gtk.MenuItem("Re_name",True);
164 menurename.connect("activate",self.rename)
165 menu.add(menurename)
166 menu.show_all()
167 menu.popup( None, None, None, event.button, event.time)
168
169 def rename(self,widget):
170 print "RENAMING OBJECT"
171
172 def BlockToolChain():
173 """
174 The default tool chain build from HoverTool, ItemTool and HandleTool.
175 """
176 chain = ToolChain()
177 chain.append(HoverTool())
178 chain.append(PortConnectingHandleTool())
179 chain.append(ContextMenuTool())
180 chain.append(ItemTool())
181 chain.append(RubberbandTool())
182 return chain
183
184 class app(gtk.Window):
185 def __init__(self):
186 self.status = gtk.Statusbar()
187
188 # the Gaphas canvas
189 canvas = BlockCanvas()
190
191 # the main window
192 gtk.Window.__init__(self)
193 self.set_title("ASCEND Blocks")
194 self.set_default_size(400, 500)
195 self.connect("destroy", gtk.main_quit)
196 self.connect("key-press-event", self.key_press_event)
197
198 # vbox containing the main view and the status bar at the bottom
199 vbox = gtk.VBox()
200
201 # hbox occupies top part of vbox, with icons on left & canvas on right.
202 hbox = gtk.HBox()
203
204 # the 'view' widget implemented by Gaphas
205 self.view = GtkView()
206 self.view.tool = BlockToolChain()
207
208 # table containing scrollbars and main canvas
209 t = gtk.Table(2,2)
210 self.view.canvas = canvas
211 self.view.zoom(1)
212 self.view.set_size_request(600, 500)
213 hs = gtk.HScrollbar(self.view.hadjustment)
214 vs = gtk.VScrollbar(self.view.vadjustment)
215 t.attach(self.view, 0, 1, 0, 1)
216 t.attach(hs, 0, 1, 1, 2, xoptions=gtk.FILL, yoptions=gtk.FILL)
217 t.attach(vs, 1, 2, 0, 1, xoptions=gtk.FILL, yoptions=gtk.FILL)
218
219 # a scrolling window to contain the icon palette
220 scroll = gtk.ScrolledWindow()
221 scroll.set_border_width(2)
222 scroll.set_shadow_type(gtk.SHADOW_ETCHED_IN)
223 scroll.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
224
225 # icon palette
226 self.blockiconview = BlockIconView(blocks, self)
227 scroll.add(self.blockiconview)
228
229 hbox.pack_start(scroll, True, True)
230 hbox.pack_start(t, True, True)
231 vbox.pack_start(hbox, True, True)
232 vbox.pack_start(self.status, False, False)
233 self.add(vbox)
234 self.show_all()
235
236 # a message about the found blocks
237 self.status.push(0, "Found %d block types." % (len(blocks)))
238
239 def set_placement_tool(self,block):
240 # TODO: add undo handler
241 label = block.type.getName()
242 def my_block_factory():
243 def wrapper():
244 b = DefaultBlock(label,inputs=len(block.inputs),outputs=len(block.outputs))
245 self.view.canvas.add(b)
246 return b
247 return wrapper
248 self.view.tool.grab(PlacementTool(my_block_factory(), HandleTool(), 2))
249
250 def key_press_event(self,widget,event):
251 # TODO: add undo handler
252 key = gtk.gdk.keyval_name(event.keyval)
253 if key == 'Delete' and self.view.focused_item:
254 self.view.canvas.remove(self.view.focused_item)
255 self.status.push(0,"Item deleted.")
256
257 a = app()
258 gtk.main()
259

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