CMS 3D CMS Logo

SplitterTab.py
Go to the documentation of this file.
1 from builtins import range
2 import logging
3 
4 from PyQt4.QtCore import Qt, SIGNAL, QCoreApplication, QEvent, QSize
5 from PyQt4.QtGui import QSplitter, QColor, QPalette, QToolBar, QSizePolicy, QWidget, QFrame, QHeaderView, QStandardItemModel, QVBoxLayout
6 
7 from Vispa.Main.AbstractTab import AbstractTab
8 from Vispa.Views.PropertyView import PropertyView
9 
10 class SplitterTab(QSplitter, AbstractTab):
11  """ A Tab with a QSplitter and a function to create the PropertyView.
12 
13  The Tab is split vertically and within horizontally. QWidgets can be added
14  to verticalSplitter() and horizontalSplitter(). In the constructor
15  one can choose whether the PropertyView shall be on top level or inside
16  the horizontalSplitter().
17  """
18  def __init__(self, parent=None, topLevelPropertyView=False):
19  logging.debug(__name__ + ": __init__")
20  self._topLevelPropertyView=topLevelPropertyView
21  AbstractTab.__init__(self)
22  if self._topLevelPropertyView:
23  QSplitter.__init__(self, Qt.Horizontal, parent)
24  self._verticalSplitter = QSplitter(Qt.Vertical, self)
25  else:
26  QSplitter.__init__(self, Qt.Vertical, parent)
27  self._verticalSplitter = self
28 
29  self._horizontalSplitter = QSplitter(Qt.Horizontal, self._verticalSplitter)
30 
31  self.connect(self._verticalSplitter, SIGNAL("splitterMoved(int, int)"), self.verticalSplitterMovedSlot)
32  self.connect(self._horizontalSplitter, SIGNAL("splitterMoved(int, int)"), self.horizontalSplitterMovedSlot)
33  if self._topLevelPropertyView:
34  self.connect(self, SIGNAL("splitterMoved(int, int)"), self.horizontalSplitterMovedSlot)
35  self._toolBar = None
36 
37  self._propertyView = None
38 
39  def verticalSplitter(self):
40  return self._verticalSplitter
41 
42  def verticalSplitterMovedSlot(self, pos, index):
43  """ Implement this function if you want to react on size changes invoked by the vertical splitter.
44  """
45  pass
46 
47  def horizontalSplitter(self):
48  return self._horizontalSplitter
49 
50  def horizontalSplitterMovedSlot(self, pos, index):
51  """ Implement this function if you want to react on size changes invoked by the horizontal splitter.
52  """
53  pass
54 
55  def createToolBar(self,index=None):
56  if index==None:
57  index = self.verticalSplitter().count()
58  self._toolBar = SplitterToolBar()
59  self.verticalSplitter().insertWidget(index,self._toolBar)
60  self.verticalSplitter().setCollapsible(index, False)
61  self._toolBar.setFixedHeight(20)
62  self._toolBar.show()
63 
64  def toolBar(self):
65  return self._toolBar
66 
67  def setController(self, controller):
68  AbstractTab.setController(self, controller)
69  if self._propertyView:
70  self._propertyView.setReadOnly(not self.controller().isEditable())
71  self.connect(self._propertyView, SIGNAL('valueChanged'), self.controller().setModified)
72 
73  def createPropertyView(self):
74  """ Creates PropertyView object, adds it to this tab and makes it available via propertyView().
75  """
76  if self._topLevelPropertyView:
77  parent=self
78  else:
79  parent=self.horizontalSplitter()
80  self._propertyView = PropertyView(parent, "PropertyView")
81 
82  def propertyView(self):
83  """ Returns PropertyView object. See createPropertyView().
84  """
85  return self._propertyView
86 
87  def closeEvent(self,event):
88  """ Call close if tab is not embedded in TabWidget
89  """
90  if not self._tabWidget and self.mainWindow().isTabWidget(self):
91  if not self.controller().close():
92  event.ignore()
93  else:
94  event.accept()
95  else:
96  event.accept()
97 
98  def event(self,event):
99  """ Call tabChanged if window is activated.
100  """
101  if not self._tabWidget:
102  if event.type()==QEvent.WindowActivate:
103  QCoreApplication.instance().tabChanged()
104  return QSplitter.event(self,event)
105 
106 
107 class SplitterToolBar(QToolBar):
108  """ A vertical toolbar which can be split up in sections.
109 
110  The toolbar can be placed in the verticalSplitter() of the SplitterTab
111  to separate two parts. The toolbar can hold buttons to control its
112  neighboring views.
113  """
114 
115  ALIGNMENT_LEFT = 0
116  ALIGNMENT_CENTER = 1
117  ALIGNMENT_RIGHT = 2
118 
119  def __init__(self, parent=None):
120  self._sections = []
121  self._sizes = None
122  QToolBar.__init__(self, parent)
123  self.layout().setSpacing(0)
124 
125  def _createSpacer(self, width=0):
126  spacer = QWidget(self)
127  spacer.setFixedSize(width, self.iconSize().height())
128  return spacer
129 
130  def addSection(self, alignment=None):
131  if alignment == None:
132  alignment = self.ALIGNMENT_CENTER
133 
134  leftSpacer = self._createSpacer()
135  rightSpacer = self._createSpacer()
136  contentList = []
137  leftSpacerAction = self.addWidget(leftSpacer)
138  rightSpacerAction = self.addWidget(rightSpacer)
139  section = {"leftSpacer": leftSpacer, "leftSpacerAction": leftSpacerAction,
140  "contentList": contentList,
141  "rightSpacer": rightSpacer, "rightSpacerAction": rightSpacerAction,
142  "alignment": alignment}
143 
144  self._sections.append(section)
145  if self._sizes:
146  self.setSectionSizes(self._sizes)
147  return len(self._sections) - 1
148 
149  def addWidgetToSection(self, widget, section):
150  if section > len(self._sections) - 1:
151  logging.error(self.__class__.__name__ +": addWidgetToSection() - Unknown section number %d. Aborting..." % section)
152  return
153 
154  widget.show()
155  self._sections[section]["contentList"].append(widget)
156  self.insertWidget(self._sections[section]["rightSpacerAction"], widget)
157  # TODO: implement remove function
158  if self._sizes:
159  self.setSectionSizes(self._sizes)
160 
161  def setSectionSizes(self, sizes):
162  """ sizes is list of widths for section spacers.
163  """
164  self._sizes = sizes # try to fix design, need to find better solution
165  for i in range(min(len(self._sections), len(sizes))):
166  section = self._sections[i]
167  contentsWidth = 0
168  for content in section["contentList"]:
169  contentsWidth += content.width() + self.layout().spacing() + 1
170  if section["alignment"] == self.ALIGNMENT_LEFT:
171  rightWidth = sizes[i] - contentsWidth
172  leftWidth = 0
173  elif section["alignment"] == self.ALIGNMENT_RIGHT:
174  contentsWidth += self.layout().spacing() * 2
175  rightWidth = 0
176  leftWidth = sizes[i] - contentsWidth
177  else:
178  # Default is ALIGNMENT_CENTER
179  leftWidth = 0.5 * (sizes[i] - contentsWidth)
180  rightWidth = leftWidth
181  section["leftSpacer"].setFixedSize(max(0, leftWidth), self.iconSize().height())
182  section["rightSpacer"].setFixedSize(max(0, rightWidth), self.iconSize().height())
183 
184  def takeToolBoxContainerButtons(self, toolBox, section):
185  for button in toolBox.toggleButtons():
186  self.addWidgetToSection(button, section)
187 
188  def showEvent(self, event):
189  QToolBar.showEvent(self, event)
190  if self._sizes:
191  self.setSectionSizes(self._sizes)
def addWidgetToSection(self, widget, section)
Definition: SplitterTab.py:149
def setController(self, controller)
Definition: SplitterTab.py:67
def verticalSplitterMovedSlot(self, pos, index)
Definition: SplitterTab.py:42
def addSection(self, alignment=None)
Definition: SplitterTab.py:130
def createToolBar(self, index=None)
Definition: SplitterTab.py:55
T min(T a, T b)
Definition: MathUtil.h:58
def __init__(self, parent=None, topLevelPropertyView=False)
Definition: SplitterTab.py:18
def horizontalSplitterMovedSlot(self, pos, index)
Definition: SplitterTab.py:50
def takeToolBoxContainerButtons(self, toolBox, section)
Definition: SplitterTab.py:184