1 2from gi.repository import Gtk, GObject 3 4from .__init__ import NORTH, EAST, SOUTH, WEST, CENTER, reprPos 5 6 7class PyDockComposite(Gtk.Alignment): 8 def __init__(self, position, perspective): 9 GObject.GObject.__init__(self, xscale=1, yscale=1) 10 11 if position == NORTH or position == SOUTH: 12 paned = Gtk.VPaned() 13 elif position == EAST or position == WEST: 14 paned = Gtk.HPaned() 15 self.position = position 16 self.perspective = perspective 17 self.paned = paned 18 self.add(self.paned) 19 self.paned.show() 20 21 def _del(self): 22 for component in self.getComponents(): 23 component._del() 24 25 def __repr__(self): 26 return "composite %s (%s, %s)" % (reprPos[self.position], 27 repr(self.paned.get_child1()), 28 repr(self.paned.get_child2())) 29 30 def dock(self, widget, position, title, id): 31 assert position != CENTER, "POSITION_CENTER only makes sense for leaves" 32 parent = self.get_parent() 33 while not isinstance(parent, PyDockComposite): 34 parent = parent.get_parent() 35 from .PyDockLeaf import PyDockLeaf 36 leaf = PyDockLeaf(widget, title, id, self.perspective) 37 new = PyDockComposite(position, self.perspective) 38 parent.changeComponent(self, new) 39 new.initChildren(self, leaf) 40 return leaf 41 42 def changeComponent(self, old, new): 43 if old == self.paned.get_child1(): 44 self.paned.remove(old) 45 self.paned.pack1(new, resize=True, shrink=True) 46 else: 47 self.paned.remove(old) 48 self.paned.pack2(new, resize=True, shrink=True) 49 new.show() 50 51 def removeComponent(self, component): 52 if component == self.paned.get_child1(): 53 new = self.paned.get_child2() 54 else: 55 new = self.paned.get_child1() 56 self.paned.remove(new) 57 parent = self.get_parent() 58 while not isinstance(parent, PyDockComposite): 59 parent = parent.get_parent() 60 parent.changeComponent(self, new) 61 component._del() # TODO: is this necessary? 62 new.show() 63 64 def getComponents(self): 65 return self.paned.get_children() 66 67 def initChildren(self, old, new, preserve_dimensions=False): 68 if self.position == NORTH or self.position == WEST: 69 self.paned.pack1(new, resize=True, shrink=True) 70 self.paned.pack2(old, resize=True, shrink=True) 71 elif self.position == SOUTH or self.position == EAST: 72 self.paned.pack1(old, resize=True, shrink=True) 73 self.paned.pack2(new, resize=True, shrink=True) 74 old.show() 75 new.show() 76 77 def cb(widget, allocation): 78 # Set initial position of the divider between the two panes of Gtk.Paned 79 if allocation.height != 1: 80 if self.position == NORTH: 81 pos = 0.381966011 * allocation.height 82 elif self.position == SOUTH: 83 pos = 0.618033989 * allocation.height 84 elif self.position == WEST: 85 pos = 0.381966011 * allocation.width 86 elif self.position == EAST: 87 pos = 0.618033989 * allocation.width 88 89 widget.set_position(int(pos + .5)) 90 widget.disconnect(conid) 91 92 if not preserve_dimensions: 93 conid = self.paned.connect("size-allocate", cb) 94 95 def getPosition(self): 96 """ Returns NORTH or SOUTH if the children are packed vertically. 97 Returns WEST or EAST if the children are packed horizontally. 98 Returns CENTER if there is only one child """ 99 return self.position 100