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