aboutsummaryrefslogtreecommitdiffstats
path: root/mvc/widgets/osx/layout.py
diff options
context:
space:
mode:
Diffstat (limited to 'mvc/widgets/osx/layout.py')
-rw-r--r--mvc/widgets/osx/layout.py748
1 files changed, 0 insertions, 748 deletions
diff --git a/mvc/widgets/osx/layout.py b/mvc/widgets/osx/layout.py
deleted file mode 100644
index 0238975..0000000
--- a/mvc/widgets/osx/layout.py
+++ /dev/null
@@ -1,748 +0,0 @@
-# @Base: Miro - an RSS based video player application
-# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
-# Participatory Culture Foundation
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# In addition, as a special exception, the copyright holders give
-# permission to link the code of portions of this program with the OpenSSL
-# library.
-#
-# You must obey the GNU General Public License in all respects for all of
-# the code used other than OpenSSL. If you modify file(s) with this
-# exception, you may extend this exception to your version of the file(s),
-# but you are not obligated to do so. If you do not wish to do so, delete
-# this exception statement from your version. If you delete this exception
-# statement from all source files in the program, then also delete it here.
-
-""".layout -- Widgets that handle laying out other
-widgets.
-
-We basically follow GTK's packing model. Widgets are packed into vboxes,
-hboxes or other container widgets. The child widgets request a minimum size,
-and the container widgets allocate space for their children. Widgets may get
-more size then they requested in which case they have to deal with it. In
-rare cases, widgets may get less size then they requested in which case they
-should just make sure they don't throw an exception or segfault.
-
-Check out the GTK tutorial for more info.
-"""
-
-import itertools
-
-from AppKit import *
-from Foundation import *
-from objc import YES, NO, nil, signature, loadBundle
-
-import tableview
-import wrappermap
-from .base import Container, Bin, FlippedView
-from mvc.utils import Matrix
-
-# These don't seem to be in pyobjc's AppKit (yet)
-NSScrollerKnobStyleDefault = 0
-NSScrollerKnobStyleDark = 1
-NSScrollerKnobStyleLight = 2
-
-NSScrollerStyleLegacy = 0
-NSScrollerStyleOverlay = 1
-
-def _extra_space_iter(extra_length, count):
- """Utility function to allocate extra space left over in containers."""
- if count == 0:
- return
- extra_space, leftover = divmod(extra_length, count)
- while leftover >= 1:
- yield extra_space + 1
- leftover -= 1
- yield extra_space + leftover
- while True:
- yield extra_space
-
-class BoxPacking:
- """Utility class to store how we are packing a single widget."""
-
- def __init__(self, widget, expand, padding):
- self.widget = widget
- self.expand = expand
- self.padding = padding
-
-class Box(Container):
- """Base class for HBox and VBox. """
- CREATES_VIEW = False
-
- def __init__(self, spacing=0):
- self.spacing = spacing
- Container.__init__(self)
- self.packing_start = []
- self.packing_end = []
- self.expand_count = 0
-
- def packing_both(self):
- return itertools.chain(self.packing_start, self.packing_end)
-
- def get_children(self):
- for packing in self.packing_both():
- yield packing.widget
- children = property(get_children)
-
- # Internally Boxes use a (length, breadth) coordinate system. length and
- # breadth will be either x or y depending on which way the box is
- # oriented. The subclasses must provide methods to translate between the
- # 2 coordinate systems.
-
- def translate_size(self, size):
- """Translate a (width, height) tulple to (length, breadth)."""
- raise NotImplementedError()
-
- def untranslate_size(self, size):
- """Reverse the work of translate_size."""
- raise NotImplementedError()
-
- def make_child_rect(self, position, length):
- """Create a rect to position a child with."""
- raise NotImplementedError()
-
- def pack_start(self, child, expand=False, padding=0):
- self.packing_start.append(BoxPacking(child, expand, padding))
- if expand:
- self.expand_count += 1
- self.child_added(child)
-
- def pack_end(self, child, expand=False, padding=0):
- self.packing_end.append(BoxPacking(child, expand, padding))
- if expand:
- self.expand_count += 1
- self.child_added(child)
-
- def _remove_from_packing(self, child):
- for i in xrange(len(self.packing_start)):
- if self.packing_start[i].widget is child:
- return self.packing_start.pop(i)
- for i in xrange(len(self.packing_end)):
- if self.packing_end[i].widget is child:
- return self.packing_end.pop(i)
- raise LookupError("%s not found" % child)
-
- def remove(self, child):
- packing = self._remove_from_packing(child)
- if packing.expand:
- self.expand_count -= 1
- self.child_removed(child)
-
- def translate_widget_size(self, widget):
- return self.translate_size(widget.get_size_request())
-
- def calc_size_request(self):
- length = breadth = 0
- for packing in self.packing_both():
- child_length, child_breadth = \
- self.translate_widget_size(packing.widget)
- length += child_length
- if packing.padding:
- length += packing.padding * 2 # Need to pad on both sides
- breadth = max(breadth, child_breadth)
- spaces = max(0, len(self.packing_start) + len(self.packing_end) - 1)
- length += spaces * self.spacing
- return self.untranslate_size((length, breadth))
-
- def place_children(self):
- request_length, request_breadth = self.translate_widget_size(self)
- ps = self.viewport.placement.size
- total_length, dummy = self.translate_size((ps.width, ps.height))
- total_extra_space = total_length - request_length
- extra_space_iter = _extra_space_iter(total_extra_space,
- self.expand_count)
- start_end = self._place_packing_list(self.packing_start,
- extra_space_iter, 0)
- if self.expand_count == 0 and total_extra_space > 0:
- # account for empty space after the end of pack_start list and
- # before the pack_end list.
- self.draw_empty_space(start_end, total_extra_space)
- start_end += total_extra_space
- self._place_packing_list(reversed(self.packing_end), extra_space_iter,
- start_end)
-
- def draw_empty_space(self, start, length):
- empty_rect = self.make_child_rect(start, length)
- my_view = self.viewport.view
- opaque_view = my_view.opaqueAncestor()
- if opaque_view is not None:
- empty_rect2 = opaque_view.convertRect_fromView_(empty_rect, my_view)
- opaque_view.setNeedsDisplayInRect_(empty_rect2)
-
- def _place_packing_list(self, packing_list, extra_space_iter, position):
- for packing in packing_list:
- child_length, child_breadth = \
- self.translate_widget_size(packing.widget)
- if packing.expand:
- child_length += extra_space_iter.next()
- if packing.padding: # space before
- self.draw_empty_space(position, packing.padding)
- position += packing.padding
- child_rect = self.make_child_rect(position, child_length)
- if packing.padding: # space after
- self.draw_empty_space(position, packing.padding)
- position += packing.padding
- packing.widget.place(child_rect, self.viewport.view)
- position += child_length
- if self.spacing > 0:
- self.draw_empty_space(position, self.spacing)
- position += self.spacing
- return position
-
- def enable(self):
- Container.enable(self)
- for mem in self.children:
- mem.enable()
-
- def disable(self):
- Container.disable(self)
- for mem in self.children:
- mem.disable()
-
-class VBox(Box):
- """See https://develop.participatoryculture.org/index.php/WidgetAPI for a description of the API for this class."""
- def translate_size(self, size):
- return (size[1], size[0])
-
- def untranslate_size(self, size):
- return (size[1], size[0])
-
- def make_child_rect(self, position, length):
- placement = self.viewport.placement
- return NSMakeRect(placement.origin.x, placement.origin.y + position,
- placement.size.width, length)
-
-class HBox(Box):
- """See https://develop.participatoryculture.org/index.php/WidgetAPI for a description of the API for this class."""
- def translate_size(self, size):
- return (size[0], size[1])
-
- def untranslate_size(self, size):
- return (size[0], size[1])
-
- def make_child_rect(self, position, length):
- placement = self.viewport.placement
- return NSMakeRect(placement.origin.x + position, placement.origin.y,
- length, placement.size.height)
-
-class Alignment(Bin):
- """See https://develop.participatoryculture.org/index.php/WidgetAPI for a description of the API for this class."""
- CREATES_VIEW = False
-
- def __init__(self, xalign=0.0, yalign=0.0, xscale=0.0, yscale=0.0,
- top_pad=0, bottom_pad=0, left_pad=0, right_pad=0):
- Bin.__init__(self)
- self.xalign = xalign
- self.yalign = yalign
- self.xscale = xscale
- self.yscale = yscale
- self.top_pad = top_pad
- self.bottom_pad = bottom_pad
- self.left_pad = left_pad
- self.right_pad = right_pad
- if self.child is not None:
- self.place_children()
-
- def set(self, xalign=0.0, yalign=0.0, xscale=0.0, yscale=0.0):
- self.xalign = xalign
- self.yalign = yalign
- self.xscale = xscale
- self.yscale = yscale
- if self.child is not None:
- self.place_children()
-
- def set_padding(self, top_pad=0, bottom_pad=0, left_pad=0, right_pad=0):
- self.top_pad = top_pad
- self.bottom_pad = bottom_pad
- self.left_pad = left_pad
- self.right_pad = right_pad
- if self.child is not None and self.viewport is not None:
- self.place_children()
-
- def vertical_pad(self):
- return self.top_pad + self.bottom_pad
-
- def horizontal_pad(self):
- return self.left_pad + self.right_pad
-
- def calc_size_request(self):
- if self.child:
- child_width, child_height = self.child.get_size_request()
- return (child_width + self.horizontal_pad(),
- child_height + self.vertical_pad())
- else:
- return (0, 0)
-
- def calc_size(self, requested, total, scale):
- extra_width = max(0, total - requested)
- return requested + int(round(extra_width * scale))
-
- def calc_position(self, size, total, align):
- return int(round((total - size) * align))
-
- def place_children(self):
- if self.child is None:
- return
-
- total_width = self.viewport.placement.size.width
- total_height = self.viewport.placement.size.height
- total_width -= self.horizontal_pad()
- total_height -= self.vertical_pad()
- request_width, request_height = self.child.get_size_request()
-
- child_width = self.calc_size(request_width, total_width, self.xscale)
- child_height = self.calc_size(request_height, total_height, self.yscale)
- child_x = self.calc_position(child_width, total_width, self.xalign)
- child_y = self.calc_position(child_height, total_height, self.yalign)
- child_x += self.left_pad
- child_y += self.top_pad
-
- my_origin = self.viewport.area().origin
- child_rect = NSMakeRect(my_origin.x + child_x, my_origin.y + child_y, child_width, child_height)
- self.child.place(child_rect, self.viewport.view)
- # Make sure the space not taken up by our child is redrawn.
- self.viewport.queue_redraw()
-
-class DetachedWindowHolder(Alignment):
- def __init__(self):
- Alignment.__init__(self, bottom_pad=16, xscale=1.0, yscale=1.0)
-
-class _TablePacking(object):
- """Utility class to help with packing Table widgets."""
- def __init__(self, widget, column, row, column_span, row_span):
- self.widget = widget
- self.column = column
- self.row = row
- self.column_span = column_span
- self.row_span = row_span
-
- def column_indexes(self):
- return range(self.column, self.column + self.column_span)
-
- def row_indexes(self):
- return range(self.row, self.row + self.row_span)
-
-class Table(Container):
- """See https://develop.participatoryculture.org/index.php/WidgetAPI for a description of the API for this class."""
- CREATES_VIEW = False
-
- def __init__(self, columns, rows):
- Container.__init__(self)
- self._cells = Matrix(columns, rows)
- self._children = [] # List of _TablePacking objects
- self._children_sorted = True
- self.rows = rows
- self.columns = columns
- self.row_spacing = self.column_spacing = 0
-
- def _ensure_children_sorted(self):
- if not self._children_sorted:
- def cell_area(table_packing):
- return table_packing.column_span * table_packing.row_span
- self._children.sort(key=cell_area)
- self._children_sorted = True
-
- def get_children(self):
- return [cell.widget for cell in self._children]
- children = property(get_children)
-
- def calc_size_request(self):
- self._ensure_children_sorted()
- self._calc_dimensions()
- return self.total_width, self.total_height
-
- def _calc_dimensions(self):
- self.column_widths = [0] * self.columns
- self.row_heights = [0] * self.rows
-
- for tp in self._children:
- child_width, child_height = tp.widget.get_size_request()
- # recalc the width of the child's columns
- self._recalc_dimension(child_width, self.column_widths,
- tp.column_indexes())
- # recalc the height of the child's rows
- self._recalc_dimension(child_height, self.row_heights,
- tp.row_indexes())
-
- self.total_width = (self.column_spacing * (self.columns - 1) +
- sum(self.column_widths))
- self.total_height = (self.row_spacing * (self.rows - 1) +
- sum(self.row_heights))
-
- def _recalc_dimension(self, child_size, size_array, positions):
- current_size = sum(size_array[p] for p in positions)
- child_size_needed = child_size - current_size
- if child_size_needed > 0:
- iter = _extra_space_iter(child_size_needed, len(positions))
- for p in positions:
- size_array[p] += iter.next()
-
- def place_children(self):
- # This method depepnds on us calling _calc_dimensions() in
- # calc_size_request(). Ensure that this happens.
- if self.cached_size_request is None:
- self.get_size_request()
- column_positions = [0]
- for width in self.column_widths[:-1]:
- column_positions.append(width + column_positions[-1] + self.column_spacing)
- row_positions = [0]
- for height in self.row_heights[:-1]:
- row_positions.append(height + row_positions[-1] + self.row_spacing)
-
- my_x= self.viewport.placement.origin.x
- my_y = self.viewport.placement.origin.y
- for tp in self._children:
- x = my_x + column_positions[tp.column]
- y = my_y + row_positions[tp.row]
- width = sum(self.column_widths[i] for i in tp.column_indexes())
- height = sum(self.row_heights[i] for i in tp.row_indexes())
- rect = NSMakeRect(x, y, width, height)
- tp.widget.place(rect, self.viewport.view)
-
- def pack(self, widget, column, row, column_span=1, row_span=1):
- tp = _TablePacking(widget, column, row, column_span, row_span)
- for c in tp.column_indexes():
- for r in tp.row_indexes():
- if self._cells[c, r]:
- raise ValueError("Cell %d x %d is already taken" % (c, r))
- self._cells[column, row] = widget
- self._children.append(tp)
- self._children_sorted = False
- self.child_added(widget)
-
- def remove(self, child):
- for i in xrange(len(self._children)):
- if self._children[i].widget is child:
- self._children.remove(i)
- break
- else:
- raise ValueError("%s is not a child of this Table" % child)
- self._cells.remove(child)
- self.child_removed(widget)
-
- def set_column_spacing(self, spacing):
- self.column_spacing = spacing
- self.invalidate_size_request()
-
- def set_row_spacing(self, spacing):
- self.row_spacing = spacing
- self.invalidate_size_request()
-
- def enable(self, row=None, column=None):
- Container.enable(self)
- if row != None and column != None:
- if self._cells[column, row]:
- self._cells[column, row].enable()
- elif row != None:
- for mem in self._cells.row(row):
- if mem: mem.enable()
- elif column != None:
- for mem in self._cells.column(column):
- if mem: mem.enable()
- else:
- for mem in self._cells:
- if mem: mem.enable()
-
- def disable(self, row=None, column=None):
- Container.disable(self)
- if row != None and column != None:
- if self._cells[column, row]:
- self._cells[column, row].disable()
- elif row != None:
- for mem in self._cells.row(row):
- if mem: mem.disable()
- elif column != None:
- for mem in self._cells.column(column):
- if mem: mem.disable()
- else:
- for mem in self._cells:
- if mem: mem.disable()
-
-class MiroScrollView(NSScrollView):
- def tile(self):
- NSScrollView.tile(self)
- # tile is called when we need to layout our child view and scrollers.
- # This probably means that we've either hidden or shown a scrollbar so
- # call invalidate_size_request to ensure that things get re-layed out
- # correctly. (#see 13842)
- wrapper = wrappermap.wrapper(self)
- if wrapper is not None:
- wrapper.invalidate_size_request()
-
-class Scroller(Bin):
- """See https://develop.participatoryculture.org/index.php/WidgetAPI for a description of the API for this class."""
- def __init__(self, horizontal, vertical):
- Bin.__init__(self)
- self.view = MiroScrollView.alloc().init()
- self.view.setAutohidesScrollers_(YES)
- self.view.setHasHorizontalScroller_(horizontal)
- self.view.setHasVerticalScroller_(vertical)
- self.document_view = FlippedView.alloc().init()
- self.view.setDocumentView_(self.document_view)
-
- def prepare_for_dark_content(self):
- try:
- self.view.setScrollerKnobStyle_(NSScrollerKnobStyleLight)
- except AttributeError:
- # This only works on 10.7 and abvoe
- pass
-
- def set_has_borders(self, has_border):
- self.view.setBorderType_(NSBezelBorder)
-
- def viewport_repositioned(self):
- # If the window is resized, this translates to a
- # viewport_repositioned() event. Instead of calling
- # place_children() one, which is what our suporclass does, we need
- # some extra logic here. place the chilren to work out if we need a
- # scrollbar, then get the new size, then replace the children (which
- # now takes into account of scrollbar size.)
- super(Scroller, self).viewport_repositioned()
- self.cached_size_request = self.calc_size_request()
- self.place_children()
-
- def set_background_color(self, color):
- self.view.setBackgroundColor_(self.make_color(color))
-
- def add(self, child):
- child.parent_is_scroller = True
- Bin.add(self, child)
-
- def remove(self):
- child.parent_is_scroller = False
- Bin.remove(self)
-
- def children_changed(self):
- # since our size isn't dependent on our children, don't call
- # invalidate_size_request() here. Just call place_children() so that
- # they get positioned correctly in the document view.
- #
- # XXX dodgy - why are we laying out the children twice? When the
- # children change, the scroller could appear/disappear. But you have
- # no idea if that's going to happen without knowing how big your
- # children are. So we lay it out, get the size, then, place the
- # children again. This makes sure that the right side of the children
- # are redrawn. There's got to be a better way??
- self.place_children()
- self.cached_size_request = self.calc_size_request()
- self.place_children()
-
- def calc_size_request(self):
- if self.child:
- width = height = 0
- try:
- legacy = self.view.scrollerStyle() == NSScrollerStyleLegacy
- except AttributeError:
- legacy = True
- if not self.view.hasHorizontalScroller():
- width = self.child.get_size_request()[0]
- if not self.view.hasVerticalScroller():
- height = self.child.get_size_request()[1]
- # Add a little room for the scrollbars (if necessary)
- if legacy and self.view.hasHorizontalScroller():
- height += NSScroller.scrollerWidth()
- if legacy and self.view.hasVerticalScroller():
- width += NSScroller.scrollerWidth()
- return width, height
- else:
- return 0, 0
-
- def place_children(self):
- if self.child is not None:
- scroll_view_size = self.view.contentView().frame().size
- child_width, child_height = self.child.get_size_request()
- child_width = max(child_width, scroll_view_size.width)
- child_height = max(child_height, scroll_view_size.height)
- frame = NSRect(NSPoint(0,0), NSSize(child_width, child_height))
- if isinstance(self.child, tableview.TableView) and self.child.is_showing_headers():
- # Hack to allow the content of a table view to scroll, but not
- # the headers
- self.child.place(frame, self.document_view)
- if self.view.documentView() is not self.child.tableview:
- self.view.setDocumentView_(self.child.tableview)
- else:
- self.child.place(frame, self.document_view)
- self.document_view.setFrame_(frame)
- self.document_view.setNeedsDisplay_(YES)
- self.view.setNeedsDisplay_(YES)
- self.child.emit('place-in-scroller')
-
-class ExpanderView(FlippedView):
- def init(self):
- self = super(ExpanderView, self).init()
- self.label_rect = None
- self.content_view = None
- self.button = NSButton.alloc().init()
- self.button.setState_(NSOffState)
- self.button.setTitle_("")
- self.button.setBezelStyle_(NSDisclosureBezelStyle)
- self.button.setButtonType_(NSPushOnPushOffButton)
- self.button.sizeToFit()
- self.addSubview_(self.button)
- self.button.setTarget_(self)
- self.button.setAction_('buttonChanged:')
- self.content_view = FlippedView.alloc().init()
- return self
-
- def buttonChanged_(self, button):
- if button.state() == NSOnState:
- self.addSubview_(self.content_view)
- else:
- self.content_view.removeFromSuperview()
- if self.window():
- wrappermap.wrapper(self).invalidate_size_request()
-
- def mouseDown_(self, event):
- pass # Just need to respond to the selector so we get mouseUp_
-
- def mouseUp_(self, event):
- position = event.locationInWindow()
- window_label_rect = self.convertRect_toView_(self.label_rect, None)
- if NSPointInRect(position, window_label_rect):
- self.button.setNextState()
- self.buttonChanged_(self.button)
-
-class Expander(Bin):
- BUTTON_PAD_TOP = 2
- BUTTON_PAD_LEFT = 4
- LABEL_SPACING = 4
-
- def __init__(self, child):
- Bin.__init__(self)
- if child:
- self.add(child)
- self.label = None
- self.spacing = 0
- self.view = ExpanderView.alloc().init()
- self.button = self.view.button
- self.button.setFrameOrigin_(NSPoint(self.BUTTON_PAD_LEFT,
- self.BUTTON_PAD_TOP))
- self.content_view = self.view.content_view
-
- def remove_viewport(self):
- Bin.remove_viewport(self)
- if self.label is not None:
- self.label.remove_viewport()
-
- def set_spacing(self, spacing):
- self.spacing = spacing
-
- def set_label(self, widget):
- if self.label is not None:
- self.label.remove_viewport()
- self.label = widget
- self.children_changed()
-
- def set_expanded(self, expanded):
- if expanded:
- self.button.setState_(NSOnState)
- else:
- self.button.setState_(NSOffState)
- self.view.buttonChanged_(self.button)
-
- def calc_top_size(self):
- width = self.button.bounds().size.width
- height = self.button.bounds().size.height
- if self.label is not None:
- label_width, label_height = self.label.get_size_request()
- width += self.LABEL_SPACING + label_width
- height = max(height, label_height)
- width += self.BUTTON_PAD_LEFT
- height += self.BUTTON_PAD_TOP
- return width, height
-
- def calc_size_request(self):
- width, height = self.calc_top_size()
- if self.child is not None and self.button.state() == NSOnState:
- child_width, child_height = self.child.get_size_request()
- width = max(width, child_width)
- height += self.spacing + child_height
- return width, height
-
- def place_children(self):
- top_width, top_height = self.calc_top_size()
- if self.label:
- label_width, label_height = self.label.get_size_request()
- button_width = self.button.bounds().size.width
- label_x = self.BUTTON_PAD_LEFT + button_width + self.LABEL_SPACING
- label_rect = NSMakeRect(label_x, self.BUTTON_PAD_TOP,
- label_width, label_height)
- self.label.place(label_rect, self.viewport.view)
- self.view.label_rect = label_rect
- if self.child:
- size = self.viewport.area().size
- child_rect = NSMakeRect(0, 0, size.width, size.height -
- top_height)
- self.content_view.setFrame_(NSMakeRect(0, top_height, size.width,
- size.height - top_height))
- self.child.place(child_rect, self.content_view)
-
-
-class TabViewDelegate(NSObject):
- def tabView_willSelectTabViewItem_(self, tab_view, tab_view_item):
- try:
- wrapper = wrappermap.wrapper(tab_view)
- except KeyError:
- pass # The NSTabView hasn't been placed yet, don't worry about it.
- else:
- wrapper.place_child_with_item(tab_view_item)
-
-class TabContainer(Container):
- def __init__(self):
- Container.__init__(self)
- self.children = []
- self.item_to_child = {}
- self.view = NSTabView.alloc().init()
- self.view.setAllowsTruncatedLabels_(NO)
- self.delegate = TabViewDelegate.alloc().init()
- self.view.setDelegate_(self.delegate)
-
- def append_tab(self, child_widget, label, image):
- item = NSTabViewItem.alloc().init()
- item.setLabel_(label)
- item.setView_(FlippedView.alloc().init())
- self.view.addTabViewItem_(item)
- self.children.append(child_widget)
- self.child_added(child_widget)
- self.item_to_child[item] = child_widget
-
- def select_tab(self, index):
- self.view.selectTabViewItemAtIndex_(index)
-
- def place_children(self):
- self.place_child_with_item(self.view.selectedTabViewItem())
-
- def place_child_with_item(self, tab_view_item):
- child = self.item_to_child[tab_view_item]
- child_view = tab_view_item.view()
- content_rect =self.view.contentRect()
- child_view.setFrame_(content_rect)
- child.place(child_view.bounds(), child_view)
-
- def calc_size_request(self):
- tab_size = self.view.minimumSize()
- # make sure there's enough room for the tabs, plus a little extra
- # space to make things look good
- max_width = tab_size.width + 60
- max_height = 0
- for child in self.children:
- width, height = child.get_size_request()
- max_width = max(width, max_width)
- max_height = max(height, max_height)
- max_height += tab_size.height
-
- return max_width, max_height