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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1939 - (hide annotations) (download) (as text)
Thu Oct 30 02:38:43 2008 UTC (13 years, 9 months ago) by jpye
File MIME type: text/x-python
File size: 7337 byte(s)
Right-click context menu.
1 jpye 1935 from __future__ import with_statement
2 jpye 1937 import os, sys
3 jpye 1929
4 jpye 1937 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 jpye 1929 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 jpye 1801 import ascpy
33    
34     L = ascpy.Library()
35    
36 jpye 1929 # FIXME need to add way to add/remove modules from the Library?
37     L.load('test/canvas/blocktypes.a4c')
38 jpye 1801
39     D = L.getAnnotationDatabase()
40    
41     M = L.getModules()
42    
43     blocktypes = set()
44    
45 jpye 1935 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 jpye 1936 return gtk.gdk.pixbuf_new_from_file_at_size("defaultblock.svg",width,height)
63 jpye 1935
64 jpye 1937
65 jpye 1813 for m in M:
66     T = L.getModuleTypes(m)
67     for t in T:
68 jpye 1925 # '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 jpye 1893 continue
73 jpye 1925 x = D.getNotes(t,ascpy.SymChar("block"),ascpy.SymChar("SELF"))
74     if x:
75 jpye 1813 blocktypes.add(t)
76    
77 jpye 1935 blocks = []
78    
79 jpye 1813 print "block types:"
80     if not blocktypes:
81     print "NONE FOUND"
82     for t in blocktypes:
83    
84 jpye 1935 b = Block(t,D)
85 jpye 1926
86 jpye 1935 blocks += [b]
87 jpye 1925
88 jpye 1935 print b.type.getName()
89    
90     print "\t\tinputs:",[n.getId() for n in b.inputs]
91     for n in b.inputs:
92 jpye 1929 print "\t\t\t%s: %s (type = %s)" % (n.getId(),n.getText(),n.getType())
93 jpye 1935 print "\t\toutputs:",[n.getId() for n in b.outputs]
94     for n in b.outputs:
95 jpye 1929 print "\t\t\t%s: %s" % (n.getId(),n.getText())
96 jpye 1926
97 jpye 1935
98     # render icon table
99     import threading
100     import gtk
101     import os, os.path, re
102 jpye 1936
103     import cairo
104     from gaphas import GtkView, View
105     from gaphas.tool import HoverTool, PlacementTool, HandleTool, ToolChain
106 jpye 1939 from gaphas.tool import Tool, ItemTool, RubberbandTool
107 jpye 1936 from port import *
108    
109 jpye 1935 gtk.gdk.threads_init()
110    
111 jpye 1937 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 jpye 1939 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 jpye 1935 class app(gtk.Window):
185     def __init__(self):
186 jpye 1937 self.status = gtk.Statusbar()
187 jpye 1936
188 jpye 1937 # the Gaphas canvas
189 jpye 1936 canvas = BlockCanvas()
190    
191 jpye 1937 # the main window
192 jpye 1935 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 jpye 1938 self.connect("key-press-event", self.key_press_event)
197 jpye 1935
198 jpye 1937 # vbox containing the main view and the status bar at the bottom
199 jpye 1935 vbox = gtk.VBox()
200    
201 jpye 1937 # hbox occupies top part of vbox, with icons on left & canvas on right.
202 jpye 1936 hbox = gtk.HBox()
203    
204 jpye 1937 # the 'view' widget implemented by Gaphas
205     self.view = GtkView()
206 jpye 1939 self.view.tool = BlockToolChain()
207 jpye 1936
208 jpye 1937 # table containing scrollbars and main canvas
209 jpye 1936 t = gtk.Table(2,2)
210 jpye 1937 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 jpye 1936 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 jpye 1937 # 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 jpye 1936 hbox.pack_start(scroll, True, True)
230     hbox.pack_start(t, True, True)
231     vbox.pack_start(hbox, True, True)
232 jpye 1937 vbox.pack_start(self.status, False, False)
233 jpye 1935 self.add(vbox)
234     self.show_all()
235    
236 jpye 1937 # 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 jpye 1938 # TODO: add undo handler
241 jpye 1937 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 jpye 1938
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 jpye 1935
257     a = app()
258     gtk.main()
259    

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