text: # -*- coding: utf-8 -*-
  from ..Qt import QtCore, QtGui, QtWidgets
  import weakref
  
  class Container(object):
      #sigStretchChanged = QtCore.Signal()  ## can't do this here; not a QObject.
      
      def __init__(self, area):
          object.__init__(self)
          self.area = area
          self._container = None
          self._stretch = (10, 10)
          self.stretches = weakref.WeakKeyDictionary()
          
      def container(self):
          return self._container
          
      def containerChanged(self, c):
          self._container = c
  
      def type(self):
          return None
  
      def insert(self, new, pos=None, neighbor=None):
          # remove from existing parent first
          new.setParent(None)
          
          if not isinstance(new, list):
              new = [new]
          if neighbor is None:
              if pos == 'before':
                  index = 0
              else:
                  index = self.count()
          else:
              index = self.indexOf(neighbor)
              if index == -1:
                  index = 0
              if pos == 'after':
                  index += 1
                  
          for n in new:
              #print "change container", n, " -> ", self
              n.containerChanged(self)
              #print "insert", n, " -> ", self, index
              self._insertItem(n, index)
              index += 1
              n.sigStretchChanged.connect(self.childStretchChanged)
          #print "child added", self
          self.updateStretch()
              
      def apoptose(self, propagate=True):
          ##if there is only one (or zero) item in this container, disappear.
          cont = self._container
          c = self.count()
          if c > 1:
              return
          if self.count() == 1:  ## if there is one item, give it to the parent container (unless this is the top)
              if self is self.area.topContainer:
                  return
              self.container().insert(self.widget(0), 'before', self)
          #print "apoptose:", self
          self.close()
          if propagate and cont is not None:
              cont.apoptose()
          
      def close(self):
          self.area = None
          self._container = None
          self.setParent(None)
          
      def childEvent(self, ev):
          ch = ev.child()
          if ev.removed() and hasattr(ch, 'sigStretchChanged'):
              #print "Child", ev.child(), "removed, updating", self
              try:
                  ch.sigStretchChanged.disconnect(self.childStretchChanged)
              except:
                  pass
              self.updateStretch()
          
      def childStretchChanged(self):
          #print "child", QtCore.QObject.sender(self), "changed shape, updating", self
          self.updateStretch()
          
      def setStretch(self, x=None, y=None):
          #print "setStretch", self, x, y
          self._stretch = (x, y)
          self.sigStretchChanged.emit()
  
      def updateStretch(self):
          ###Set the stretch values for this container to reflect its contents
          pass
          
          
      def stretch(self):
          """Return the stretch factors for this container"""
          return self._stretch
              
  
  class SplitContainer(Container, QtWidgets.QSplitter):
      """Horizontal or vertical splitter with some changes:
       - save/restore works correctly
      """
      sigStretchChanged = QtCore.Signal()
      
      def __init__(self, area, orientation):
          QtWidgets.QSplitter.__init__(self)
          self.setOrientation(orientation)
          Container.__init__(self, area)
          #self.splitterMoved.connect(self.restretchChildren)
          
      def _insertItem(self, item, index):
          self.insertWidget(index, item)
          item.show()  ## need to show since it may have been previously hidden by tab
          
      def saveState(self):
          sizes = self.sizes()
          if all([x == 0 for x in sizes]):
              sizes = [10] * len(sizes)
          return {'sizes': sizes}
          
      def restoreState(self, state):
          sizes = state['sizes']
          self.setSizes(sizes)
          for i in range(len(sizes)):
              self.setStretchFactor(i, sizes[i])
  
      def childEvent(self, ev):
          QtWidgets.QSplitter.childEvent(self, ev)
          Container.childEvent(self, ev)
  
      #def restretchChildren(self):
          #sizes = self.sizes()
          #tot = sum(sizes)
          
          
          
  
  class HContainer(SplitContainer):
      def __init__(self, area):
          SplitContainer.__init__(self, area, QtCore.Qt.Horizontal)
          
      def type(self):
          return 'horizontal'
          
      def updateStretch(self):
          ##Set the stretch values for this container to reflect its contents
          #print "updateStretch", self
          x = 0
          y = 0
          sizes = []
          for i in range(self.count()):
              wx, wy = self.widget(i).stretch()
              x += wx
              y = max(y, wy)
              sizes.append(wx)
              #print "  child", self.widget(i), wx, wy
          self.setStretch(x, y)
          #print sizes
          
          tot = float(sum(sizes))
          if tot == 0:
              scale = 1.0
          else:
              scale = self.width() / tot
          self.setSizes([int(s*scale) for s in sizes])
          
  
  
  class VContainer(SplitContainer):
      def __init__(self, area):
          SplitContainer.__init__(self, area, QtCore.Qt.Vertical)
          
      def type(self):
          return 'vertical'
  
      def updateStretch(self):
          ##Set the stretch values for this container to reflect its contents
          #print "updateStretch", self
          x = 0
          y = 0
          sizes = []
          for i in range(self.count()):
              wx, wy = self.widget(i).stretch()
              y += wy
              x = max(x, wx)
              sizes.append(wy)
              #print "  child", self.widget(i), wx, wy
          self.setStretch(x, y)
  
          #print sizes
          tot = float(sum(sizes))
          if tot == 0:
              scale = 1.0
          else:
              scale = self.height() / tot
          self.setSizes([int(s*scale) for s in sizes])
  
  
  class TContainer(Container, QtWidgets.QWidget):
      sigStretchChanged = QtCore.Signal()
      def __init__(self, area):
          QtWidgets.QWidget.__init__(self)
          Container.__init__(self, area)
          self.layout = QtWidgets.QGridLayout()
          self.layout.setSpacing(0)
          self.layout.setContentsMargins(0,0,0,0)
          self.setLayout(self.layout)
          
          self.hTabLayout = QtWidgets.QHBoxLayout()
          self.hTabBox = QtWidgets.QWidget()
          self.hTabBox.setLayout(self.hTabLayout)
          self.hTabLayout.setSpacing(2)
          self.hTabLayout.setContentsMargins(0,0,0,0)
          self.layout.addWidget(self.hTabBox, 0, 1)
  
          self.stack = QtWidgets.QStackedWidget()
          self.layout.addWidget(self.stack, 1, 1)
          self.stack.childEvent = self.stackChildEvent
  
  
          self.setLayout(self.layout)
          for n in ['count', 'widget', 'indexOf']:
              setattr(self, n, getattr(self.stack, n))
  
  
      def _insertItem(self, item, index):
          if not isinstance(item, Dock.Dock):
              raise Exception("Tab containers may hold only docks, not other containers.")
          self.stack.insertWidget(index, item)
          self.hTabLayout.insertWidget(index, item.label)
          #QtCore.QObject.connect(item.label, QtCore.SIGNAL('clicked'), self.tabClicked)
          item.label.sigClicked.connect(self.tabClicked)
          self.tabClicked(item.label)
          
      def tabClicked(self, tab, ev=None):
          if ev is None or ev.button() == QtCore.Qt.LeftButton:
              for i in range(self.count()):
                  w = self.widget(i)
                  if w is tab.dock:
                      w.label.setDim(False)
                      self.stack.setCurrentIndex(i)
                  else:
                      w.label.setDim(True)
          
      def raiseDock(self, dock):
          """Move *dock* to the top of the stack"""
          self.stack.currentWidget().label.setDim(True)
          self.stack.setCurrentWidget(dock)
          dock.label.setDim(False)
          
          
      def type(self):
          return 'tab'
  
      def saveState(self):
          return {'index': self.stack.currentIndex()}
          
      def restoreState(self, state):
          self.stack.setCurrentIndex(state['index'])
          
      def updateStretch(self):
          ##Set the stretch values for this container to reflect its contents
          x = 0
          y = 0
          for i in range(self.count()):
              wx, wy = self.widget(i).stretch()
              x = max(x, wx)
              y = max(y, wy)
          self.setStretch(x, y)
          
      def stackChildEvent(self, ev):
          QtWidgets.QStackedWidget.childEvent(self.stack, ev)
          Container.childEvent(self, ev)
          
  from . import Dock
  