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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1942 - (show annotations) (download) (as text)
Tue Nov 4 07:19:26 2008 UTC (13 years, 7 months ago) by jpye
File MIME type: text/x-python
File size: 7600 byte(s)
Adding pan/zoom capability to the canvas.
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(ZoomTool())
179 chain.append(PanTool())
180 chain.append(RubberbandTool())
181 return chain
182
183 class app(gtk.Window):
184 def __init__(self):
185 self.status = gtk.Statusbar()
186
187 # the Gaphas canvas
188 canvas = BlockCanvas()
189
190 # the main window
191 gtk.Window.__init__(self)
192 self.set_title("ASCEND Blocks")
193 self.set_default_size(400, 500)
194 self.connect("destroy", gtk.main_quit)
195 self.connect("key-press-event", self.key_press_event)
196
197 # vbox containing the main view and the status bar at the bottom
198 vbox = gtk.VBox()
199
200 # hbox occupies top part of vbox, with icons on left & canvas on right.
201 hbox = gtk.HBox()
202
203 # the 'view' widget implemented by Gaphas
204 self.view = GtkView()
205 self.view.tool = BlockToolChain()
206
207 # table containing scrollbars and main canvas
208 t = gtk.Table(2,2)
209 self.view.canvas = canvas
210 self.view.zoom(1)
211 self.view.set_size_request(600, 500)
212 hs = gtk.HScrollbar(self.view.hadjustment)
213 vs = gtk.VScrollbar(self.view.vadjustment)
214 t.attach(self.view, 0, 1, 0, 1)
215 t.attach(hs, 0, 1, 1, 2, xoptions=gtk.FILL, yoptions=gtk.FILL)
216 t.attach(vs, 1, 2, 0, 1, xoptions=gtk.FILL, yoptions=gtk.FILL)
217
218 # a scrolling window to contain the icon palette
219 scroll = gtk.ScrolledWindow()
220 scroll.set_border_width(2)
221 scroll.set_shadow_type(gtk.SHADOW_ETCHED_IN)
222 scroll.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
223
224 # icon palette
225 self.blockiconview = BlockIconView(blocks, self)
226 scroll.add(self.blockiconview)
227
228 hbox.pack_start(scroll, True, True)
229 hbox.pack_start(t, True, True)
230 vbox.pack_start(hbox, True, True)
231 vbox.pack_start(self.status, False, False)
232 self.add(vbox)
233 self.show_all()
234
235 # a message about the found blocks
236 self.status.push(0, "Found %d block types." % (len(blocks)))
237
238 def set_placement_tool(self,block):
239 # TODO: add undo handler
240 label = block.type.getName()
241 def my_block_factory():
242 def wrapper():
243 b = DefaultBlock(label,inputs=len(block.inputs),outputs=len(block.outputs))
244 self.view.canvas.add(b)
245 return b
246 return wrapper
247 self.view.tool.grab(PlacementTool(my_block_factory(), HandleTool(), 2))
248 self.status.push(0,"Selected '%s'..." % block.type.getName())
249
250 def set_connector_tool(self):
251 def my_line_factory():
252 def wrapper():
253 l = Line()
254 self.view.canvas.add(l)
255 return l
256 return wrapper
257 self.view.tool.grab(PlacementTool(my_line_factory(), HandleTool(), 1))
258
259 def key_press_event(self,widget,event):
260 # TODO: add undo handler
261 key = gtk.gdk.keyval_name(event.keyval)
262 if key == 'Delete' and self.view.focused_item:
263 self.view.canvas.remove(self.view.focused_item)
264 self.status.push(0,"Item deleted.")
265 elif key == 'l' or key == 'L':
266 self.set_connector_tool()
267 self.status.push(0,"Line draw mode...")
268
269 a = app()
270 gtk.main()
271

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