home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 June / maximum-cd-2009-06.iso / DiscContents / digsby_setup.exe / lib / gui / uberwidgets / uberbook / tabbar.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-02-26  |  25.1 KB  |  842 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from __future__ import with_statement
  5. from tab import Tab
  6. from gui import skin
  7. from OverlayImage import OverlayImage
  8. from navigation_arrows import Navi
  9. from gui.uberwidgets.UberButton import UberButton
  10. from gui.uberwidgets.UberEvents import EVT_DRAG_START
  11. import wx
  12. from wx import RectS, Rect, RectPS
  13. from util import do
  14. from common import pref, profile, prefprop
  15. from gui.uberwidgets import UberWidget
  16. from cgui import SimplePanel
  17. CUPID = wx.NewId()
  18. CDOWNID = wx.NewId()
  19. CLOSE_TAB = wx.NewId()
  20. CLOSE_OTHER_TABS = wx.NewId()
  21.  
  22. class TabBar(SimplePanel, UberWidget):
  23.     
  24.     def __init__(self, parent, skinkey):
  25.         SimplePanel.__init__(self, parent)
  26.         self.tabs = []
  27.         self.rows = []
  28.         self.rowindex = 0
  29.         self.tabindex = 0
  30.         self.tabendex = 0
  31.         events = [
  32.             (wx.EVT_PAINT, self.OnPaint),
  33.             (wx.EVT_SIZE, self.OnSize),
  34.             (wx.EVT_BUTTON, self.OnButton),
  35.             (wx.EVT_MOUSEWHEEL, self.OnWheel),
  36.             (wx.EVT_MOTION, self.OnMotion)]
  37.         for event, method in events:
  38.             self.Bind(event, method)
  39.         
  40.         self.flagedrows = set()
  41.         self.lastsize = self.Size
  42.         self.rowheight = 0
  43.         self.SetSkinKey(skinkey, True)
  44.         self.cupb = UberButton(self, CUPID, skin = self.scrollbuttonskin, icon = self.upicon)
  45.         self.cupb.Show(False)
  46.         self.cdownb = UberButton(self, CDOWNID, skin = self.scrollbuttonskin, icon = self.downicon)
  47.         self.cdownb.Show(False)
  48.         self.navi = Navi(self)
  49.         self.dragorigin = None
  50.         self.dragtarget = None
  51.         self.dropmarker = OverlayImage(self, self.dropmarkerimage)
  52.         self.dragside = None
  53.         link = profile.prefs.link
  54.         link('tabs.rows', self.Generate, False)
  55.         link('tabs.tabbar_x', self.Generate, False)
  56.         link('tabs.hide_at_1', self.Generate, False)
  57.         link('tabs.side_tabs', self.SkinRedirect, False)
  58.         self.Top.Bind(wx.EVT_MENU, self.OnMenuEvent)
  59.  
  60.     side_tabs = prefprop('tabs.side_tabs')
  61.     tab_rows = prefprop('tabs.rows', 2)
  62.     
  63.     def UpdateSkin(self):
  64.         key = self.tabskin = self.skinkey
  65.         
  66.         g = lambda k, default = (sentinel,): skin.get(key + '.' + k, default)
  67.         
  68.         sg = lambda k, default = (sentinel,): skin.get('side' + key + '.' + k, default)
  69.         elems = (('spacing', 'spacing', 2), ('bg', 'backgrounds.bar'), ('dropmarkerimage', 'dropmarker.image'), ('dropmarkeroffset', 'dropmarker.offset', 0), ('closebuttonskin', 'closebuttonskin', ''), ('closeicon', 'icons.close', None), ('scrollbuttonskin', 'scrollbuttonskin', ''), ('lefticon', 'icons.left', ''), ('righticon', 'icons.right', ''), ('upicon', 'icons.up', ''), ('downicon', 'icons.down', ''))
  70.         for elem in elems:
  71.             setattr(self, 'top' + elem[0], g(*elem[1:]))
  72.             setattr(self, 'side' + elem[0], sg(elem[1], getattr(self, 'top' + elem[0])))
  73.             None(setattr, self, elem[0](getattr, self if self.side_tabs else 'top' + elem[0]))
  74.         
  75.         if hasattr(self, 'dropmarker'):
  76.             self.dropmarker.SetImage(self.dropmarkerimage)
  77.             if self.side_tabs:
  78.                 pass
  79.             self.dropmarker.SetRotation(not (self.dropmarkerimage))
  80.         
  81.         navi = getattr(self, 'navi', None)
  82.         if navi is not None:
  83.             self.cdownb.SetSkinKey(self.scrollbuttonskin)
  84.             self.cupb.SetSkinKey(self.scrollbuttonskin)
  85.             self.cdownb.SetIcon(self.downicon)
  86.             self.cupb.SetIcon(self.upicon)
  87.             self.navi.closebutton.SetSkinKey(self.closebuttonskin)
  88.             self.navi.closebutton.SetIcon(self.closeicon)
  89.             scrollskin = self.scrollbuttonskin
  90.             navi.prevb.SetSkinKey(scrollskin)
  91.             navi.nextb.SetSkinKey(scrollskin)
  92.             navi.upb.SetSkinKey(scrollskin)
  93.             navi.downb.SetSkinKey(scrollskin)
  94.             navi.prevb.SetIcon(self.lefticon)
  95.             navi.nextb.SetIcon(self.righticon)
  96.             navi.upb.SetIcon(self.upicon)
  97.             navi.downb.SetIcon(self.downicon)
  98.         
  99.         wx.CallAfter(self.Generate)
  100.  
  101.     
  102.     def SkinRedirect(self, val = None):
  103.         elems = ('spacing', 'bg', 'dropmarkerimage', 'closebuttonskin', 'closeicon', 'scrollbuttonskin', 'lefticon', 'righticon', 'upicon', 'downicon')
  104.         for elem in elems:
  105.             None(setattr, self, elem(getattr, self if self.side_tabs else 'top' + elem))
  106.         
  107.         self.UpdateChildSkins()
  108.  
  109.     
  110.     def UpdateChildSkins(self):
  111.         self.cdownb.SetSkinKey(self.scrollbuttonskin, True)
  112.         self.cupb.SetSkinKey(self.scrollbuttonskin, True)
  113.         navi = self.navi
  114.         sbs = self.scrollbuttonskin
  115.         navi.closebutton.SetSkinKey(self.closebuttonskin, True)
  116.         navi.prevb.SetSkinKey(sbs, True)
  117.         navi.nextb.SetSkinKey(sbs, True)
  118.         navi.upb.SetSkinKey(sbs, True)
  119.         navi.downb.SetSkinKey(sbs, True)
  120.         self.UpdateChildrenIcons()
  121.         for tab in self.tabs:
  122.             tab.UpdateMode()
  123.         
  124.         self.Generate()
  125.  
  126.     
  127.     def __repr__(self):
  128.         return '<TabBar %r>' % self.tabs
  129.  
  130.     
  131.     def OnDragStart(self, tab):
  132.         self.NotifyDrag(tab)
  133.  
  134.     
  135.     def OnMotion(self, event):
  136.         if event.LeftIsDown():
  137.             if self.dragorigin or self.Manager.source:
  138.                 self.DragCalc(event.Position)
  139.             
  140.  
  141.     
  142.     def __getitem__(self, index):
  143.         return self.tabs[index]
  144.  
  145.     
  146.     def OnPaint(self, event):
  147.         dc = wx.PaintDC(self)
  148.         rect = RectS(self.Size)
  149.         if not self.side_tabs:
  150.             rcount = min(len(self.rows), pref('tabs.rows', 2))
  151.             height = self.tabs[0].Size.height
  152.             y = 0
  153.             for unused_i in xrange(rcount):
  154.                 self.bg.Draw(dc, Rect(rect.x, y, rect.width, height))
  155.                 y += height
  156.             
  157.         else:
  158.             self.bg.Draw(dc, rect)
  159.  
  160.     
  161.     def Add(self, page, focus, resort = True):
  162.         tab = Tab(self, page, skinkey = self.tabskin)
  163.         tab.Bind(wx.EVT_CONTEXT_MENU, self.ShowMenu)
  164.         tab.Show(False)
  165.         self.tabs.append(tab)
  166.         if focus:
  167.             wx.CallAfter(tab.SetActive, True)
  168.         elif resort:
  169.             if self.side_tabs:
  170.                 self.ReVgenerate()
  171.             else:
  172.                 self.Regenerate(True)
  173.         
  174.         return tab
  175.  
  176.     
  177.     def ShowMenu(self, e):
  178.         self._menutab = e.EventObject
  179.         
  180.         try:
  181.             menu = self._tabmenu
  182.         except AttributeError:
  183.             UMenu = UMenu
  184.             import gui.uberwidgets.umenu
  185.             menu = self._tabmenu = UMenu(self)
  186.             menu.AddItem('Close &Other Tabs', id = CLOSE_OTHER_TABS)
  187.             menu.AddSep()
  188.             menu.AddItem('&Close Tab', id = CLOSE_TAB)
  189.  
  190.         menu.PopupMenu()
  191.  
  192.     
  193.     def OnMenuEvent(self, e):
  194.         if e.Id == CLOSE_TAB:
  195.             self._menutab.CloseTab()
  196.         elif e.Id == CLOSE_OTHER_TABS:
  197.             menutab = self._menutab
  198.             menutab.active = True
  199.             self.Frozen().__enter__()
  200.             
  201.             try:
  202.                 for tab in self.tabs[:]:
  203.                     if tab is not menutab:
  204.                         tab.CloseTab()
  205.                         continue
  206.                     self.Frozen()
  207.             finally:
  208.                 pass
  209.  
  210.         else:
  211.             e.Skip()
  212.  
  213.     
  214.     def Generate(self, val = None):
  215.         self.navi.closebutton.Show(pref('tabs.tabbar_x', False))
  216.         if self.side_tabs:
  217.             self.ReVgenerate(True)
  218.         else:
  219.             self.Regenerate()
  220.  
  221.     
  222.     def ReVgenerate(self, total = False, safe = False, dotoggle = True):
  223.         tabs = self.tabs
  224.         if not tabs:
  225.             return None
  226.         
  227.         do((lambda .0: for tab in .0:
  228. tab.Show(False))(self.tabs))
  229.         for tab in self.tabs:
  230.             tab.row = None
  231.         
  232.         del self.rows[:]
  233.         if self.tabindex < 0 or self.tabindex >= len(tabs):
  234.             self.tabindex = 0
  235.         
  236.         n = self.tabindex
  237.         self.rowheight = tabs[0].GetMinHeight()
  238.         area = self.Notebook.Size.height - 32
  239.         i = area // self.rowheight
  240.         count = len(tabs)
  241.         for r in xrange(count):
  242.             tabs[r].row = r
  243.         
  244.         rows = self.rows
  245.         size = self.Size
  246.         navi = self.navi
  247.         navi.ShowNav(4)
  248.         navi.Hide()
  249.         navi.Position = wx.Point(size.width - navi.Size.width, 0)
  250.         if (total and not rows or i + 1 != len(rows[0])) and not (i > len(rows[0])) and len(rows[0]) == len(tabs):
  251.             rows.append([])
  252.             col = rows[0]
  253.             if i >= count:
  254.                 n = 0
  255.                 self.tabindex = 0
  256.                 (do,)((lambda .0: for tab in .0:
  257. col.append(tab))(tabs))
  258.                 av = col[0].MinSize.height
  259.             else:
  260.                 for t in xrange(n, n + i + 1):
  261.                     if t < len(tabs):
  262.                         col.append(tabs[t])
  263.                         continue
  264.                 
  265.                 while len(col) < i and n > 0:
  266.                     n -= 1
  267.                     col.insert(0, tabs[n])
  268.                 if col:
  269.                     av = col[0].MinSize.height
  270.                 
  271.         else:
  272.             col = rows[0]
  273.             av = col[0].MinSize.height
  274.         count = 16
  275.         for t in col:
  276.             t.Size = (self.Size.width, av)
  277.             t.Position = (0, count)
  278.             count += av
  279.             t.Show()
  280.         
  281.         self.tabindex = n
  282.         endex = self.tabendex = n + len(col)
  283.         if dotoggle:
  284.             self.Toggle()
  285.         
  286.         cupb = self.cupb
  287.         cdownb = self.cdownb
  288.         cupb.Enable(self.tabindex != 0)
  289.         if not endex < len(tabs):
  290.             pass
  291.         cdownb.Enable(tabs[endex - 1].Position.y + tabs[endex - 1].Size.height > size.height - 16)
  292.         self.UpdateNotify()
  293.  
  294.     
  295.     def Regenerate(self, safe = False, dotoggle = True):
  296.         if not self.IsShown() and len(self.tabs) == 1:
  297.             return None
  298.         
  299.         self.Frozen().__enter__()
  300.         
  301.         try:
  302.             self._Regenerate(safe = safe, dotoggle = dotoggle)
  303.         finally:
  304.             pass
  305.  
  306.         self.Refresh(False)
  307.  
  308.     
  309.     def _Regenerate(self, safe = False, dotoggle = True):
  310.         self.cupb.Show(False)
  311.         self.cdownb.Show(False)
  312.         parentpage = self.Parent.pagecontainer
  313.         style = self.tab_rows
  314.         if not safe:
  315.             pass
  316.         careful = parentpage.active
  317.         for tab in self.tabs:
  318.             tab.Show(False)
  319.             tab.row = None
  320.         
  321.         del self.rows[:]
  322.         tally = sum((lambda .0: for tab in .0:
  323. tab.MinSize.width)(self.tabs))
  324.         navi = self.navi
  325.         tabs = self.tabs
  326.         rows = self.rows
  327.         if not tabs:
  328.             return None
  329.         
  330.         if self.tabindex < 0 or self.tabindex >= len(tabs):
  331.             self.tabindex = 0
  332.         
  333.         n = self.tabindex
  334.         i = n
  335.         row = 0
  336.         self.rowheight = tabs[0].MinHeight
  337.         my_w = self.Size.width
  338.         nav_w = navi.Size.width
  339.         if tally >= my_w - nav_w and not style:
  340.             navi.ShowNav(1)
  341.         elif tally >= my_w - nav_w:
  342.             navi.ShowNav(3)
  343.         else:
  344.             navi.ShowNav(0)
  345.         navi.Freeze()
  346.         navi.Show(True)
  347.         navi.Fit()
  348.         navi.Position = wx.Point(self.Size.width - navi.Size.width, 0)
  349.         navi.Size = wx.Size(-1, self.Size.height)
  350.         navi.Thaw()
  351.         area = self.Notebook.Size.width - navi.Size.width
  352.         while len(tabs) > i:
  353.             tally = tabs[i].MinSize.width
  354.             rows.append([])
  355.             while i < len(tabs) and tally < area:
  356.                 i += 1
  357.                 if i < len(tabs):
  358.                     tally += tabs[i].MinSize.width
  359.                     continue
  360.             if careful and not style:
  361.                 activeindex = tabs.index(parentpage.active.tab)
  362.                 change = False
  363.                 while activeindex >= i and n != i:
  364.                     i += 1
  365.                     tally += tabs[i].MinSize.width
  366.                     change = True
  367.                 if tally >= area and change:
  368.                     tally -= tabs[n].MinSize.width
  369.                     n += 1
  370.                     self.tabindex = n
  371.                 
  372.             
  373.             if not style:
  374.                 while n > 0 and area - tally > tabs[n - 1].MinSize.width:
  375.                     n -= 1
  376.                     self.tabindex = n
  377.                     tally += tabs[n].MinSize.width
  378.             
  379.             if not style:
  380.                 break
  381.             
  382.             row += 1
  383.             n = i
  384.         row = self.rowindex
  385.         if not self.tab_rows:
  386.             pass
  387.         visible = 1
  388.         if careful and style:
  389.             active = parentpage.active.tab
  390.             for ir, r in enumerate(rows):
  391.                 if active in r:
  392.                     if ir < row:
  393.                         row = self.rowindex = ir
  394.                     elif ir >= row + visible:
  395.                         row = ir - visible - 1
  396.                     
  397.                 ir < row
  398.             
  399.         
  400.         if len(rows) - (row + 1) < visible and len(rows) >= visible:
  401.             row = len(rows) - visible
  402.             self.rowindex = row
  403.         
  404.         while row < len(rows) and row < self.rowindex + visible and len(rows[row]) != 0:
  405.             if rows.index(rows[row]) == len(rows) - 1:
  406.                 if style or len(rows[row]) == len(tabs):
  407.                     for t in xrange(0, len(rows[row])):
  408.                         thistab = rows[row][t]
  409.                         thistab.SetSize(thistab.MinSize)
  410.                         if not t:
  411.                             thistab.SetPosition((0, self.rowheight * (row - self.rowindex)))
  412.                         else:
  413.                             thistab.SetPosition((rows[row][t - 1].Position.x + rows[row][t - 1].Size.width, self.rowheight * (row - self.rowindex)))
  414.                         thistab.Show(True)
  415.                     
  416.                 elif len(rows) > row:
  417.                     ordered = [ rows[row].index(t) for t in sorted(rows[row], key = (lambda o: o.MinSize.width), reverse = True) ]
  418.                     length = len(ordered)
  419.                     reserved = 0
  420.                     o = 0
  421.                     av = (area - reserved) / (length - o)
  422.                     mark = 0
  423.                     while o < length:
  424.                         for t in xrange(o, length):
  425.                             tab = rows[row][ordered[t]]
  426.                             if tab.GetMinSize()[0] > av:
  427.                                 tab.SetSize(tab.MinSize)
  428.                                 reserved += tab.MinSize.width
  429.                                 o += 1
  430.                                 mark = o
  431.                                 if length - o:
  432.                                     av = (area - reserved) / (length - o)
  433.                                 
  434.                             length - o
  435.                             o += 1
  436.                         
  437.                         continue
  438.                         []
  439.                     for t in xrange(mark, length):
  440.                         tab = rows[row][ordered[t]]
  441.                         tab.SetSize((av, tab.MinSize.height))
  442.                     
  443.                     for t, tab in enumerate(rows[row]):
  444.                         tab.Show(True)
  445.                     
  446.                 
  447.             row += 1
  448.         if dotoggle:
  449.             self.Toggle()
  450.         
  451.         if len(rows) < style or not style:
  452.             rows_shown = len(rows)
  453.         else:
  454.             rows_shown = style
  455.         if self.Parent.SashPosition != rows_shown * self.rowheight:
  456.             self.MinSize = wx.Size(-1, rows_shown * self.rowheight)
  457.             self.Parent.SetSashPosition(self.MinSize.height)
  458.         
  459.         navi.Enabler()
  460.         self.tabendex = i - 1
  461.         self.UpdateNotify()
  462.         navi.Size = wx.Size(-1, rows_shown * self.rowheight)
  463.  
  464.     
  465.     def Remove(self, target):
  466.         index = self.tabs.index(target)
  467.         self.tabs.remove(target)
  468.         if len(self.tabs) == 0:
  469.             self.Notebook.window.Close()
  470.         elif index > self.tabindex and index < self.tabendex and self.tabindex > 0:
  471.             self.tabindex -= 1
  472.         
  473.         if self.side_tabs:
  474.             self.ReVgenerate(total = True)
  475.         else:
  476.             self.Regenerate(safe = True)
  477.  
  478.     
  479.     def OnSize(self, event):
  480.         event.Skip()
  481.         if self.side_tabs and self.tabs:
  482.             cupb = self.cupb
  483.             cdownb = self.cdownb
  484.             size = self.Size
  485.             tabs = self.tabs
  486.             endex = self.tabendex
  487.             cupb.Position = (0, 0)
  488.             cupb.Size = (size.width, 16)
  489.             cupb.Show()
  490.             cupb.Enable(self.tabindex != 0)
  491.             cdownb.Position = (0, size.height - 16)
  492.             cdownb.Size = (size.width, 16)
  493.             cdownb.Show()
  494.             if not endex < len(tabs):
  495.                 pass
  496.             cdownb.Enable(tabs[endex - 1].Position.y + tabs[endex - 1].Size.height > size.height - 16)
  497.         
  498.         sz = self.Size
  499.         if (sz.width != self.lastsize.width or not (self.side_tabs) or sz != self.lastsize or self.side_tabs) and self.IsShownOnScreen():
  500.             self.lastsize = sz
  501.             if self.side_tabs:
  502.                 self.ReVgenerate(dotoggle = False)
  503.             else:
  504.                 self.Regenerate(True, dotoggle = False)
  505.         
  506.         
  507.         try:
  508.             wx.CallAfter(wx.CallAfter, self.Parent.pagecontainer.active.panel.input_area.expandEvent)
  509.         except AttributeError:
  510.             pass
  511.  
  512.         self.Refresh(False)
  513.  
  514.     
  515.     def GetTabCount(self):
  516.         return [](_[1])
  517.  
  518.     
  519.     def NextTab(self):
  520.         self.SetNextActive(self.ActiveTab, wrap = True)
  521.  
  522.     
  523.     def PrevTab(self):
  524.         self.SetLastActive(self.ActiveTab, wrap = True)
  525.  
  526.     
  527.     def SetNextActive(self, origin, wrap = False):
  528.         if origin in self.tabs:
  529.             index = self.tabs.index(origin)
  530.             if not (index < len(self.tabs) - 1) and wrap:
  531.                 self.tabs[0].SetActive(True)
  532.             elif index < len(self.tabs) - 1:
  533.                 self.tabs[index + 1].SetActive(True)
  534.             elif index > 0:
  535.                 self.tabs[index - 1].SetActive(True)
  536.             
  537.             self.Refresh(False)
  538.         
  539.  
  540.     
  541.     def SetLastActive(self, origin, wrap = False):
  542.         if origin in self.tabs:
  543.             index = self.tabs.index(origin)
  544.             if not (index > 0) and wrap:
  545.                 self.tabs[len(self.tabs) - 1].SetActive(True)
  546.             elif index > 0:
  547.                 self.tabs[index - 1].SetActive(True)
  548.             elif index < 0:
  549.                 self.tabs[index + 1].SetActive(True)
  550.             
  551.             self.Refresh(False)
  552.         
  553.  
  554.     
  555.     def SyncActive(self, atab):
  556.         if not atab:
  557.             return None
  558.         
  559.         if self.side_tabs:
  560.             if atab < self.tabindex:
  561.                 self.tabindex = atab
  562.                 self.ReVgenerate(True)
  563.             else:
  564.                 thetab = self.tabs[atab]
  565.                 while atab >= self.tabendex or thetab.Position.y + thetab.Size.height > self.Size.height - 16:
  566.                     self.tabindex += 1
  567.                     self.ReVgenerate(True)
  568.                     continue
  569.                     self
  570.         else:
  571.             style = self.tab_rows
  572.             if atab < self.rowindex:
  573.                 self.rowindex = atab
  574.                 self.Regenerate()
  575.             elif atab > self.rowindex + style - 1:
  576.                 self.rowindex = (atab - style) + 1
  577.                 self.Regenerate()
  578.             
  579.  
  580.     
  581.     def OnWheel(self, event):
  582.         if RectS(self.Size).Contains(event.Position):
  583.             direction = event.GetWheelRotation()
  584.             if direction < 0:
  585.                 self.SetNextActive(self.ActiveTab, True)
  586.             elif direction > 0:
  587.                 self.SetLastActive(self.ActiveTab, True)
  588.             
  589.         
  590.  
  591.     
  592.     def Notebook(self):
  593.         return self.Parent
  594.  
  595.     Notebook = property(Notebook)
  596.     
  597.     def Manager(self):
  598.         return self.Notebook.manager
  599.  
  600.     Manager = property(Manager)
  601.     
  602.     def ActiveTab(self):
  603.         active = self.Notebook.pagecontainer.active
  604.         if active is not None:
  605.             return active.tab
  606.         
  607.  
  608.     ActiveTab = property(ActiveTab)
  609.     
  610.     def OnButton(self, event):
  611.         if event.GetId() == CUPID:
  612.             if self.tabindex > 0:
  613.                 self.tabindex -= 1
  614.                 self.ReVgenerate(total = True)
  615.             
  616.         elif event.GetId() == CDOWNID:
  617.             if self.tabendex < len(self.tabs) or self.tabs[self.tabendex - 1].Position.y + self.tabs[self.tabendex - 1].Size.height > self.Size.height - 16:
  618.                 self.tabindex += 1
  619.                 self.ReVgenerate(total = True)
  620.             
  621.         
  622.         self.UpdateNotify()
  623.  
  624.     
  625.     def NotifyDrag(self, origin):
  626.         self.dragorigin = origin
  627.         origin.SetCursor(wx.StockCursor(wx.CURSOR_NO_ENTRY))
  628.         self.Manager.Notify(self.Notebook)
  629.  
  630.     
  631.     def DragCalc(self, point):
  632.         sidetabs = self.side_tabs
  633.         if not (self.dragorigin) and self.Manager.source:
  634.             master = self.Manager.source
  635.             dragorigin = master.tabbar.dragorigin
  636.             self.Manager.Request(self.Notebook)
  637.         else:
  638.             dragorigin = self.dragorigin
  639.         if not (self.dragtarget) or not self.dragtarget.Rect.Contains(point):
  640.             wap = wx.FindWindowAtPointer()
  641.             self.dragtarget = None if isinstance(wap, Tab) else None
  642.             self.dragside = None
  643.         
  644.         if self.dragtarget and self.dragtarget != dragorigin:
  645.             dtrect = self.dragtarget.Rect
  646.             if not sidetabs:
  647.                 x = point[0] - dtrect.x
  648.                 x2 = dtrect.width / 2
  649.             else:
  650.                 x = point[1] - dtrect.y
  651.                 x2 = dtrect.height / 2
  652.             if x <= x2:
  653.                 if self.dragside != False:
  654.                     self.dragside = False
  655.                     if not sidetabs:
  656.                         self.DrawDropMarker(dtrect.x, dtrect.y)
  657.                     else:
  658.                         self.DrawDropMarker(dtrect.x, dtrect.y)
  659.                 
  660.             elif not self.dragside:
  661.                 self.dragside = True
  662.                 if not sidetabs:
  663.                     self.DrawDropMarker(dtrect.x + dtrect.width, dtrect.y)
  664.                 else:
  665.                     self.DrawDropMarker(dtrect.x, dtrect.y + dtrect.height)
  666.             
  667.             self.SetFocus()
  668.         elif not dragorigin or self.dragtarget != dragorigin:
  669.             if (dragorigin == None or self.dragtarget == None) and self.Rect.Contains(point):
  670.                 if not sidetabs:
  671.                     row = self.rows[point[1] // self.rowheight + self.rowindex]
  672.                     tab = row[len(row) - 1]
  673.                     self.dragside = True
  674.                 elif point.y > self.rowheight:
  675.                     tab = self.rows[0][len(self.rows[0]) - 1]
  676.                     self.dragside = True
  677.                 else:
  678.                     tab = self.rows[0][0]
  679.                     self.dragside = False
  680.                 dtrect = tab.Rect
  681.                 if not sidetabs:
  682.                     self.DrawDropMarker(dtrect.x + dtrect.width, dtrect.y)
  683.                 elif self.dragside == True:
  684.                     self.DrawDropMarker(dtrect.x, dtrect.y + dtrect.height)
  685.                 else:
  686.                     self.DrawDropMarker(dtrect.x + dtrect.width / 2, dtrect.y)
  687.                 self.SetFocus()
  688.                 self.dragtarget = tab
  689.             else:
  690.                 self.dropmarker.Show(False)
  691.  
  692.     
  693.     def Explode(self):
  694.         newwin = self.Notebook.window.winman.NewWindow
  695.         for x, tab in enumerate(self.tabs[1:]):
  696.             pos = wx.Point(30, 30) + (20 * (x + 1), 20 * (x + 1))
  697.             dest = newwin(self.Manager, pos).notebook
  698.             page = tab.page
  699.             del tab.page
  700.             del page.tab
  701.             self.tabs.remove(tab)
  702.             tab.Close()
  703.             dest.Insert(page)
  704.             wx.CallAfter(page.Show)
  705.         
  706.         self.tabs[0].SetActive(True)
  707.         if self.side_tabs:
  708.             self.ReVgenerate(True)
  709.         else:
  710.             self.Regenerate()
  711.  
  712.     
  713.     def DragFinish(self, new = False):
  714.         if not wx.IsDestroyed(self.dragorigin):
  715.             self.dragorigin.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
  716.         
  717.         if self.dragorigin and self.dragorigin.previewtabs:
  718.             self.dragorigin.previewtabs.Stop()
  719.             self.dragorigin.previewtabs = None
  720.         
  721.         rect = RectPS(self.Notebook.ClientToScreen(self.Position), self.Size)
  722.         parentrect = self.Notebook.window.Rect
  723.         mousepos = wx.GetMousePosition()
  724.         manager = self.Manager
  725.         if not new:
  726.             if manager.destination or not parentrect.Contains(mousepos) or not rect.Contains(mousepos):
  727.                 if self.ActiveTab == self.dragorigin:
  728.                     self.SetNextActive(self.dragorigin)
  729.                 
  730.                 self.dragorigin.Show(False)
  731.                 dest = manager.destination
  732.                 if not dest or not dest.tabbar.Rect.Contains(dest.ScreenToClient(wx.GetMousePosition())):
  733.                     originsize = self.dragorigin.GetSize()
  734.                     newpoint = wx.Point(mousepos[0] - originsize[0], mousepos[1] - originsize[1])
  735.                     destination = self.Notebook.window.winman.NewWindow(manager, newpoint, self.Notebook.window.GetSize()).notebook
  736.                 else:
  737.                     destination = dest
  738.                 manager.Request()
  739.                 page = self.dragorigin.page
  740.                 del self.dragorigin.page
  741.                 del page.tab
  742.                 self.tabs.remove(self.dragorigin)
  743.                 self.dragorigin.Close()
  744.                 destination.Insert(page, False)
  745.                 manager.Notify()
  746.                 self.dragorigin = None
  747.                 if self.side_tabs:
  748.                     self.ReVgenerate(True)
  749.                 else:
  750.                     self.Regenerate(safe = True)
  751.             elif self.dragtarget and self.dragorigin and self.dragorigin != self.dragtarget and self.Rect.Contains(self.Notebook.ScreenToClient(mousepos)):
  752.                 self.tabs.remove(self.dragorigin)
  753.                 pos = None + self.tabs.index(self.dragtarget) if self.dragside else 0
  754.                 self.tabs.insert(pos, self.dragorigin)
  755.                 if self.side_tabs:
  756.                     self.ReVgenerate(True)
  757.                 else:
  758.                     self.Regenerate()
  759.             elif new:
  760.                 if self.side_tabs:
  761.                     self.ReVgenerate(True)
  762.                 else:
  763.                     self.Regenerate()
  764.             
  765.         if self.dragorigin:
  766.             self.dragorigin.OnMouseLeave()
  767.         
  768.         self.dropmarker.Show(False)
  769.         self.dragorigin = None
  770.         self.dragtarget = None
  771.         dest = manager.destination
  772.         if dest:
  773.             dest.tabbar.dragorigin = None
  774.             dest.tabbar.dragtarget = None
  775.         
  776.         manager.Request()
  777.         manager.Notify()
  778.         if len(self.tabs) == 0:
  779.             self.Notebook.window.Close()
  780.         
  781.  
  782.     
  783.     def DrawDropMarker(self, x, y):
  784.         self.dropmarker.Teleport(self.ClientToScreen((x, y + self.dropmarkeroffset)))
  785.         if not self.dropmarker.IsShown():
  786.             self.Manager.ShowDropMarker(self.dropmarker)
  787.         
  788.  
  789.     
  790.     def Toggle(self, switch = None):
  791.         if pref('tabs.hide_at_1', True) and len(self.tabs) <= 1 and not switch:
  792.             self.Notebook.Split(False)
  793.             self.ProcessEvent(wx.CommandEvent(wx.wxEVT_SIZE))
  794.         else:
  795.             self.Notebook.Split(True)
  796.  
  797.     
  798.     def UpdateNotify(self):
  799.         frows = self.flagedrows
  800.         frows.clear()
  801.         if self.side_tabs:
  802.             tabs = self.tabs
  803.             for i, tab in enumerate(tabs):
  804.                 if tab.notified:
  805.                     frows.add(i)
  806.                     continue
  807.                 if i in self.flagedrows:
  808.                     frows.remove(i)
  809.                     continue
  810.             
  811.             if len(frows):
  812.                 pass
  813.             self.cupb.SetNotify(min(frows) < self.tabindex)
  814.             if not len(frows) and max(frows) >= self.tabendex:
  815.                 pass
  816.             self.cdownb.SetNotify(tabs[max(frows)].Position.y + tabs[max(frows)].Size.height > self.Size.height - 16)
  817.         else:
  818.             for i, row in enumerate(self.rows):
  819.                 flaged = False
  820.                 for tab in row:
  821.                     if tab and tab.notified:
  822.                         flaged = True
  823.                         frows.add(i)
  824.                         continue
  825.                 
  826.             
  827.             if len(frows):
  828.                 pass
  829.             self.navi.upb.SetNotify(min(frows) < self.rowindex)
  830.             if len(frows):
  831.                 pass
  832.             self.navi.downb.SetNotify(max(frows) > self.rowindex + self.tab_rows - 1)
  833.  
  834.  
  835.  
  836. try:
  837.     import psyco
  838. except ImportError:
  839.     pass
  840.  
  841. psyco.bind(TabBar)
  842.