Пример #1
0
    def __init__(self, parent, viewer):
        wx.Panel.__init__(self, parent)


        self.viewer = viewer

        # construct
        find_label = wx.StaticText(self, -1, _('Find'))
        self.TextControl = find_input = wx.TextCtrl(self, -1, size = (180, -1), style = wx.TE_PROCESS_ENTER)

        nextbutton = self.nextbutton = UberButton(self, label = _('Next'), skin = 'AppDefaults.PastButton')
        prevbutton = self.prevbutton = UberButton(self, label = _('Prev'), skin = 'AppDefaults.PastButton')

        # layout
        sz = self.Sizer = wx.BoxSizer(wx.HORIZONTAL)
        sz.AddMany([(find_label, 0, TOP | BOTTOM | LEFT | ALIGN_CENTER_VERTICAL | ALIGN_RIGHT, 6),
                    (find_input, 0, TOP | BOTTOM | LEFT | ALIGN_CENTER_VERTICAL , 6),
                    (nextbutton, 0, TOP | BOTTOM | LEFT | ALIGN_CENTER_VERTICAL | EXPAND , 6),
                    (prevbutton, 0, TOP | BOTTOM | LEFT | ALIGN_CENTER_VERTICAL | EXPAND , 6)])

        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)

        Bind = self.Bind
        Bind(wx.EVT_PAINT, self.OnPaint)
        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)

        fiBind = find_input.Bind
        fiBind(wx.EVT_TEXT,     self.OnFindText)
        fiBind(wx.EVT_KEY_DOWN, self.OnFindKey)

        nextbutton.Bind(wx.EVT_BUTTON, self.OnFindText)
        prevbutton.Bind(wx.EVT_BUTTON, lambda e: self.OnFindText(e,False))

        self.EnableFindButtons('')
Пример #2
0
def buttons(parent):

    yahoo = skin.load_bitmap('../../protocols/yahoo.png')

    s = 'button'
    b1 = UberButton(parent, -1, 'Skinned', skin=s)
    b2 = UberButton(parent, -1, 'Native', skin=None)
    b3 = UberButton(parent, -1, 'SkinnedPic', skin=s, icon=yahoo)
    b4 = UberButton(parent, -1, 'NativePic', skin=None, icon=yahoo)

    return [b1, b2, b3, b4]
Пример #3
0
    def __init__(self, parent, skinkey):
        SimplePanel.__init__(self, parent)

        self.tabs     = [] # a list of all the tabs
        self.rows     = [] # a list of all the visible row, each a list of all the tabs in that row
        self.rowindex = 0  # the first visible row
        self.tabindex = 0  # the first tab of the first visible row
        self.tabendex = 0  # the last tab of the last visible row

        events = [(wx.EVT_PAINT, self.OnPaint),
                  (wx.EVT_SIZE, self.OnSize),
                  (wx.EVT_BUTTON, self.OnButton),
                  (wx.EVT_MOUSEWHEEL, self.OnWheel),
                  (wx.EVT_MOTION,self.OnMotion)]

        for event, method in events: self.Bind(event, method)


        self.flagedrows = set()
        self.lastsize=self.Size

        self.rowheight=0#height of a row in pixels

        self.SetSkinKey(skinkey,True)

        #buttons for verticle alignment
        self.cupb = UberButton(self, CUPID, skin=self.scrollbuttonskin, icon=self.upicon)
        self.cupb.Show(False)

        self.cdownb = UberButton(self, CDOWNID, skin=self.scrollbuttonskin, icon=self.downicon)
        self.cdownb.Show(False)

        #the navigation box
        self.navi=Navi(self)


        self.dragorigin = None#when draging the tab that you are dragging
        self.dragtarget = None#when dragging the mouse is over and at that point released on

        # the arrow image shown when dragging tabs
        self.dropmarker=OverlayImage(self, self.dropmarkerimage)

        # self.dropmarker = Storage(Show = lambda v=True: None)
        self.dragside=None#was the tab droped on the left or right of the target tab

        #linking prefs
        link = profile.prefs.link #@UndefinedVariable
        link('tabs.rows',      self.Generate, False)
        link('tabs.tabbar_x',  self.Generate, False)
        link('tabs.hide_at_1', self.Generate, False)
        link('tabs.side_tabs', self.SkinRedirect, False)

        self.Top.Bind(wx.EVT_MENU, self.OnMenuEvent)
Пример #4
0
    def __init__(self, parent, xferlist):
        wx.Panel.__init__(self, parent)
        self.xferlist = xferlist

        self.Sizer = s = wx.BoxSizer(wx.VERTICAL)
        ftlist = FileTransferList(self, xferlist)
        s.Add(ftlist, 1, wx.EXPAND | wx.ALL)

        from gui.uberwidgets.UberBar import UberBar
        bar = self.bar = UberBar(
            self,
            skinkey=skin.get('FileTransfers.CleanupTaskBar'),
            alignment=wx.ALIGN_RIGHT)
        s.Add(self.bar, 0, wx.EXPAND)

        bar.AddStretchSpacer(1)
        self.cleanup = cleanup = UberButton(bar, -1, _('Clean Up'))
        cleanup.Bind(wx.EVT_BUTTON, self.on_cleanup)

        # button disabled when there are no transfers
        cleanup.Enable(bool(xferlist))
        xferlist.add_gui_observer(self.on_xfer)
        self.Bind(wx.EVT_WINDOW_DESTROY,
                  lambda e, w=self: self.xferlist.remove_observer(self.on_xfer)
                  if e.EventObject is w else None)

        bar.Add(cleanup)
Пример #5
0
    def __init__(self):
        wx.Frame.__init__(self, None, title='Simple Menu Test')
        self.panel = wx.Panel(self)

        self.panel.Sizer = wx.BoxSizer(wx.VERTICAL)

        menu = SimpleMenu(self, skinkey='simplemenu', maxheight=10, width=100)

        items = [
            SimpleMenuItem('Test1'),  #,self.DifferentMethodTest),
            SimpleMenuItem('Test2'),
            SimpleMenuItem('Test3'),
            SimpleMenuItem(id=-1),
            SimpleMenuItem('Test4')
        ]

        menu.SetItems(items)

        skin = 'button'
        size = None  #(100,100)#
        type = 'menu'  #None#'toggle'#
        #menu=None#self.menu#
        icon = None  #wx.Bitmap('../../../res/skins/default/statusicons/mobile.png',wx.BITMAP_TYPE_PNG)#wx.Bitmap('../../res/skins/default/tinydigsby.png',wx.BITMAP_TYPE_PNG)

        self.smb1 = UberButton(self.panel,
                               wx.NewId(),
                               "SMB",
                               skin,
                               icon=icon,
                               style=wx.HORIZONTAL,
                               size=size,
                               type=type,
                               menu=menu)

        self.panel.Sizer.Add(self.smb1)
Пример #6
0
    def __init__(self, parent):
        SimplePanel.__init__(self, parent, wx.FULL_REPAINT_ON_RESIZE)

        content = self.content = wx.BoxSizer(wx.VERTICAL)

        self.SetSkinKey('AccountPanels', True)

        cl = self.cl = ConnectionList(self)
        content.Add(cl, 1, wx.EXPAND)

        statebutton = self.statebutton = UberButton(self,
                                                    icon=self.iconshow,
                                                    skin=self.buttonskin)
        self.button_has_been_pressed = False
        statebutton.Bind(wx.EVT_BUTTON, self.__OnButtonClick)

        if self.expandup:
            content.Add(statebutton, 0, wx.EXPAND)
        else:
            content.Insert(0, statebutton, 0, wx.EXPAND)

        self.Sizer = MarginSizer(self.framesize, content)

        Bind = self.Bind
        Bind(wx.EVT_SIZE, self.OnSize)
        Bind(wx.EVT_PAINT, self.OnPaint)

        profile.prefs.add_observer(self.WhenOrderChanges,
                                   'buddylist.order')  #@UndefinedVariable
Пример #7
0
    def __init__(self):
        wx.Frame.__init__(self,None,title='Extended Simple Menu Test')
        self.panel=wx.Panel(self)

        self.panel.Sizer=wx.BoxSizer(wx.VERTICAL)


        menu=SimpleMenu(self, 'simplemenu',width=100)
        submenu=SimpleMenu(menu, 'simplemenu',width=100)
        submenu2=SimpleMenu(submenu, 'simplemenu',width=100)

        subitems=[
            SimpleMenuItem('Test5'),
            SimpleMenuItem(id=-1),
            SimpleMenuItem('Test6'),
            SimpleMenuItem('Test7',menu=submenu2),
            SimpleMenuItem('Test8')
        ]

        submenu.SetItems(subitems)

        items=[
            SimpleMenuItem('Test1'),
            SimpleMenuItem('Test2'),
            SimpleMenuItem("Test3 is a submenu m'kay",menu=submenu),
            SimpleMenuItem(id=-1),
            SimpleMenuItem('Test4'),
        ]

        items3=[
            SimpleMenuItem('Test9'),
            SimpleMenuItem('Test10'),
            SimpleMenuItem('Test11'),
            SimpleMenuItem('Test12'),
            SimpleMenuItem('Test13'),
            SimpleMenuItem('Test14'),
            SimpleMenuItem('Test15'),
            SimpleMenuItem('Test16'),
            SimpleMenuItem('Test17')
        ]

        submenu2.SetItems(items3)


        menu.SetItems(items)

        skin='button'
        size=None#(100,100)#
        type='menu'#None#'toggle'#
        #menu=None#self.menu#
        icon=wx.Bitmap('../../../res/skins/default/statusicons/mobile.png',wx.BITMAP_TYPE_PNG)#wx.Bitmap('../../res/skins/default/tinydigsby.png',wx.BITMAP_TYPE_PNG)

        self.smb1=UberButton(self.panel,wx.NewId(),"SMB",skin,icon=icon,style=wx.HORIZONTAL,size=size,type=type,menu=menu)

        self.panel.Sizer.Add(self.smb1)

        self.Bind(wx.EVT_MENU,self.OnMenu)
Пример #8
0
    def CreateSendButton(self):

        self.spacer = SpacerPanel(self, skinkey='inputspacer')
        self.inputsizer.Add(self.spacer, 0, wx.EXPAND)

        sendbutton = self.sendbutton = UberButton(
            self, label=_('Send'),
            skin='InputButton')  #wx.Button(self, label = _('Send'))
        self.inputsizer.Add(sendbutton, 0, wx.EXPAND)
        sendbutton.Bind(wx.EVT_BUTTON, lambda e: self.entercallback(self))
Пример #9
0
    def SetButton(self, label, callback):
        if self.button:
            self.headersizer.Detach(self.button)
            self.button.Destroy()

        # native button on mac instead of the vista clone button
        if not wxMac:
            self.button = UberButton(self,
                                     -1,
                                     label,
                                     skin='AppDefaults.PrefButton')
        else:
            self.button = wx.Button(self, -1, label)
            self.button.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)

        self.button.Bind(wx.EVT_BUTTON, lambda e: callback(self.button))

        self.headersizer.AddStretchSpacer(1)
        self.headersizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL | RIGHT,
                             7)
Пример #10
0
    def __init__(self, parent):
        """
            standard fair
        """
        wx.Panel.__init__(self, parent, style=0)

        events=[
            (wx.EVT_PAINT,self.OnPaint),
            (wx.EVT_ERASE_BACKGROUND, lambda e:None),
            (wx.EVT_BUTTON, self.OnButton)
        ]
        do(self.Bind(event, method) for (event, method) in events)

        #make sizers
        self.Sizer=wx.BoxSizer(wx.HORIZONTAL)
        self.hsizer=wx.BoxSizer(wx.HORIZONTAL)
        self.vsizer=wx.BoxSizer(wx.VERTICAL)

        #make Buttons
        self.closebutton=UberButton(self, CLOSEID, skin=self.Parent.closebuttonskin, icon=self.Parent.closeicon)
        self.prevb=UberButton(self, PREVID, skin=self.Parent.scrollbuttonskin, icon=self.Parent.lefticon)
        self.nextb=UberButton(self, NEXTID, skin=self.Parent.scrollbuttonskin, icon=self.Parent.righticon)
        self.upb=UberButton(self, UPID, skin=self.Parent.scrollbuttonskin, icon=self.Parent.upicon)
        self.downb=UberButton(self, DOWNID, skin=self.Parent.scrollbuttonskin, icon=self.Parent.downicon)

        #add butons to sizers
        self.hsizer.Add(self.prevb, 0, wx.EXPAND)
        self.hsizer.Add(self.nextb, 0, wx.EXPAND)
        self.vsizer.Add(self.upb, 1, wx.EXPAND)
        self.vsizer.Add(self.downb, 1, wx.EXPAND)
        self.Sizer.Add(self.hsizer, 0, wx.EXPAND)
        self.Sizer.Add(self.closebutton, 0, wx.CENTER|wx.ALL, 5)

        #Hide all buttons
        self.prevb.Show(False)
        self.nextb.Show(False)
        self.upb.Show(False)
        self.downb.Show(False)
        self.closebutton.Show(pref('tabs.tabbar_x', False))

        self.type=None
Пример #11
0
    def _constructSkinElements(self):
        'Creates the buttons that launch menu dropdowns in the bar.'

        s, p = self.skin, self.panel
        p.bg = s.get("background", SkinColor(wx.WHITE))

        pad = p.padding = s.get("padding", wx.Point(0, 0))

        for child in list(p.Children):
            child.Hide()
            child.Destroy()

        v = wx.BoxSizer(wx.VERTICAL)
        h = wx.BoxSizer(wx.HORIZONTAL)
        v.Add(h, 1, wx.EXPAND | wx.TOP | wx.BOTTOM, pad.y)

        p.Sizer = s.get('margins', Margins()).Sizer(v)

        # create a button for each item in the menubar
        self.buttons = []
        addb = self.buttons.append
        menus, nummenus = self.Menus, len(self.Menus)
        for i, (menu, label) in enumerate(menus):

            del menu.OnDismiss[:]

            # the API sucks for getting Titles with mnemonic characters
            label = self.toptitles.get(menu, label)

            #            (self, parent, id = -1, label='', skin='Button', icon=None,
            #                 pos=wx.DefaultPosition, size=None, style=wx.HORIZONTAL,
            #                 type=None, menu=None, menubarmode=False, onclick = None):
            button = UberButton(p,
                                -1,
                                skin=s.itemskin,
                                label=label,
                                type="menu",
                                menu=menu,
                                menubarmode=True)
            addb(button)

            # store some special attributes in the menu, which it will use for
            # keyboard/mouse navigation of the menubar
            menu._next = menus[(i + 1) % nummenus][0]
            menu._prev = menus[i - 1][0]
            menu._button = button

        # add buttons to the size
        h.AddMany((b, 0, wx.EXPAND | wx.LEFT, pad.x) for b in self.buttons)

        # bind keyboard accelerators
        self._bindAccelerators()
Пример #12
0
def main():
    a = testapp()
    f = wx.Frame(None)

    bar = UberBar(f, skinkey='ButtonBarSkin', overflowmode=True)

    for x in xrange(5):
        title = 'test %d' % x
        b = UberButton(bar, -1, title)
        bar.Add(b)

    f.Show()
    a.MainLoop()
Пример #13
0
    def __init__(self):
        wx.Frame.__init__(self, None, wx.NewId(), "UberBar sampler", (0, 0),
                          (600, 150))
        events = [
            #(wx.EVT_BUTTON,self.onButton)
        ]
        do(self.Bind(event, method) for (event, method) in events)
        content = wx.BoxSizer(wx.VERTICAL)

        self.skin = 'buttonbar'  #None#

        self.ubar = UberBar(self, skinkey=self.skin, alignment=wx.ALIGN_LEFT)
        self.b1 = UberButton(self.ubar,
                             -1,
                             'Button 1',
                             icon=wx.Bitmap(
                                 resdir / 'skins/default/digsbybig.png',
                                 wx.BITMAP_TYPE_PNG))
        self.b2 = UberButton(self.ubar,
                             -1,
                             'Button 2',
                             style=wx.VERTICAL,
                             icon=wx.Bitmap(
                                 resdir / 'skins/default/digsbybig.png',
                                 wx.BITMAP_TYPE_PNG))
        self.b3 = UberButton(self.ubar,
                             -1,
                             'Button 3',
                             icon=wx.Bitmap(
                                 resdir / 'skins/default/digsbybig.png',
                                 wx.BITMAP_TYPE_PNG))
        self.ubar.Add(self.b1)
        self.ubar.Add(self.b2)
        self.ubar.AddSpacer()
        self.ubar.Add(self.b3)

        content.Add(self.ubar, 0, wx.EXPAND, 0)
        self.SetSizer(content)
Пример #14
0
class F4(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.NewId(), "UberBar Overflow sampler",
                          (0, 0), (600, 150))

        content = wx.BoxSizer(wx.VERTICAL)

        self.skin = 'buttonbar'  #None#

        self.ubar = UberBar(self,
                            skinkey=self.skin,
                            overflowmode=True,
                            alignment=wx.ALIGN_LEFT)
        self.b1 = UberButton(self.ubar, -1, 'Button 1')
        self.b2 = UberButton(self.ubar, -1, 'Button 2')
        self.bi = UberButton(self.ubar, -1, 'Button i')
        self.b3 = UberButton(self.ubar, -1, 'Button 3')
        self.b4 = UberButton(self.ubar, -1, 'Button 4')
        self.ubar.Add(self.b1)
        self.ubar.Add(self.b2)
        self.ubar.Add(self.bi)
        self.ubar.Add(self.b3)
        self.ubar.Add(self.b4)

        #        self.b1.Show(self.b1,False)
        self.bi.Show(self.bi, False)

        self.ubar.AddMenuItem(SimpleMenuItem('Menu Item 1'))
        self.ubar.AddMenuItem(SimpleMenuItem('Menu Item 2'))
        self.ubar.AddMenuItem(SimpleMenuItem('Menu Item 3'))

        self.b4 = UberButton(self.ubar,
                             -1,
                             icon=wx.Bitmap(
                                 resdir / 'skins/default/digsbybig.png',
                                 wx.BITMAP_TYPE_PNG))
        self.ubar.AddStatic(self.b4)

        content.Add(self.ubar, 0, wx.EXPAND, 0)
        self.SetSizer(content)
Пример #15
0
    def __init__(self,
                 parent,
                 buddylist,
                 statuses,
                 get_status_method=get_profile_status,
                 set_status_method=set_profile_status):
        '''
        StatusCombo constructor.

        parent   - a wx.Window parent window
        statuses - an observable list of StatusMessage objects
        '''

        self.buddylist = buddylist
        self.buddylist.Bind(wx.EVT_KEY_DOWN, self.on_buddylist_key)
        self.searching = False
        self.searchHintShown = False

        if not getattr(StatusCombo, 'searchThresholdRegistered',
                       False) and pref('search.buddylist.show_hint', True):

            def SearchThresholdReached(*a, **k):
                if pref('search.buddylist.show_hint', True):
                    setpref('search.buddylist.show_hint', False)

            Hook('digsby.achievements.threshold',
                 'buddylist.search').register(SearchThresholdReached)
            StatusCombo.searchThresholdRegistered = True

        self.offline_item = None
        self.get_profile_status = get_status_method
        self.set_profile_status = set_status_method

        status = self.get_profile_status()

        UberCombo.__init__(self,
                           parent,
                           skinkey='combobox',
                           typeable=True,
                           valuecallback=self.on_text_lose_focus,
                           empty_text=getattr(status, 'hint',
                                              status.title.title()),
                           maxmenuheight=15)

        self.buttoncallback = self.on_status_button
        self.cbutton = UberButton(self, -1, skin=self.cbuttonskin)
        self.cbutton.Bind(wx.EVT_BUTTON, self._on_left_button)
        self.content.Insert(0, self.cbutton, 0, wx.EXPAND)

        self.cbutton.BBind(RIGHT_UP=self.on_status_button_right_click,
                           LEFT_DOWN=self.on_status_button_left_click,
                           LEFT_UP=self.on_status_button_left_up)

        self.display.Bind(
            wx.EVT_LEFT_DOWN, lambda e:
            (e.Skip(), setattr(self, 'oldValue', self.Value)))

        # the on_allow_status_changes method is called when the list of connected
        # im accounts changes size. if all accounts are offline this control
        # becomes disabled..

        #profile.account_manager.connected_accounts.add_observer(self.on_allow_status_changes)
        profile.account_manager.connected_accounts.add_observer(
            self.on_offline_allowed, obj=self)

        # Listen on status messages (changes, additions, deletes).
        _obs_link = statuses.add_list_observer(self.on_status_messages_changed,
                                               self.on_status_messages_changed)
        self.Bind(
            wx.EVT_WINDOW_DESTROY, lambda e:
            (log.info('status combo removing observers'), e.Skip(),
             _obs_link.disconnect()))

        self.on_status_messages_changed(statuses)

        # when the profile's status changes, update to reflect it
        profile.add_observer(self.on_profile_status_changed, 'status')

        # Display the current status.
        self.show_status(self.get_profile_status())

        # Timer for committing status messages after a delay.
        self.timer = wx.PyTimer(self.SetFocus)
        self.Bind(wx.EVT_TEXT, self.on_typing)

        self.button_timer = wx.PyTimer(self.on_status_button_right_click)

        textbind = self.TextField.Bind
        textbind(wx.EVT_SET_FOCUS, lambda e: setattr(self, 'skipenter', False))
        textbind(wx.EVT_KEY_DOWN, self._on_key_down)
        textbind(wx.EVT_TEXT_ENTER, self._on_enter)

        self.DropDownButton.Bind(wx.EVT_LEFT_DOWN, self._dbutton_left)

        self.OnActivateSearch = Delegate()
        self.OnDeactivateSearch = Delegate()
Пример #16
0
    bitmap = skin.load_bitmap('error.png')

    b = UButton(p, label = '&Digsby', bitmap = bitmap); s.Add(b)

    b.Bind(wx.EVT_BUTTON, lambda e, but=b: setattr(but, 'Native', not getattr(but, 'Native')))

    b = UButton(p, label = 'Digsby &Rocks', bitmap = bitmap); s.Add(b)
    b = UButton(p, label = '&Exact Fit', style = wx.BU_EXACTFIT); s.Add(b)
    b = UButton(p, label = '&Cancel'); s.Add(b)
    b = UButton(p, label = 'Disab&led'); s.Add(b); b.Enable(False)

    b = UButton(p, label = 'Digs&by', bitmap = bitmap, style = wx.BU_RIGHT, menuMode = True); s.Add(b, 0, wx.EXPAND)
    b = UButton(p, label = 'Digsby Rocks', bitmap = bitmap, style = wx.BU_RIGHT); s.Add(b, 0, wx.EXPAND)
    b = UButton(p, label = '&OK'); s.Add(b, 0, wx.EXPAND)
    b = UButton(p, label = 'Cancel'); s.Add(b, 0, wx.EXPAND)

    s.AddSpacer((30,30))

    from gui.uberwidgets.UberButton import UberButton

    hs = wx.BoxSizer(wx.HORIZONTAL)
    for x in xrange(4):
        b = UberButton(p, label = 'UberButton'); hs.Add(b, 1, wx.EXPAND)

    s.Add(hs, 0, wx.EXPAND)

    def printsrc(e): print e.EventObject
    p.Bind(wx.EVT_BUTTON, printsrc)

    f.Show()
    a.MainLoop()
Пример #17
0
class PrefPanel(SimplePanel):
    def __init__(self,
                 parent,
                 content=None,
                 title='',
                 buttonlabel='',
                 buttoncb=None,
                 titlemaker=None,
                 prefix=''):
        SimplePanel.__init__(self, parent, wx.FULL_REPAINT_ON_RESIZE)

        sizer = self.Sizer = BoxSizer(VERTICAL)
        self.headersizer = BoxSizer(HORIZONTAL)
        self.bodysizer = BoxSizer(VERTICAL)
        sizer.Add(self.headersizer, 0, EXPAND | TOP, space_over_header)
        sizer.Add(self.bodysizer, 1, EXPAND | TOP, space_under_header)

        self.title = None
        self.combo = None
        self.button = None
        self.content = None
        self.contents = {}
        self.titlemaker = titlemaker
        if wxMac:
            self.menuitems = {}

        if title and isinstance(title, basestring):
            self.title = wx.StaticText(self,
                                       -1,
                                       ' ' + title + ' ',
                                       style=wx.ALIGN_CENTER_VERTICAL)

            #need grey backgound behind label on mac to hide the line
            if wxMac:
                self.title.BackgroundColour = wx.Color(232, 232, 232)
            self.title.Font = self.HeaderFont
            self.headersizer.Add(self.title, 0, *header_sizer_flags)

        if callable(content):
            content = self.content = content(self, prefix)
            self.bodysizer.Add(self.content, 1, pref_sizer_style, 7)
        elif isinstance(content, wx.WindowClass):
            content.Reparent(self)
            self.content = content
            self.bodysizer.Add(self.content, 1, pref_sizer_style, 7)
        elif isinstance(content, list):
            self.SetContents(content)

        if buttoncb:
            self.SetButton(buttonlabel, buttoncb)

        Bind = self.Bind
        Bind(wx.EVT_PAINT, self.OnPaint)

        #darker border if mac so it is visible for now
        if not wxMac:
            self.pen = wx.Pen(wx.Colour(213, 213, 213))
        else:
            self.pen = wx.Pen(wx.Colour(155, 155, 155))

    def SetTitle(self, title):
        self.title.SetLabel(title)

    @property
    def HeaderFont(self):
        try:
            return self._headerfont
        except AttributeError:
            if not wxMac:
                PrefPanel._headerfont = makeFont('arial 8 bold')
            else:
                PrefPanel._headerfont = makeFont('9 bold')
            return self._headerfont

    _fg_brush = \
    _bg_brush = \
    _fg_pen = \
    _bg_pen = lambda self: None

    def get_bg_brush(self):
        return self._bg_brush() or wx.WHITE_BRUSH

    def get_fg_brush(self):
        return self._fg_brush() or wx.TRANSPARENT_BRUSH

    def get_bg_pen(self):
        return self._bg_pen() or wx.TRANSPARENT_PEN

    def get_fg_pen(self):
        return self._fg_pen() or self.pen

    bg_brush = property(get_bg_brush)
    fg_brush = property(get_fg_brush)
    bg_pen = property(get_bg_pen)
    fg_pen = property(get_fg_pen)

    def OnPaint(self, event):
        size = self.Size
        dc = AutoDC(self)

        if not wxMac:
            # Non mac: white background, rounded rectangle around controls
            rect = wx.RectS(size)
            dc.Brush = self.bg_brush  #background
            dc.Pen = self.bg_pen  #background border
            dc.DrawRectangleRect(rect)
            ypos = self.headersizer.Size.height // 2 + space_over_header
            gc = wx.GraphicsContext.Create(dc)
            gc.SetBrush(self.fg_brush)  #foreground
            gc.SetPen(self.fg_pen)  #foreground
            gc.DrawRoundedRectangle(0, ypos, size.width - 1,
                                    size.height - ypos - 1, 5)
        else:
            # Mac: normal grey background, horizontal line above controls
            ypos = self.headersizer.Size.height // 2 + space_over_header + 2
            dc.Pen = self.fg_pen
            button_width = 0 if self.button is None else (
                self.button.Size.width)
            dc.DrawLine(10, ypos,
                        self.headersizer.Size.width - 10 - button_width, ypos)

        content = self.content
        if isinstance(content, AnyList):  # TODO: don't special case
            crect = wx.Rect(*content.Rect)
            crect = crect.Inflate(1, 1)
            dc.SetBrush(wx.TRANSPARENT_BRUSH)
            dc.SetPen(self.pen)
            dc.DrawRectangleRect(crect)

    def ChangeShownContent(self, *a):
        if self.content:
            self.content.Show(False)

        if wxMac:
            menu_item = self.menuitems[self.combo.GetStringSelection()]
        else:
            menu_item = self.combo.Value

        self.content = self.contents[menu_item]
        self.content.Show(True)
        self.Layout()

    def SetButton(self, label, callback):
        if self.button:
            self.headersizer.Detach(self.button)
            self.button.Destroy()

        # native button on mac instead of the vista clone button
        if not wxMac:
            self.button = UberButton(self,
                                     -1,
                                     label,
                                     skin='AppDefaults.PrefButton')
        else:
            self.button = wx.Button(self, -1, label)
            self.button.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)

        self.button.Bind(wx.EVT_BUTTON, lambda e: callback(self.button))

        self.headersizer.AddStretchSpacer(1)
        self.headersizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL | RIGHT,
                             7)

    @property
    def MenuItems(self):
        combo = self.combo
        if wxMac:
            return [combo.GetClientData(i) for i in xrange(combo.Count)]
        else:
            return combo.menu.spine.items

    def SetContents(self, content, destroyold=False):
        if destroyold:
            if not self.contents:
                self.content.Destroy()
            for content in self.contents.values():
                content.Destroy()

        # the currently showing pane in a multiple pane pref panel
        if self.content:
            self.content.Show(False)
            self.content = None

        self.bodysizer.Clear()
        contents = self.contents = {}

        titlemaker = self.titlemaker

        if self.combo is None:
            if not wxMac:
                self.combo = UberCombo(self,
                                       value='',
                                       skinkey='AppDefaults.PrefCombo',
                                       valuecallback=self.ChangeShownContent)
            else:
                # use a native ComboBox on mac
                self.combo = wx.ComboBox(self,
                                         style=wx.CB_DROPDOWN | wx.CB_READONLY)
                self.combo.Bind(wx.EVT_COMBOBOX, self.ChangeShownContent)
            newcombo = True
        else:
            self.combo.RemoveAllItems()
            newcombo = False

        for object in content:
            if isinstance(object, tuple):
                window, label = object
            elif isinstance(object, wx.WindowClass):
                window = object
                label = titlemaker(window) if titlemaker else object.Label

            window.Show(False)
            window.Reparent(self)
            assert window.Parent is self
            self.bodysizer.Add(window, 1, pref_sizer_style, 7)

            menuitem = SimpleMenuItem(label)
            contents[menuitem] = window

            if wxMac:
                itemname = menuitem.GetContentAsString()
                self.combo.Append(itemname)
                self.menuitems[itemname] = menuitem
            else:
                self.combo.AppendItem(menuitem)

        if self.combo:
            if wxMac:
                self.combo.SetSelection(0)
                self.ChangeShownContent()
            else:
                self.combo.Value = self.combo[0]

        if self.combo is not None and newcombo:
            self.headersizer.Add(self.combo, 1, *combo_sizer_flags)
Пример #18
0
class TabBar(SimplePanel, UberWidget):
    """
        Where the tabs live, handles all display and organization functionality
    """
    def __init__(self, parent, skinkey):
        SimplePanel.__init__(self, parent)

        self.tabs     = [] # a list of all the tabs
        self.rows     = [] # a list of all the visible row, each a list of all the tabs in that row
        self.rowindex = 0  # the first visible row
        self.tabindex = 0  # the first tab of the first visible row
        self.tabendex = 0  # the last tab of the last visible row

        events = [(wx.EVT_PAINT, self.OnPaint),
                  (wx.EVT_SIZE, self.OnSize),
                  (wx.EVT_BUTTON, self.OnButton),
                  (wx.EVT_MOUSEWHEEL, self.OnWheel),
                  (wx.EVT_MOTION,self.OnMotion)]

        for event, method in events: self.Bind(event, method)


        self.flagedrows = set()
        self.lastsize=self.Size

        self.rowheight=0#height of a row in pixels

        self.SetSkinKey(skinkey,True)

        #buttons for verticle alignment
        self.cupb = UberButton(self, CUPID, skin=self.scrollbuttonskin, icon=self.upicon)
        self.cupb.Show(False)

        self.cdownb = UberButton(self, CDOWNID, skin=self.scrollbuttonskin, icon=self.downicon)
        self.cdownb.Show(False)

        #the navigation box
        self.navi=Navi(self)


        self.dragorigin = None#when draging the tab that you are dragging
        self.dragtarget = None#when dragging the mouse is over and at that point released on

        # the arrow image shown when dragging tabs
        self.dropmarker=OverlayImage(self, self.dropmarkerimage)

        # self.dropmarker = Storage(Show = lambda v=True: None)
        self.dragside=None#was the tab droped on the left or right of the target tab

        #linking prefs
        link = profile.prefs.link #@UndefinedVariable
        link('tabs.rows',      self.Generate, False)
        link('tabs.tabbar_x',  self.Generate, False)
        link('tabs.hide_at_1', self.Generate, False)
        link('tabs.side_tabs', self.SkinRedirect, False)

        self.Top.Bind(wx.EVT_MENU, self.OnMenuEvent)

    side_tabs = prefprop('tabs.side_tabs')
    tab_rows = prefprop('tabs.rows', 2)

    def UpdateSkin(self):
        key = self.tabskin = self.skinkey
        g   = lambda k, default = sentinel: skin.get(key + '.' + k, default)
        sg   = lambda k, default = sentinel: skin.get('side' + key + '.' + k, default)

        elems = (('spacing', 'spacing',          2),
                 ('bg', 'backgrounds.bar'),
                 ('dropmarkerimage', 'dropmarker.image'),
#                 ('dropmarkeroverlay', 'dropmarker.overlay', 0),
                 ('dropmarkeroffset', 'dropmarker.offset', 0),
                 ('closebuttonskin', 'closebuttonskin', ''),
                 ('closeicon', 'icons.close', None),
                 ('scrollbuttonskin', 'scrollbuttonskin', ''),
                 ('lefticon', 'icons.left', ''),
                 ('righticon', 'icons.right', ''),
                 ('upicon', 'icons.up', ''),
                 ('downicon', 'icons.down', ''))

        for elem in elems:
            setattr(self, 'top' + elem[0], g(*elem[1:]))
            setattr(self, 'side' + elem[0], sg(elem[1],getattr(self,'top' + elem[0])))
            setattr(self, elem[0], getattr(self, ('side' if self.side_tabs else 'top') + elem[0]))


        if hasattr(self,'dropmarker'):
            self.dropmarker.SetImage(self.dropmarkerimage)
            self.dropmarker.SetRotation((self.side_tabs and not self.dropmarkerimage))

        navi = getattr(self, 'navi', None)
        if navi is not None:
            self.cdownb.SetSkinKey(self.scrollbuttonskin)
            self.cupb.SetSkinKey(self.scrollbuttonskin)
            self.cdownb.SetIcon(self.downicon)
            self.cupb.SetIcon(self.upicon)

            self.navi.closebutton.SetSkinKey(self.closebuttonskin)

            self.navi.closebutton.SetIcon(self.closeicon)

            scrollskin = self.scrollbuttonskin

            navi.prevb.SetSkinKey(scrollskin)
            navi.nextb.SetSkinKey(scrollskin)
            navi.upb.SetSkinKey(scrollskin)
            navi.downb.SetSkinKey(scrollskin)

            navi.prevb.SetIcon(self.lefticon)
            navi.nextb.SetIcon(self.righticon)
            navi.upb.SetIcon(self.upicon)
            navi.downb.SetIcon(self.downicon)

        wx.CallAfter(self.Generate)


    def SkinRedirect(self,val=None):
        elems = ('spacing',
                 'bg',
                 'dropmarkerimage',
                 #'dropmarkeroverlay',
                 'closebuttonskin',
                 'closeicon',
                 'scrollbuttonskin',
                 'lefticon',
                 'righticon',
                 'upicon',
                 'downicon'
                 )

        for elem in elems:
            setattr(self, elem, getattr(self,('side' if self.side_tabs else 'top') + elem))

        self.UpdateChildSkins()

    def UpdateChildSkins(self):
        self.cdownb.SetSkinKey(self.scrollbuttonskin,True)
        self.cupb.SetSkinKey(self.scrollbuttonskin,True)

        navi, sbs = self.navi, self.scrollbuttonskin
        navi.closebutton.SetSkinKey(self.closebuttonskin,True)
        navi.prevb.SetSkinKey(sbs, True)
        navi.nextb.SetSkinKey(sbs, True)
        navi.upb.SetSkinKey(sbs, True)
        navi.downb.SetSkinKey(sbs, True)

        self.UpdateChildrenIcons()

        for tab in self.tabs:
            tab.UpdateMode()

        self.Generate()

    def __repr__(self):
        return '<TabBar %r>' % self.tabs

    def OnDragStart(self, tab):
        'Catches the tab drag event and starts the tab dragging system.'

        self.NotifyDrag(tab)

    def OnMotion(self,event):
        'Positioning updates during drag and drop'

        if event.LeftIsDown() and (self.dragorigin or self.Manager.source):
            self.DragCalc(event.Position)

    def __getitem__(self, index):
        return self.tabs[index]

    def OnPaint(self, event):
        dc   = wx.PaintDC(self)
        rect = RectS(self.Size)
        if not self.side_tabs:
            rcount = min(len(self.rows), pref('tabs.rows', 2))
            height = self.tabs[0].Size.height

            y=0
            for unused_i in xrange(rcount):
                self.bg.Draw(dc, Rect(rect.x, y, rect.width, height))
                y += height

        else:
            self.bg.Draw(dc,rect)

    def Add(self, page, focus, resort = True):
        """
            Adds a tab to the bar.  Should only be used by parent NoteBook.
            page - page in PageContainer the tab is to be associated with
            focus - whether that tab should steal focus from current tab
        """
        tab = Tab(self, page, skinkey = self.tabskin)
        tab.Bind(wx.EVT_CONTEXT_MENU, self.ShowMenu)
        tab.Show(False)
        self.tabs.append(tab)

        if focus:
            wx.CallAfter(tab.SetActive, True)

        elif resort:
            if self.side_tabs:
                self.ReVgenerate()
            else:
                self.Regenerate(True)

        return tab

    def ShowMenu(self, e):
        self._menutab = e.EventObject

        try:
            menu = self._tabmenu
        except AttributeError:
            from gui.uberwidgets.umenu import UMenu
            menu = self._tabmenu = UMenu(self)
            menu.AddItem('Close &Other Tabs', id = CLOSE_OTHER_TABS)
            menu.AddSep()
            menu.AddItem('&Close Tab', id = CLOSE_TAB)

        menu.PopupMenu()

    def OnMenuEvent(self, e):
        '''Invoked when a tab context menu item is clicked.'''

        if e.Id == CLOSE_TAB:
            self._menutab.CloseTab()
        elif e.Id == CLOSE_OTHER_TABS:
            menutab = self._menutab

            # switch to that tab first
            menutab.active = True

            with self.Frozen():
                for tab in self.tabs[:]:
                    if tab is not menutab:
                        tab.CloseTab()
        else:
            e.Skip()

    def Generate(self, val=None):
        self.navi.closebutton.Show(pref('tabs.tabbar_x', False))

        if self.side_tabs:
            self.ReVgenerate(True)
        else:
            self.Regenerate()

    def ReVgenerate(self,total=False, safe=False, dotoggle=True):
        """
        It's like Doo... err.. Regenerate, only vertical
        """

#        print "Starting: Regenerate",self.Top.Title,'\n'#,'='*80,'\n','\n'.join(format_stack())
#        print '='*80

        #TODO: Should we be careful about the tab leaving the bar?
        tabs = self.tabs

        if not tabs: return

        do(tab.Show(False) for tab in self.tabs)
        for tab in self.tabs: tab.row = None
        del self.rows[:]

        # Safty precautions prevent list access errors
        if self.tabindex < 0 or self.tabindex >= len(tabs):
            self.tabindex = 0

        # Preset variables
        n = self.tabindex   # the first tab shown
        self.rowheight = tabs[0].GetMinHeight()
        area = self.Notebook.Size.height - 32 # Height in pixels of the tabbar

        # number of fully visible rows in the given area at the given height
        i = area//self.rowheight

        count = len(tabs)

        #one tab per row
        for r in xrange(count): tabs[r].row=r

        rows = self.rows
        size = self.Size

        #Sets navimode and position
        navi = self.navi
        navi.ShowNav(4)
        navi.Hide()
        navi.Position = wx.Point(size.width - navi.Size.width,0)

        # Totally reconstructs the list if it's told to or there are not tabs in the rows or
        # if there isn't one more tab than there is room for and there is enough room to fit
        # them all and number of tabs in the row equals the number of tabs
        if total or not rows or (i + 1 != len(rows[0])) and not (i > len(rows[0])) and len(rows[0]) == len(tabs):
            rows.append([])
            col = rows[0]

            #if all tabs fit
            if i >= count:
                n=0
                self.tabindex=0
                do(col.append(tab) for tab in tabs)
                av=col[0].MinSize.height
            #calculate and show range
            else:
                for t in xrange(n,n+i+1):
                    if t < len(tabs):col.append(tabs[t])

                # populate with earlier stuff
                while len(col) < i and n > 0:
                    n-=1
                    col.insert(0,tabs[n])

                if col: av = col[0].MinSize.height
        else:
            #just leave the new values the same as the old
            col = rows[0]
            av  = col[0].MinSize.height

        # Show all tabs in the bar
        count = 16
        for t in col:
            t.Size = (self.Size.width,av)
            t.Position = (0,count)
            count += av
            t.Show()

        self.tabindex=n
        endex = self.tabendex=n+len(col)

        if dotoggle:
            self.Toggle()

        cupb, cdownb = self.cupb, self.cdownb


        cupb.Enable(self.tabindex != 0)
        cdownb.Enable(endex < len(tabs) or tabs[endex - 1].Position.y +
                           tabs[endex-1].Size.height > size.height - 16)


        self.UpdateNotify()

    def Regenerate(self, safe = False, dotoggle=True):
        '''
        Regenerates layout information.

        safe is a flag to indicate if we should try to keep the currently active
        tab in view at all times. (This doesn't occur when scrolling, for
        instance.)
        '''

#        print "Starting: Regenerate",self.Top.Title,'\n','='*80,'\n','\n'.join(format_stack())
#        print '='*80
        # early exit for when the tabbar isn't visible.
        if not self.IsShown() and len(self.tabs) == 1:
            return

        with self.Frozen():
            self._Regenerate(safe = safe, dotoggle = dotoggle)

        self.Refresh(False)

    def _Regenerate(self, safe = False, dotoggle = True):
        self.cupb.Show(False)
        self.cdownb.Show(False)
        parentpage = self.Parent.pagecontainer

        # style is the number of rows (or 0 for single)
        style = self.tab_rows

        # Should we be careful about the tab leaving the bar?
        careful = not safe and parentpage.active

        # Hide all tabs preparation for refilling
        for tab in self.tabs:
            tab.Show(False)
            tab.row = None
        del self.rows[:]

        # navi set up, see if arrows are needed and placement
        tally = sum(tab.MinSize.width for tab in self.tabs) #total size of tabs

        navi = self.navi
        tabs = self.tabs
        rows = self.rows

        if not tabs: return

        # Tab alignment calculations

        # Saftey precautions prevent list access errors
        if self.tabindex < 0 or self.tabindex >= len(tabs):
            self.tabindex = 0

        # Preset variables
        n = self.tabindex   # the first tab shown
        i = n
        row = 0
        self.rowheight = tabs[0].MinHeight


        my_w, nav_w = self.Size.width, navi.Size.width

        # Decide what kind of navigation panel, if any, to use...
        if tally >= my_w - nav_w and not style:
            navi.ShowNav(1) # arrows left and right
        elif tally >= (my_w - nav_w):
            navi.ShowNav(3) # arrows up and down next to the X
        else:
            navi.ShowNav(0)

        #Where to put navigation panel.
        navi.Freeze()
        navi.Show(True)
        navi.Fit()
        navi.Position = wx.Point(self.Size.width-navi.Size.width,0)
        navi.Size = wx.Size(-1,self.Size.height)
        navi.Thaw()

        #More preparing vars
        area = self.Notebook.Size.width - navi.Size.width

        #While more tabs are not in a row
        while len(tabs) > i:
            tally = tabs[i].MinSize.width
            rows.append([])

            # Loop through each visible tab, fitting tabs on the right.
            while i < len(tabs) and tally < area:
                i += 1
                if i < len(tabs):
                    tally += tabs[i].MinSize.width

            #Be carefull that the active tab doesn't scroll off the bar
            if careful and not style:
                activeindex = tabs.index(parentpage.active.tab)
                change=False

                #add tabs until the active tab is visible
                while activeindex>=i and n!=i:
                    i += 1
                    tally += tabs[i].MinSize.width
                    change = True

                #Remove tab if more tabs than room
                if tally >= area and change:
                    tally -= tabs[n].MinSize.width
                    n += 1
                    self.tabindex=n




            # If extra space, fit tabs to the right of the row
            if not style: # if single row,
                while n > 0 and area - tally > tabs[n-1].MinSize.width:
                    n -= 1
                    self.tabindex = n
                    tally += tabs[n].MinSize.width


            # Injects tabs calculated to fit in that row into that row
            if range(n, i):
                rows[row] = [tabs[t] for t in xrange(n, i)]
                for tab in rows[row]:
                    tab.row=row
            else:
                rows[row].append(tabs[i])
                i += 1

            if not style: break # If we're in single row, break now.
            row += 1
            n = i
        # Row calculation

        if self.rowindex >= len(rows):
            self.rowindex = len(rows) - 1

        #cycle through visible rows
        row = self.rowindex
        visible = self.tab_rows or 1

        if careful and style:
            #print "Being Careful"
            active = parentpage.active.tab
            #print active
            for ir,r in enumerate(rows):
                #print ir,r
                if active in r:
                    if ir<row:
                        #print "moving index down"
                        row = self.rowindex = ir
                    elif ir >= row + visible:
                        #print "moving index up"
                        row = ir - (visible - 1)


        # If we're closing tabs above where is visible, keep the visible
        # index "where it is"
        if len(rows) - (row + 1) < visible and len(rows) >= visible:
            row = len(rows) - visible
            self.rowindex = row

        # Place tabs!
        while row < len(rows) and row < self.rowindex + visible and len( rows[row] ) != 0:

            # if this is a row that needs to be scrunched...
            if rows.index(rows[row]) == len(rows)-1 and \
                (style or len(rows[row]) == len(tabs)):

                for t in xrange(0,len(rows[row])):
                    thistab = rows[row][t]
                    thistab.SetSize(thistab.MinSize)
                    if not t:
                        # The first tab is set to it's minimum width at x: 0
                        thistab.SetPosition((0, self.rowheight*(row-self.rowindex)))
                    else:
                        # Every other tab is placed right next to the tab
                        # before it.
                        thistab.SetPosition((rows[row][t-1].Position.x \
                                             + rows[row][t-1].Size.width,
                                             self.rowheight*(row-self.rowindex)))
                    thistab.Show(True)

            # If there are more rows than the current row...
            elif len(rows) > row:
                # Get a list of tab indices, widest to smallest.
                ordered = [rows[row].index(t)
                           for t in sorted(rows[row],
                                           key=lambda o: o.MinSize.width,
                                                         reverse=True) ]
                length = len(ordered)
                reserved=0
                o=0 # o_O ?

                # Average width of tab if all tabs are the same size, and
                # fill up all the area.
                av = (area - reserved) / (length - o)
                mark = 0
                while o < length:
                    # Loop from "current" tab to the end
                    for t in xrange(o, length):
                        tab = rows[row][ordered[t]]

                        # If this tab is larger than average...
                        if tab.GetMinSize()[0] > av:
                            # Make it it's minimum, and keep track of it
                            tab.SetSize(tab.MinSize)
                            reserved += tab.MinSize.width
                            o += 1
                            mark = o

                            # If we're not on the last tab, recalc average
                            if (length - o):
                                av=(area-reserved)/(length-o)
                        else:
                            o += 1
                            break

                # For tabs less than the average, set them to average
                for t in xrange(mark, length):
                    tab = rows[row][ordered[t]]
                    tab.SetSize((av, tab.MinSize.height))

                # For every tab in the row
                for t, tab in enumerate(rows[row]):
                    if not t: # If it's the first tab:
                        if length==1:
                            # If the row is so small it can only fit one tab,
                            # make due.
                            tab.Size = wx.Size(area, tab.MinSize.height)
                        tab.Position = wx.Point(0, self.rowheight * (row - self.rowindex))
                    else:
                        tab.Position = wx.Point(rows[row][t-1].Position.x + rows[row][t-1].Size.width,
                                                self.rowheight * (row - self.rowindex))

                    tab.Show(True)
            row += 1
        if dotoggle:
            self.Toggle()

        # If total rows is less than total rows being shown, shrink the
        # tab area so that it's only just big enough.
        if len(rows) < style or not style:
            rows_shown = len(rows)
        else:
            rows_shown = style
        if  self.Parent.SashPosition != rows_shown * self.rowheight:#self.MinSize.height
            self.MinSize = wx.Size(-1, rows_shown * self.rowheight)
            self.Parent.SetSashPosition(self.MinSize.height)
#            self.Size=self.MinSize

        # Determine if the Navi needs to enable or show arrows
        navi.Enabler()
        #self.Parent.Layout()    # Relayout self
        self.tabendex = i-1     # final tab being shown

        self.UpdateNotify()

        navi.Size = wx.Size(-1,rows_shown * self.rowheight)

    def Remove(self, target):
        'Removes the tab specified from the bar.'

        index=self.tabs.index(target)
        self.tabs.remove(target)
        #if no more tabs close window
        if len(self.tabs)==0:
            self.Notebook.window.Close()
        else:
            #if index is between index and endex and bring one tab from the left
            if index>self.tabindex and index<self.tabendex and self.tabindex>0:
                self.tabindex-=1

            if self.side_tabs:
                self.ReVgenerate(total=True)
            else:
                self.Regenerate(safe = True)


    def OnSize(self, event):
        'ReLayout the tabs if the bar on event of a resize'
        event.Skip()

        if self.side_tabs and self.tabs:
            cupb   = self.cupb
            cdownb = self.cdownb
            size   = self.Size
            tabs = self.tabs
            endex = self.tabendex

            # position and size buttons
            cupb.Position = (0,0)
            cupb.Size = (size.width, 16)
            cupb.Show()
            cupb.Enable(self.tabindex != 0)

            cdownb.Position = (0, size.height - 16)
            cdownb.Size     = (size.width, 16)
            cdownb.Show()
            cdownb.Enable(endex < len(tabs) or tabs[endex - 1].Position.y +
                           tabs[endex-1].Size.height > size.height - 16)


        sz = self.Size
        if ((sz.width != self.lastsize.width and not self.side_tabs) or (sz != self.lastsize and self.side_tabs)) and self.IsShownOnScreen():
            self.lastsize = sz
            if self.side_tabs:
                self.ReVgenerate(dotoggle = False)
            else:
                self.Regenerate(False,dotoggle = False)

        try:
            wx.CallAfter(wx.CallAfter,self.Parent.pagecontainer.active.panel.input_area.expandEvent)
        except AttributeError:
            pass

        self.Refresh(False)


    def GetTabCount(self):
        """
            Returns the number of tabs in the bar
        """
        return len([t for t in self if t])

    def NextTab(self):
        self.SetNextActive(self.ActiveTab, wrap = True)

    def PrevTab(self):
        self.SetLastActive(self.ActiveTab, wrap = True)


    def SetNextActive(self, origin,wrap=False):
        """
            Sets the tab after the curent active
            -if it does not exist does the previbus
            -or the first if wrap is true
        """
        if origin in self.tabs:
            index=self.tabs.index(origin)
            if not index < len(self.tabs)-1 and wrap:
                self.tabs[0].SetActive(True)
            elif index < len(self.tabs)-1:
                self.tabs[index+1].SetActive(True)
            elif index>0:
                self.tabs[index-1].SetActive(True)
            self.Refresh(False)

    def SetLastActive(self, origin, wrap = False):
        """
            Sets the tab before the curent active
            -if it does not exist does the next
            -or the last if wrap is true
        """
        if origin in self.tabs:
            index=self.tabs.index(origin)
            if not index > 0 and wrap:
                self.tabs[len(self.tabs)-1].SetActive(True)
            elif index >0:
                self.tabs[index-1].SetActive(True)
            elif index<0:
                self.tabs[index+1].SetActive(True)
            self.Refresh(False)

    def SyncActive(self,atab):
        """
            Moves the index and endex so that the active tab is in the bar
        """
        if not atab: return

        if self.side_tabs:
            if atab < self.tabindex:
                self.tabindex=atab
                self.ReVgenerate(True)
            else:
                thetab=self.tabs[atab]
                while atab >= self.tabendex or thetab.Position.y+thetab.Size.height > self.Size.height-16:
                    self.tabindex+=1
                    self.ReVgenerate(True)
        else:
            style = self.tab_rows
            if atab < self.rowindex:
                self.rowindex=atab
                self.Regenerate()
            elif atab > self.rowindex+style-1:
                self.rowindex=atab-style+1
                self.Regenerate()

    def OnWheel(self,event):
        """
            Event that handles mouse wheeling,
            maps the events to SetNextActive and SetLastActive
        """
        if RectS(self.Size).Contains(event.Position):
            direction = event.GetWheelRotation()
            if direction<0:
                self.SetNextActive(self.ActiveTab, True)
            elif direction>0:
                self.SetLastActive(self.ActiveTab, True)

    @property
    def Notebook(self):
        return self.Parent

    @property
    def Manager(self):
        return self.Notebook.manager

    @property
    def ActiveTab(self):
        active = self.Notebook.pagecontainer.active
        if active is not None:
            return active.tab

    def OnButton(self,event):
        """
            The button events for vertical alignment for up and down
        """
        if event.GetId()==CUPID:
            if self.tabindex > 0:
                self.tabindex -= 1
                self.ReVgenerate(total = True)
        elif event.GetId()==CDOWNID:
            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:
                self.tabindex+=1
                self.ReVgenerate(total=True)

        self.UpdateNotify()

    def NotifyDrag(self, origin):
        """
            When a tab is dragged this is called to start the tabbar handling dragging
            origin - tab being dragged
        """
        # Lets the TabMan know a tab as been dragged
        self.dragorigin = origin
        origin.SetCursor(wx.StockCursor(wx.CURSOR_NO_ENTRY))
        self.Manager.Notify(self.Notebook)


    def DragCalc(self,point):
        """
            This does the dragging calculations for the tabs
        """

        sidetabs = self.side_tabs

        # if here is no local origin tab but there is a remote source identified in TabMan
        if not self.dragorigin and self.Manager.source:
            #setting a local drag origin
            master = self.Manager.source
            dragorigin=master.tabbar.dragorigin
            # announcing to TabMan it is expecting a tab
            self.Manager.Request(self.Notebook)
        # if there is a local origin use that
        else:
            dragorigin=self.dragorigin

        # if dragtarget is out of date find what you're dragging to
        if not self.dragtarget or not self.dragtarget.Rect.Contains(point):

            wap = wx.FindWindowAtPointer()
            self.dragtarget = wap if isinstance(wap,Tab) else None
            self.dragside   = None

        # if there is a tab as target
        if self.dragtarget and self.dragtarget != dragorigin:
            dtrect=self.dragtarget.Rect
            # data to decide what side the tab would be dropped on
            if not sidetabs:
                x  = point[0] - dtrect.x
                x2 = dtrect.width / 2
            else:
                x  = point[1] - dtrect.y
                x2 = dtrect.height / 2
            # make the left/top or right/bottom decision
            if x <= x2:#left/top
                if self.dragside!=False:
                    self.dragside=False
                    if not sidetabs:
                        self.DrawDropMarker(dtrect.x, dtrect.y)# + (dtrect.height // 2)
                    else:
                        self.DrawDropMarker(dtrect.x, dtrect.y)# + dtrect.width // 2

            elif not self.dragside:#right/bottom
                self.dragside=True
                if not sidetabs:
                    self.DrawDropMarker(dtrect.x+dtrect.width,dtrect.y)#+(dtrect.height//2)
                else: self.DrawDropMarker(dtrect.x,dtrect.y+dtrect.height)#+dtrect.width//2
            self.SetFocus()
        # if being dropped in the whitespace of the TabBar
        elif (dragorigin and self.dragtarget!=dragorigin) or (dragorigin==None and self.dragtarget==None) and self.Rect.Contains(point):
            # find what row the tab is being dropped in
            if not sidetabs:
                row=self.rows[(point[1]//self.rowheight)+self.rowindex]
                tab=row[len(row)-1]
                self.dragside=True
            # or in vertical if at the beginning or end
            else:
                if point.y>self.rowheight:
                    tab=self.rows[0][len(self.rows[0])-1]
                    self.dragside=True
                else:
                    tab=self.rows[0][0]
                    self.dragside=False
            dtrect=tab.Rect
            #Place marker
            if not sidetabs: self.DrawDropMarker(dtrect.x+dtrect.width,dtrect.y)#+(dtrect.height//2)
            elif self.dragside==True: self.DrawDropMarker(dtrect.x,dtrect.y+dtrect.height)#+dtrect.width//2
            else: self.DrawDropMarker(dtrect.x+dtrect.width/2,dtrect.y)
            self.SetFocus()
            #cleanup
            self.dragtarget=tab

        else:#if not in tabbar anymore don't show arrow
            self.dropmarker.Show(False)

    def DragFinish(self,new=False):
        """
        Ends dragging and does any rearranging if required
        """

        if not wx.IsDestroyed(self.dragorigin):
            self.dragorigin.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))

        if self.dragorigin and self.dragorigin.previewtabs:
            # Destroy the preview tab
            self.dragorigin.previewtabs.Stop()
            self.dragorigin.previewtabs = None

        rect       = RectPS(self.Notebook.ClientToScreen(self.Position), self.Size)
        parentrect = self.Notebook.window.Rect
        mousepos   = wx.GetMousePosition()
        manager    = self.Manager

        #if released out of the window...
        if not new and ((manager.destination and not parentrect.Contains(mousepos)) or not rect.Contains(mousepos)):
            if self.ActiveTab==self.dragorigin:
                self.SetNextActive(self.dragorigin)
            self.dragorigin.Show(False)

            #If no or invalid destination in manager create a new window and sets it destination
            dest = manager.destination
            if not dest or not dest.tabbar.Rect.Contains(dest.ScreenToClient(wx.GetMousePosition())):
                # FIXME: SWIG doesn't like subtracting a wx.Size from a wx.Point, so do it the hard way
                # until the SIP migration is finished.
                originsize = self.dragorigin.GetSize()
                newpoint = wx.Point(mousepos[0] - originsize[0], mousepos[1] - originsize[1])
                destination = self.Notebook.winman.NewWindow(newpoint, self.Notebook.window.GetSize()).notebook
            #else set the destination to the manager's destination
            else:
                destination = dest

            #clear tabman's destination
            manager.Request()

            # Grab a reference to the tab's page
            page = self.dragorigin.page

            # Make the tab "forget" about the page
            self.Notebook.did_remove(page.panel)
            del self.dragorigin.page
            del page.tab

            # Remove the tab from the tabs list, and destroy the wxWindow
            self.tabs.remove(self.dragorigin)

            self.dragorigin.Close()

            # remove page from this notebook and insert it into the target notebook
            #page.Parent.RemoveChild(page)
            destination.Insert(page, False)

            # cleanup
            manager.Notify()
            self.dragorigin=None

            # re-sort tabs
            if self.side_tabs:
                self.ReVgenerate(True)
            else:
                self.Regenerate(safe = True)

        # if released inside of the window
        # used both for moving within a window and as the last step of a
        # interwindow move in case of interwindow tab has already been moved to
        # this window at the end of the list and all that is left is to move it
        # to the correct position.
        elif self.dragtarget and self.dragorigin and self.dragorigin!=self.dragtarget and self.Rect.Contains(self.Notebook.ScreenToClient(mousepos)):
            #remove the tab from the list
            self.tabs.remove(self.dragorigin)

            #decide which side of the target the tab should be dropped
            pos = self.tabs.index(self.dragtarget) + (1 if self.dragside else 0)

            # Reinsert the tab in it's new position
            self.tabs.insert(pos, self.dragorigin)

            after = self.tabs[pos+1] if pos+1 < len(self.tabs) else None
            if after is not None:
                after = after.page.panel

            # call after so that windows are all in their correct places
            wx.CallAfter(self.Notebook.did_rearrange, self.dragorigin.page.panel, after)

#            # Resort
            if self.side_tabs:
                self.ReVgenerate(True)
            else:
                self.Regenerate()
        elif new:
            if self.side_tabs:
                self.ReVgenerate(True)
            else:
                self.Regenerate()

        #if there is a dragorigin run onMouseLeave on it to reset it's look
        if self.dragorigin:
            self.dragorigin.OnMouseLeave()

        #local cleanup
        self.dropmarker.Show(False)
        self.dragorigin=None
        self.dragtarget=None

        #destination and manager cleanup
        dest = manager.destination
        if dest:
            dest.tabbar.dragorigin=None
            dest.tabbar.dragtarget=None

        manager.Request()
        manager.Notify()

        if len(self.tabs)==0: self.Notebook.window.Close()

    def DrawDropMarker(self,x,y):
        """
        Places the marker for where to drop the tab
        x and y are center position, saves calculation that way
        """

#        if self.side_tabs:
#            self.dropmarker.SetSize((self.Size.width - self.dropmarkeroverlay, -1))
#        else:
#            self.dropmarker.SetSize((-1, self.rowheight - self.dropmarkeroverlay))
        self.dropmarker.Teleport(self.ClientToScreen((x, y+self.dropmarkeroffset)))

        if not self.dropmarker.IsShown():
            self.Manager.ShowDropMarker(self.dropmarker)

    def Toggle(self, switch = None):
        'Toggle whether the tabbar is hidden or shown.'

        if pref('tabs.hide_at_1', True) and len(self.tabs) <= 1 and not switch:
            self.Notebook.Split(False)

            #make sure the content of the IM win resizes if tabbaar hides
            self.ProcessEvent(wx.CommandEvent(wx.wxEVT_SIZE))
        else:
            self.Notebook.Split(True)


    def UpdateNotify(self):

        frows = self.flagedrows
        frows.clear()

        # Resort
        if self.side_tabs:
            tabs=self.tabs
            for i, tab in enumerate(tabs):
                if tab.notified:
                    frows.add(i)
                elif i in self.flagedrows:
                    frows.remove(i)

            self.cupb.SetNotify(len(frows) and min(frows) < self.tabindex)
            self.cdownb.SetNotify(len(frows) and (max(frows) >= self.tabendex or
                                                  tabs[max(frows)].Position.y + tabs[max(frows)].Size.height > self.Size.height - 16))
        else:
            for i, row in enumerate(self.rows):
                flaged = False
                for tab in row:
                    if tab and tab.notified:
                        flaged = True
                        frows.add(i)
            self.navi.upb.SetNotify(len(frows) and min(frows)<self.rowindex)
            self.navi.downb.SetNotify(len(frows) and max(frows)>self.rowindex + self.tab_rows - 1)
Пример #19
0
class P(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self,parent,-1)#,style = wx.CLIP_CHILDREN|wx.CLIP_SIBLINGS

        self.Bind(wx.EVT_BUTTON,self.onButton),
        self.Bind(wx.EVT_LEFT_UP,self.OnMouse),
        self.Bind(wx.EVT_LEFT_DOWN,self.OnMouse)

        self.skin = 'button'
#        print self.skin
#        self.menu=UMenu(self)
#        self.menu.Append(wx.NewId(),'item 1')
#        self.menu.Append(wx.NewId(),'item 2')
#        self.menu.Append(wx.NewId(),'item 3')

        content=wx.BoxSizer(wx.VERTICAL)

        size=None#(200,50)#
        type=None#'menu'#'toggle'#'toggle'#
        menu=None#self.menu#
        icon=wx.Bitmap('../../../../res/skins/default/statusicons/mobile.png',wx.BITMAP_TYPE_PNG)#wx.Bitmap('../../res/skins/default/tinydigsby.png',wx.BITMAP_TYPE_PNG)
        #label= "button"#"Super wide Button Name of Impending doooooooooooom!!!"#"button"#
        skin=self.skin#None#

        self.b1=UberButton(self,wx.NewId(),'&One',skin,icon=icon,style=wx.HORIZONTAL,size=size,type=type,menu=menu)
#        self.b1.SetStaticWidth(60)
        self.b2=UberButton(self,wx.NewId(),'&Two',icon=icon,style=wx.HORIZONTAL,size=size,type=type,menu=menu)
        self.b3=UberButton(self,wx.NewId(),'T&hree',skin,icon=icon,style=wx.VERTICAL,size=size,type=type,menu=menu)
        self.b4=UberButton(self,wx.NewId(),'&Four',icon=icon,style=wx.VERTICAL,size=size,type=type,menu=menu)
        self.b5=UberButton(self,wx.NewId(),"",skin,icon=icon,size=size,type=type,menu=menu)
        self.b6=UberButton(self,wx.NewId(),"",icon=icon,size=size,type=type,menu=menu)
        self.b7=UberButton(self,wx.NewId(),'Fi&ve',skin,size=size,type=type,menu=menu)
        self.b8=UberButton(self,wx.NewId(),'&Six',size=size,type=type,menu=menu)
        self.b9=UberButton(self,wx.NewId(),"",skin,size=size,type=type,menu=menu)
        self.b10=UberButton(self,wx.NewId(),"",size=size,type=type,menu=menu)
        self.b11 = wx.Button(self, wx.NewId(), 'Native')
        self.b12= wx.Button(self, wx.NewId(), ' ')
        self.b12.Bind(wx.EVT_BUTTON,self.ToggleAlignment)

        self.b13 = UberButton(self, wx.NewId(), 'active?', self.skin)
        self.b13.Bind(wx.EVT_BUTTON,self.ToggleSkin)

        wexp = 0#wx.EXPAND#wx.ALL|
        hrat = 0#1#
        pad = 0

        content.Add(self.b1,hrat,wexp,pad)
        content.Add(self.b2,hrat,wexp,pad)
        content.Add(self.b3,hrat,wexp,pad)
        content.Add(self.b4,hrat,wexp,pad)
        content.Add(self.b5,hrat,wexp,pad)
        content.Add(self.b6,hrat,wexp,pad)
        content.Add(self.b7,hrat,wexp,pad)
        content.Add(self.b8,hrat,wexp,pad)
        content.Add(self.b9,hrat,wexp,pad)
        content.Add(self.b10,hrat,wexp,pad)
        content.Add(self.b11,hrat,wexp,pad)
        content.Add(self.b12,hrat,wexp,pad)
        content.Add(self.b13, hrat, wexp, pad)


        self.SetSizer(content)

    def onButton(self,event):
        print event.GetEventObject().Label
#        print "..."
#        if type(event.EventObject)==wx.Button:
#            print event.EventObject.Label
#        else:
#            print event.EventObject.label
#        switch= not self.b1.IsEnabled()
#        self.b1.Enable(switch)
#        self.b2.Enable(switch)
#        self.b3.Enable(switch)
#        self.b4.Enable(switch)
#        self.b5.Enable(switch)
#        self.b6.Enable(switch)
#        self.b7.Enable(switch)
#        self.b8.Enable(switch)
#        self.b9.Enable(switch)
#        self.b10.Enable(switch)
#        self.b11.Enable(switch)

    def ToggleSkin(self,event = None):
        key = None if self.b1.skinkey else 'button'

        print 'toggleskin to',key
        self.b1.SetSkinKey(key,1)
        self.b3.SetSkinKey(key,1)
        self.b5.SetSkinKey(key,1)
        self.b7.SetSkinKey(key,1)
        self.b9.SetSkinKey(key,1)

    def ToggleAlignment(self,event = None):
        print "ToggleAlignment DISABLED!!! It can not be!!!"
#        align = wx.VERTICAL if self.b1.Alignment == wx.HORIZONTAL else wx.HORIZONTAL
#        self.b1.Alignment = align
#        self.b3.Alignment = align
#        self.b5.Alignment = align
#        self.b7.Alignment = align
#        self.b9.Alignment = align
#        self.Layout()


    def OnMouse(self,event):
        print "window caught mouse"
Пример #20
0
    def __init__(self, parent):
        wx.Frame.__init__(self,
                          parent,
                          -1,
                          "Shaped Window",
                          style=wx.FRAME_SHAPED | wx.SIMPLE_BORDER
                          | wx.FRAME_NO_TASKBAR | wx.STAY_ON_TOP)

        self.hasShape = False
        self.delta = (0, 0)

        [
            self.Bind(e, m) for e, m in [
                (wx.EVT_LEFT_DCLICK, self.OnDoubleClick),
                (wx.EVT_LEFT_DOWN, self.OnLeftDown),
                (wx.EVT_LEFT_UP, self.OnLeftUp),
                (wx.EVT_MOTION, self.OnMouseMove),
                (wx.EVT_RIGHT_UP, self.OnExit),
                (wx.EVT_PAINT, self.OnPaint),
            ]
        ]

        from skins import images as imgmngr
        from skins import skins

        f = file("../../res/skins/halloween/skin.yaml")
        images = util.to_storage(yaml.load(f)).Images
        f.close()

        skins.res_path = "../../res/skins/halloween"

        mimg = MultiImage(images)

        from gui.uberwidgets.UberBar import UberBar as UberBar
        from gui.uberwidgets.UberButton import UberButton as UberButton

        self.content = wx.Panel(self)

        innerSizer = wx.BoxSizer(wx.HORIZONTAL)

        self.bsizer = wx.BoxSizer(wx.VERTICAL)
        self.menu = UberBar(self.content)
        [
            self.menu.add(UberButton(self.menu, -1, s))
            for s in 'Digsby Edit Help'.split()
        ]

        self.bsizer.Add(self.menu, 0, wx.EXPAND, 0)
        self.content.SetSizer(self.bsizer)

        self.hsizer = wx.BoxSizer(wx.HORIZONTAL)
        self.hsizer.Add(self.content, 1, wx.EXPAND | wx.ALL, 140)
        self.SetSizer(self.hsizer)

        w, h = 400, 400
        self.SetClientSize((w, h))
        dc = wx.ClientDC(self)
        destbitmap = wx.EmptyBitmap(w, h)

        temp_dc = wx.MemoryDC()
        temp_dc.SelectObject(destbitmap)
        mimg.draw(temp_dc, wx.Rect(0, 0, w, h))
        temp_dc.SelectObject(wx.NullBitmap)
        destbitmap.SetMask(wx.Mask(destbitmap, wx.BLACK))
        self.bmp = destbitmap

        if wx.Platform != "__WXMAC__":
            # wxMac clips the tooltip to the window shape, YUCK!!!
            self.SetToolTipString(
                "Right-click to close the window\n"
                "Double-click the image to set/unset the window shape")

        if wx.Platform == "__WXGTK__":
            # wxGTK requires that the window be created before you can
            # set its shape, so delay the call to SetWindowShape until
            # this event.
            self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
        else:
            # On wxMSW and wxMac the window has already been created, so go for it.
            self.SetWindowShape()

        dc.DrawBitmap(destbitmap, 0, 0, True)
Пример #21
0
    def __init__(self,parent):
        wx.Panel.__init__(self,parent,-1)#,style = wx.CLIP_CHILDREN|wx.CLIP_SIBLINGS

        self.Bind(wx.EVT_BUTTON,self.onButton),
        self.Bind(wx.EVT_LEFT_UP,self.OnMouse),
        self.Bind(wx.EVT_LEFT_DOWN,self.OnMouse)

        self.skin = 'button'
#        print self.skin
#        self.menu=UMenu(self)
#        self.menu.Append(wx.NewId(),'item 1')
#        self.menu.Append(wx.NewId(),'item 2')
#        self.menu.Append(wx.NewId(),'item 3')

        content=wx.BoxSizer(wx.VERTICAL)

        size=None#(200,50)#
        type=None#'menu'#'toggle'#'toggle'#
        menu=None#self.menu#
        icon=wx.Bitmap('../../../../res/skins/default/statusicons/mobile.png',wx.BITMAP_TYPE_PNG)#wx.Bitmap('../../res/skins/default/tinydigsby.png',wx.BITMAP_TYPE_PNG)
        #label= "button"#"Super wide Button Name of Impending doooooooooooom!!!"#"button"#
        skin=self.skin#None#

        self.b1=UberButton(self,wx.NewId(),'&One',skin,icon=icon,style=wx.HORIZONTAL,size=size,type=type,menu=menu)
#        self.b1.SetStaticWidth(60)
        self.b2=UberButton(self,wx.NewId(),'&Two',icon=icon,style=wx.HORIZONTAL,size=size,type=type,menu=menu)
        self.b3=UberButton(self,wx.NewId(),'T&hree',skin,icon=icon,style=wx.VERTICAL,size=size,type=type,menu=menu)
        self.b4=UberButton(self,wx.NewId(),'&Four',icon=icon,style=wx.VERTICAL,size=size,type=type,menu=menu)
        self.b5=UberButton(self,wx.NewId(),"",skin,icon=icon,size=size,type=type,menu=menu)
        self.b6=UberButton(self,wx.NewId(),"",icon=icon,size=size,type=type,menu=menu)
        self.b7=UberButton(self,wx.NewId(),'Fi&ve',skin,size=size,type=type,menu=menu)
        self.b8=UberButton(self,wx.NewId(),'&Six',size=size,type=type,menu=menu)
        self.b9=UberButton(self,wx.NewId(),"",skin,size=size,type=type,menu=menu)
        self.b10=UberButton(self,wx.NewId(),"",size=size,type=type,menu=menu)
        self.b11 = wx.Button(self, wx.NewId(), 'Native')
        self.b12= wx.Button(self, wx.NewId(), ' ')
        self.b12.Bind(wx.EVT_BUTTON,self.ToggleAlignment)

        self.b13 = UberButton(self, wx.NewId(), 'active?', self.skin)
        self.b13.Bind(wx.EVT_BUTTON,self.ToggleSkin)

        wexp = 0#wx.EXPAND#wx.ALL|
        hrat = 0#1#
        pad = 0

        content.Add(self.b1,hrat,wexp,pad)
        content.Add(self.b2,hrat,wexp,pad)
        content.Add(self.b3,hrat,wexp,pad)
        content.Add(self.b4,hrat,wexp,pad)
        content.Add(self.b5,hrat,wexp,pad)
        content.Add(self.b6,hrat,wexp,pad)
        content.Add(self.b7,hrat,wexp,pad)
        content.Add(self.b8,hrat,wexp,pad)
        content.Add(self.b9,hrat,wexp,pad)
        content.Add(self.b10,hrat,wexp,pad)
        content.Add(self.b11,hrat,wexp,pad)
        content.Add(self.b12,hrat,wexp,pad)
        content.Add(self.b13, hrat, wexp, pad)


        self.SetSizer(content)
Пример #22
0
class StatusCombo(UberCombo):

    # number of milliseconds to wait after clicking the status button before the
    # status is set (if the user hasn't entered any text)
    set_delay = 3000

    def __init__(self,
                 parent,
                 buddylist,
                 statuses,
                 get_status_method=get_profile_status,
                 set_status_method=set_profile_status):
        '''
        StatusCombo constructor.

        parent   - a wx.Window parent window
        statuses - an observable list of StatusMessage objects
        '''

        self.buddylist = buddylist
        self.buddylist.Bind(wx.EVT_KEY_DOWN, self.on_buddylist_key)
        self.searching = False
        self.searchHintShown = False

        if not getattr(StatusCombo, 'searchThresholdRegistered',
                       False) and pref('search.buddylist.show_hint', True):

            def SearchThresholdReached(*a, **k):
                if pref('search.buddylist.show_hint', True):
                    setpref('search.buddylist.show_hint', False)

            Hook('digsby.achievements.threshold',
                 'buddylist.search').register(SearchThresholdReached)
            StatusCombo.searchThresholdRegistered = True

        self.offline_item = None
        self.get_profile_status = get_status_method
        self.set_profile_status = set_status_method

        status = self.get_profile_status()

        UberCombo.__init__(self,
                           parent,
                           skinkey='combobox',
                           typeable=True,
                           valuecallback=self.on_text_lose_focus,
                           empty_text=getattr(status, 'hint',
                                              status.title.title()),
                           maxmenuheight=15)

        self.buttoncallback = self.on_status_button
        self.cbutton = UberButton(self, -1, skin=self.cbuttonskin)
        self.cbutton.Bind(wx.EVT_BUTTON, self._on_left_button)
        self.content.Insert(0, self.cbutton, 0, wx.EXPAND)

        self.cbutton.BBind(RIGHT_UP=self.on_status_button_right_click,
                           LEFT_DOWN=self.on_status_button_left_click,
                           LEFT_UP=self.on_status_button_left_up)

        self.display.Bind(
            wx.EVT_LEFT_DOWN, lambda e:
            (e.Skip(), setattr(self, 'oldValue', self.Value)))

        # the on_allow_status_changes method is called when the list of connected
        # im accounts changes size. if all accounts are offline this control
        # becomes disabled..

        #profile.account_manager.connected_accounts.add_observer(self.on_allow_status_changes)
        profile.account_manager.connected_accounts.add_observer(
            self.on_offline_allowed, obj=self)

        # Listen on status messages (changes, additions, deletes).
        _obs_link = statuses.add_list_observer(self.on_status_messages_changed,
                                               self.on_status_messages_changed)
        self.Bind(
            wx.EVT_WINDOW_DESTROY, lambda e:
            (log.info('status combo removing observers'), e.Skip(),
             _obs_link.disconnect()))

        self.on_status_messages_changed(statuses)

        # when the profile's status changes, update to reflect it
        profile.add_observer(self.on_profile_status_changed, 'status')

        # Display the current status.
        self.show_status(self.get_profile_status())

        # Timer for committing status messages after a delay.
        self.timer = wx.PyTimer(self.SetFocus)
        self.Bind(wx.EVT_TEXT, self.on_typing)

        self.button_timer = wx.PyTimer(self.on_status_button_right_click)

        textbind = self.TextField.Bind
        textbind(wx.EVT_SET_FOCUS, lambda e: setattr(self, 'skipenter', False))
        textbind(wx.EVT_KEY_DOWN, self._on_key_down)
        textbind(wx.EVT_TEXT_ENTER, self._on_enter)

        self.DropDownButton.Bind(wx.EVT_LEFT_DOWN, self._dbutton_left)

        self.OnActivateSearch = Delegate()
        self.OnDeactivateSearch = Delegate()

    def UpdateSkin(self):
        key = 'statuspanel'

        if not skin.get(key, False) or skin.get(key + '.mode', '') == 'native':
            s = lambda k, d: None
        else:
            s = lambda k, default: skin.get('%s.%s' % (key, k), default)

        comboskinkey = s('comboboxskin', None)
        self.cbuttonskin = cbskinkey = s('statusbuttonskin', None)

        self.SetSkinKey(comboskinkey)
        UberCombo.UpdateSkin(self)

        if hasattr(self, 'cbutton'):
            self.cbutton.SetSkinKey(cbskinkey, True)
            self.SetButtonIcon(StatusMessage.icon_for(self.status_state))

        if hasattr(self, 'menu') and self.menu:
            self.on_status_messages_changed()

    def SetButtonIcon(self, icon):
        """set the icon for the cycle button"""
        self.cbutton.SetIcon(icon)
        self._button_icon = icon
        self.Layout()

    def SetCallbacks(self,
                     selection=sentinel,
                     value=sentinel,
                     button=sentinel):
        'Sets callbacks for this combobox.'

        UberCombo.SetCallbacks(self, selection, value)
        if button is not sentinel: self.buttoncallback = button

    def on_allow_status_changes(self, *a, **k):
        if self.Show(profile.allow_status_changes):
            self.Parent.gui_layout()

    def setandshow(self, statusmsg):
        'Immediately sets the status message and shows it.'

        log.info('setandshow %r', statusmsg)
        self.oldValue = None
        self.show_status(statusmsg)
        self.set_profile_status(statusmsg)

    def show_status(self, status, force=False):
        'Displays the specified status message.'

        if not force and status is getattr(self, '_shown_status', None):
            return

        # make the text area not editable for statuses like "Invisble" and
        # "Offline", which have the "editable" attribute set to False
        self.Editable = status.editable

        self.display.empty_text = getattr(status, 'hint', '')
        self.ChangeValue(status.message)  # change text
        self.SetButtonIcon(StatusMessage.icon_for(status))  # change icon
        self.status_state = status.status  # store the state
        self._shown_status = status

    #
    # events
    #

    def on_typing(self, e):
        'Invoked when the user is typing in the textfield.'

        if self.searching:
            search.link_prefs(profile.prefs)
            e.Skip()
            self.buddylist.search(e.EventObject.Value)
        else:
            self.cancel_timer()

    def on_status_button(self, button):
        '''
        Invoked when the user clicks the state button to the left of the
        dropdown.
        '''
        # toggle the control's status state
        isavail = StatusMessage.is_available_state(self.status_state)

        # do we need to change the shown text?
        needs_change = self._shown_status in StatusMessage.SpecialStatuses or not self._shown_status.editable

        self.oldValue = None

        self.change_state(state='Away' if isavail else 'Available', )
        #change_text = needs_change)

    def change_state(self, state, change_text=False):
        if not isinstance(state, basestring):
            raise TypeError('change_state takes a string got a %s' %
                            type(state))
        self.status_state = state

        if change_text:
            self.ChangeValue(self.status_state, state.title())
        else:
            self.Default = state.title()

        edit_toggle = getattr(profile.status, 'edit_toggle', True)
        if getattr(profile.status, 'edit_toggle', True):
            # update the icon
            self.SetButtonIcon(StatusMessage.icon_for(self.status_state))

            self.cancel_timer()
            self.timer.StartOneShot(self.set_delay)

            # select all text in the textfield
            disp = self.display
            disp.TypeField()
            wx.CallAfter(disp.txtfld.SetSelection, -1, -1)
        else:
            self.setandshow(
                profile.status.copy(status=self.status_state,
                                    editable=None,
                                    edit_toggle=None))

    def on_status_button_left_click(self, e=None):
        if self.searching:
            return self.TextField.SetFocus()
        self.skipenter = True
        self.button_timer.Start(BUTTON_HOLD_TIME, True)
        if e: e.Skip(True)

    def on_status_button_left_up(self, e=None):
        if not self.searching:
            self.button_timer.Stop()
        if e: e.Skip(True)

    def on_status_button_right_click(self, e=None):
        if not self.searching:
            self.show_extended_status_menu()

    def show_extended_status_menu(self):
        from gui.status import get_state_choices

        m = SimpleMenu(self, skinkey=skin.get('%s.MenuSkin' % self.skinkey))

        for status in get_state_choices():
            statusname, statuslabel = status

            def onclick(item, state=statusname):
                self.change_state(
                    state
                )  #, change_text = self.status_state == self.GetValue())

            m.AppendItem(
                SimpleMenuItem(
                    [StatusMessage.icon_for(statusname), statuslabel],
                    method=onclick))

        if m.GetCount() > 0:
            m.Display(self.cbutton)

    def on_text_lose_focus(self, new_msg):
        if self.searching:
            return self.on_search_timer()

        # Cancel the status button timer if it's running.
        self.cancel_timer()

        if getattr(self, 'skipenter', False):
            wx.CallAfter(lambda: setattr(self, 'skipenter', False))
        else:
            # don't set status if we lost focus because the user is clicking
            # on the state button
            if wx.GetMouseState().LeftDown() and wx.FindWindowAtPoint(
                    wx.GetMousePosition()) is self.cbutton:
                return

            profile_status = self.get_profile_status()
            if new_msg == '':
                self.display.empty_text = profile_status.hint
            if new_msg != profile_status.message or self.status_state != profile_status.status:
                # entering a new text value clears all exceptions
                newmsg = StatusMessage(new_msg, self.status_state, new_msg)
                self.set_profile_status(newmsg)

    def on_profile_status_changed(self, *a):
        "Invoked when the profile's status changes."

        self.show_status(profile.status)

    @calllimit(1)
    def on_offline_allowed(self, *a):
        if not self: return
        show_offline = profile.allow_status_changes

        if not show_offline and self.offline_item:
            log.info('removing the offline item')
            self.RemoveItem(self.offline_item)
            self.offline_item = None
        elif show_offline and not self.offline_item:
            log.info('adding the offline item')
            self.offline_item = self.additem(
                [skin.get('statusicons.offline'),
                 _('Offline')], self.on_offline)

    def additem(self, *a, **k):
        i = SimpleMenuItem(*a, **k)
        self.AppendItem(i)
        return i

    @calllimit(1)
    def on_status_messages_changed(self, *a):
        '''
        Invoked when a status message changes, or the user status list changes.

        Rebuilds the status menu items.
        '''
        log.info('on_status_messages_changed, updating menu')

        self.RemoveAllItems()
        additem = self.additem

        def add_status_item(pname, name):
            additem([skin.get('statusicons.%s' % pname), name],
                    method=getattr(self, 'on_' + pname))

        # Available
        add_status_item('available', _('Available'))

        # user statuses
        self.sortedstatuses = msgs = sorted([c for c in profile.statuses],
                                            key=lambda msg: msg.away)

        # Find where to insert the special "Away" status item
        j = -1
        found = False
        for j, msg in enumerate(msgs):
            if msg.away:
                found = True
                break

        for i, msg in enumerate(msgs):
            if found and i == j:
                add_status_item('away', _('Away'))
            online_image = skin.get(
                'statusicons.away' if msg.away else 'statusicons.available')
            additem([online_image, msg.title],
                    method=lambda mi, msg=msg: self.setandshow(msg),
                    id=i)

        if not found or j == -1:
            add_status_item('away', _('Away'))

        # Custom...
        additem(_('Custom...'), method=self.on_custom)
        self.AppendSeparator()
        if global_status_enabled():
            additem([skin.get('icons.globalstatus'),
                     _('Global Status')],
                    method=self.on_global)

        log.info('updating status menu with %d extra statuses',
                 len(Hook('digsby.im.statusmessages')))
        for msg in Hook('digsby.im.statusmessages'):
            message = msg()
            if message is None:
                continue
            additem([message.icon, message.title],
                    method=lambda mi, msg=msg: self.setandshow(msg()))

        if global_status_enabled():
            additem([skin.get('statusicons.promote'),
                     _('Promote Digsby!')],
                    method=self.on_promote)

        # Invisible
        additem([skin.get('statusicons.invisible'),
                 _('Invisible')], self.on_invisible)

        # Offline
        self.offline_item = None
        self.on_offline_allowed()

    #
    # special entries in the status menu.
    #

    def on_offline(self, combo_item):
        self.setandshow(StatusMessage.Offline)

    def on_available(self, comboitem):
        self.show_status(StatusMessage.Available)
        self.display.TypeField()

    def on_away(self, comboitem):
        self.show_status(StatusMessage.Away)
        self.display.TypeField()

    def on_custom(self, combo_item):
        edit_custom_status(self)

    def on_global(self, combo_item):
        wx.CallAfter(wx.GetApp().SetStatusPrompt)

    def on_promote(self, combo_item):
        wx.CallAfter(wx.GetApp().SetStatusPrompt,
                     'ALL',
                     PROMOTE_STATUS_STRING(),
                     editable=False,
                     edit_toggle=False)

    def on_nowplaying(self, combo_item):
        self.setandshow(StatusMessage.NowPlaying)

    def on_invisible(self, combo_item):
        sta = self.get_profile_status()
        cpy = StatusMessage.Invisible.copy(message=sta.message)
        self.setandshow(cpy)

    def cancel_timer(self):
        if self.timer.IsRunning():
            self.timer.Stop()

    #
    # search functionality
    #

    def _on_left_button(self, e):
        if not self.searching:
            return self.buttoncallback(self.cbutton)

    def _on_enter(self, e):
        if self.searching:
            self.buddylist.activate_selected_item()
            self.stop_searching()
        else:
            e.Skip()

    def _on_key_down(self, e):
        if self.searching:
            if e.KeyCode == wx.WXK_ESCAPE:
                self.buddylist.SetFocus()
                self.stop_searching()
            elif e.KeyCode in txtcontrol_keys:
                e.Skip()
            else:
                self.buddylist.on_key_down(e)
        else:
            e.Skip()

    def _interpret_char_event(self, e):
        key = None
        backspace = False

        if e is not None:
            mod = e.Modifiers & ~wx.MOD_SHIFT
            if e.KeyCode == wx.WXK_BACK:
                backspace = True
            elif mod or e.KeyCode <= ord(' ') or e.KeyCode in non_alphanumeric:
                return key, backspace
            else:
                key = unichr(e.UnicodeKey)

        return key, backspace

    def ShowSearchHint(self):
        self.searchHintShown = True

        def size_like(img, i):
            img = img.ResizedSmaller(max(i.Width, i.Height)).PIL
            return img.ResizeCanvas(i.Width, i.Height).WXB

        self.cbutton.SetIcon(
            size_like(skin.get('StatusPanel.SearchIcon'), self._button_icon))
        self.DropDownButton.SetIcon(skin.get('StatusPanel.CancelSearchIcon'))
        self.display.DisplayLabel = _("Press 'Ctrl+F' to Search List")

    def HideSearchHint(self):
        self.SetButtonIcon(self._button_icon)
        self.DropDownButton.SetIcon(self.dropdownicon)
        self.searchHintShown = False
        self.display.DisplayLabel = None

    def search(self, e=None):
        if not pref('search.buddylist.enabled', True):
            if e is not None: e.Skip()
            return

        key, backspace = self._interpret_char_event(e)

        def size_like(img, i):
            img = img.ResizedSmaller(max(i.Width, i.Height)).PIL
            return img.ResizeCanvas(i.Width, i.Height).WXB

        icon = skin.get('StatusPanel.SearchIcon')
        self.ForceTextFieldBackground = True
        self.cbutton.SetIcon(size_like(icon, self._button_icon))
        self.DropDownButton.SetIcon(skin.get('StatusPanel.CancelSearchIcon'))
        self.searching = True
        if not hasattr(self, 'search_timer'):
            self.search_timer = wx.PyTimer(self.on_search_timer)
        self.search_timer.Start(500)

        self.display.TypeField()

        # emulate a keypress if one started the search
        self.TextField.ChangeValue(profile.blist.search_string)

        if key is not None:
            self.TextField.AppendText(key)
        if backspace:
            # emulate a backspace
            size = self.TextField.LastPosition
            self.TextField.Remove(size - 1, size)

        self.OnActivateSearch()

    def on_search_timer(self):
        active = wx.GetActiveWindow()
        focused = wx.Window.FindFocus()

        if active is None or not self.searching:
            self.stop_searching()

        if not hasattr(self, '_allowed_windows'):
            # active windows search will stick around for
            from gui.infobox.infobox import InfoBox
            from gui.buddylist.buddylistframe import BuddyListFrame
            from gui.searchgui import SearchEditDialog

            self._allowed_windows = frozenset(
                [InfoBox, BuddyListFrame, SearchEditDialog])
            self._empty_textfield_cancels = frozenset([BuddyListFrame])

        clz = active.__class__

        if clz not in self._allowed_windows:
            self.stop_searching()

        # if search loses focus to the buddylist and there is no text in the
        # search field, just cancel the search
        elif clz in self._empty_textfield_cancels and \
                focused is not self.TextField and \
                not self.TextField.Value:
            self.stop_searching()

    def stop_searching(self):
        if not self.searching:
            return

        log.info('stopping search')
        self.ForceTextFieldBackground = False
        self.SetButtonIcon(self._button_icon)
        self.DropDownButton.SetIcon(self.dropdownicon)
        self.search_timer.Stop()
        self.searching = False
        focused_window = wx.Window.FindFocus()
        if focused_window is self.TextField:
            self.buddylist.SetFocus()
        self.show_status(get_profile_status(), force=True)
        self.buddylist.clear_search()
        self.OnDeactivateSearch()

        hooks.notify('digsby.statistics.buddylist.search')

    def _dbutton_left(self, e):
        if self.searching:
            return self.stop_searching()
        else:
            e.Skip()

    def on_buddylist_key(self, e):
        if self.searching and e.KeyCode == wx.WXK_ESCAPE:
            self.stop_searching()
        else:
            e.Skip()
Пример #23
0
class FormattingBar(ToolBar, NewSkinModule):

    initover = False

    def __init__(self, parent, textctrl, skinkey, formatOptions):

        ToolBar.__init__(self, parent, skinkey = None, alignment = wx.ALIGN_LEFT)

        self.SetSkinKey(skinkey, FormattingBarSkinDefaults)

        self.textctrl = textctrl
        if sys.platform.startswith("win"):
            textctrl.Bind(EVT_SELECTION_CHANGED, self.OnCursorMove)
        textctrl.Bind(EVT_TEXT_FORMAT_CHANGED, self.OnCursorMove)

        self.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenu)

        self.fontdd = FontDropDown(self, skinkey = self.skinTB['buttonskin'])
        self.fontdd.SetMenuSkinKey(self.skinTB["menuskin"])
        self.fontdd.Bind(wx.EVT_COMMAND_CHOICE_SELECTED, self.OnFontSelected)

        icons = self.icons

        self.msize = SimpleMenu(self, self.skinTB['menuskin'], maxheight = 10)
        self.msize.SetItems(self.GenSizeItems(DEFAULT_SIZES)) #TODO: None default sizes
#        self.msize.Bind(wx.EVT_COMMAND_CHOICE_SELECTED, self.OnSizeSelected)

        self.bsize = UberButton(self, -1, '10', menu = self.msize, type = 'menu')
        self.bsize.SetStaticWidth(self.skinFB['sizedropdownwidth'])
        self.msize.SetWidth(self.skinFB['sizedropdownwidth'])

        self.bbold = UberButton(self, -1, icon = icons['bold'], type = 'toggle')
        self.bbold.Bind(wx.EVT_TOGGLEBUTTON, self.OnBoldButton)

        self.bitalic = UberButton(self, -1, icon = icons['italic'], type="toggle")
        self.bitalic.Bind(wx.EVT_TOGGLEBUTTON, self.OnItalicButton)

        self.bunderline = UberButton(self, -1, icon = icons['underline'],  type="toggle")
        self.bunderline.Bind(wx.EVT_TOGGLEBUTTON, self.OnUnderlineButton)

        self.bcolor = UberButton(self, -1, icon = icons['foregroundcolor'] )
        self.bcolor.Bind(wx.EVT_BUTTON, self.OnColorButton)

        self.bbgcolor = UberButton(self,-1, icon = icons['backgroundcolor'])
        self.bbgcolor.Bind(wx.EVT_BUTTON, self.OnBGColorButton)

        self.bemote = UberButton(self, -1, icon = icons['emote'])
        self.bemote.Bind(wx.EVT_BUTTON, self.OnEmoteButton)

#        import pdb
#        pdb.set_trace()
        self.AddMany([self.fontdd,
                      self.bsize,
                      self.bbold,
                      self.bitalic,
                      self.bunderline,
                      self.bcolor,
                      self.bbgcolor,
                      self.bemote])


        self.initover = True
        self.EnableFormattingButtons(formatOptions)
        self.UpdateDisplay()

    def OnContextMenu(self, event):
        from gui.uberwidgets.umenu import UMenu
        m = UMenu(self)
        m.AddItem(_('Hide Formatting Bar'), callback = lambda: wx.CallAfter(setpref, 'messaging.show_formatting_bar', False))
        m.PopupMenu()

    def OnFontSelected(self, event):
        """
            Updates the button to the new font and applies it to the selection
            or calls ApplyStlye
        """
        self.textctrl.ApplyStyle(facename = self.fontdd.GetClientData(self.fontdd.GetSelection()).GetFaceName())


    def OnSizeSelected(self, item):
        """
            Updates the Size button to the new size and applies it to the selection
            or calls ApplyStyle
        """
        self.bsize.label = str(item.id)
        self.textctrl.ApplyStyle(pointsize = item.id)

    def OnBoldButton(self, event):
        self.textctrl.ApplyStyle(bold = event.EventObject.IsActive())

    def OnItalicButton(self, event):
        self.textctrl.ApplyStyle(italic = event.EventObject.IsActive())

    def OnUnderlineButton(self, event):
        self.textctrl.ApplyStyle(underline = event.EventObject.IsActive())

    def OnColorButton(self, event):
        oldtextcolor = self.textctrl.GetFormat().GetTextColour()
        self.textctrl.ApplyStyle(textcolor = wx.GetColourFromUser(self, oldtextcolor, _('Choose a foreground color')))

    def OnBGColorButton(self, event):
        oldbgcolor = self.textctrl.GetFormat().GetTextColour()
        self.textctrl.ApplyStyle(bgcolor = wx.GetColourFromUser(self, oldbgcolor, _('Choose a background color')))

    def OnEmoteButton(self, event):
        self.DisplayEmotibox(self.bemote.ScreenRect)

    def DisplayEmotibox(self, rect):
        import hooks
        hooks.notify('digsby.statistics.emoticons.box_viewed')
        ebox = self.GetEmotibox()
        # position and display the emotibox
        ebox.Display(rect)

    def GetEmotibox(self):
        'Shares the emoticon box between all instances of this class.'

        b = None
        old_name, new_name = getattr(self, '_emotipack_name', None), pref('appearance.conversations.emoticons.pack', type = unicode, default = u'default')
        self._emotipack_name = new_name

        try:
            b = self.__class__.emotibox
            if not wx.IsDestroyed(b):
                if old_name != new_name:
                    b.Destroy()
                elif b.Parent is not self:
                    b.Reparent(self)

        except AttributeError:
            pass

        if b is None or wx.IsDestroyed(b):
            from gui.imwin.emoticons import get_emoticon_bitmaps
            b = self.__class__.emotibox = UberEmotiBox(self, get_emoticon_bitmaps(self._emotipack_name), self.textctrl, maxwidth = 12)
        else:
            b.SetTextCtrl(self.textctrl)

        return b

    def OnCursorMove(self, event):

        event.Skip()
        wx.CallAfter(self.UpdateDisplay)

    def UpdateDisplay(self):
        if wx.IsDestroyed(self.textctrl):
            return

        selection = self.textctrl.GetSelection()
        if selection[0] != selection[1]:
            return

        textattr = self.textctrl.GetFormat()
        font = textattr.GetFont()

        facename = font.GetFaceName()
        self.fontdd.SetSelection(self.fontdd.FindString(facename, False))
        self.bsize.SetLabel(str(font.GetPointSize()))

        self.bbold.Active(font.GetWeight() == wx.FONTWEIGHT_BOLD)
        self.bitalic.Active(font.GetStyle() == wx.FONTSTYLE_ITALIC)
        self.bunderline.Active(font.GetUnderlined())


    def EnableFormattingButtons(self, enabledict):

        if enabledict is None:
            return

        default = enabledict['default'] if 'default' in enabledict else True

        #TODO: fontdd should be disableable
        buttons = [#('font', self.fontdd),
                   ('size',      self.bsize),
                   ('bold',      self.bbold),
                   ('italic',    self.bitalic),
                   ('underline', self.bunderline),
                   ('color',     self.bcolor),
                   ('bgcolor',   self.bbgcolor),
                   ('emote',     self.bemote)]

        for key, button in buttons:
            button.Enable(enabledict[key] if key in enabledict else default)

    def GenSizeItems(self, sizes = DEFAULT_SIZES):
        """
            Sets the list of selectable sizes
            If not set sizes default to ['8', '10', '12', '14', '18', '24', '36']
        """
        return [SimpleMenuItem([str(size)], id=size, method = self.OnSizeSelected) for size in sizes]

    def DoUpdateSkin(self, skin):

        self.skinFB = skin

        ToolBar.DoUpdateSkin(self, SkinProxy(skin['toolbarskin'], ToolBarSkinDefaults))

        icons = self.icons = {}
        icons['bold'] = skin['icons.bold']
        icons['italic'] = skin['icons.italic']
        icons['underline'] = skin['icons.underline']
        icons['foregroundcolor'] = skin['icons.foregroundcolor']
        icons['backgroundcolor'] = skin['icons.backgroundcolor']
        icons['emote'] = skin['icons.emote']

        iconsize = skin['iconsize']
        for key in icons:
            if icons[key] is not None:
                icons[key] = icons[key].Resized(iconsize)

        if self.initover:
            self.bsize.SetStaticWidth(skin['sizedropdownwidth'])
            self.msize.SetWidth(skin['sizedropdownwidth'])

            self.bbold.SetIcon(icons['bold'])
            self.bitalic.SetIcon(icons['italic'])
            self.bunderline.SetIcon(icons['underline'])
            self.bcolor.SetIcon(icons['foregroundcolor'])
            self.bbgcolor.SetIcon(icons['backgroundcolor'])
            self.bemote.SetIcon(icons['emote'])

    def GetSkinProxy(self):
        return self.skinFB if hasattr(self, 'skinFB') else None
Пример #24
0
class Navi(wx.Panel):
    """
    Container for in bar close button and navigation arrows
    """
    def __init__(self, parent):
        """
            standard fair
        """
        wx.Panel.__init__(self, parent, style=0)

        events=[
            (wx.EVT_PAINT,self.OnPaint),
            (wx.EVT_ERASE_BACKGROUND, lambda e:None),
            (wx.EVT_BUTTON, self.OnButton)
        ]
        do(self.Bind(event, method) for (event, method) in events)

        #make sizers
        self.Sizer=wx.BoxSizer(wx.HORIZONTAL)
        self.hsizer=wx.BoxSizer(wx.HORIZONTAL)
        self.vsizer=wx.BoxSizer(wx.VERTICAL)

        #make Buttons
        self.closebutton=UberButton(self, CLOSEID, skin=self.Parent.closebuttonskin, icon=self.Parent.closeicon)
        self.prevb=UberButton(self, PREVID, skin=self.Parent.scrollbuttonskin, icon=self.Parent.lefticon)
        self.nextb=UberButton(self, NEXTID, skin=self.Parent.scrollbuttonskin, icon=self.Parent.righticon)
        self.upb=UberButton(self, UPID, skin=self.Parent.scrollbuttonskin, icon=self.Parent.upicon)
        self.downb=UberButton(self, DOWNID, skin=self.Parent.scrollbuttonskin, icon=self.Parent.downicon)

        #add butons to sizers
        self.hsizer.Add(self.prevb, 0, wx.EXPAND)
        self.hsizer.Add(self.nextb, 0, wx.EXPAND)
        self.vsizer.Add(self.upb, 1, wx.EXPAND)
        self.vsizer.Add(self.downb, 1, wx.EXPAND)
        self.Sizer.Add(self.hsizer, 0, wx.EXPAND)
        self.Sizer.Add(self.closebutton, 0, wx.CENTER|wx.ALL, 5)

        #Hide all buttons
        self.prevb.Show(False)
        self.nextb.Show(False)
        self.upb.Show(False)
        self.downb.Show(False)
        self.closebutton.Show(pref('tabs.tabbar_x', False))

        self.type=None

#    def UpdateSkin(self):
#        p = self.Parent
#
#        self.closebutton.SetSkinKey(p.closeskin)
#
#        self.closebutton.SetIcon(p.closeicon)
#
#        scrollskin = p.scrollbuttonskin
#
#        self.prevb.SetSkinKey(scrollskin)
#        self.nextb.SetSkinKey(scrollskin)
#        self.upb.SetSkinKey(scrollskin)
#        self.downb.SetSkinKey(scrollskin)
#
#        self.prevb.SetIcon(p.lefticon)
#        self.nextb.SetIcon(p.righticon)
#        self.upb.SetIcon(p.upicon)
#        self.downb.SetIcon(p.downicon)

    def Enabler(self):
        """
            Enable/Disable each button based off of acceptable scrolling
        """
        self.prevb.Enable(self.Parent.tabindex>0)
        self.nextb.Enable(self.Parent.tabendex<self.Parent.GetTabCount()-1)
        self.upb.Enable(self.Parent.rowindex>0)
        self.downb.Enable(self.Parent.rowindex<len(self.Parent.rows)-pref('tabs.rows',2))#self.Parent.visible)

    def ShowNav(self, type=None):
        """
        tells the navi which set of nav aroows to show
        type 0 - No arrows
        type 1 - left and right next to close button
        type 3 - up and down below close button
        """

        #do nothing if no change
        if self.type==type:
            #self.Layout()
            return

        #hide everything in prep for change
        self.prevb.Show(False)
        self.nextb.Show(False)
        self.upb.Show(False)
        self.downb.Show(False)
        self.Sizer.Detach(self.vsizer)

        if not type:#No arrows
            self.Sizer.Detach(self.closebutton)
            self.Sizer.Add(self.closebutton, 0, wx.CENTER|wx.ALL, 5)
            self.prevb.Show(False)
            self.nextb.Show(False)
        elif type==1:#Horizantel Arrows
            self.Sizer.Detach(self.closebutton)
            self.Sizer.Add(self.closebutton, 0, wx.CENTER|wx.ALL, 5)
            self.Sizer.SetOrientation(wx.HORIZONTAL)
            self.prevb.Show(True)
            self.nextb.Show(True)
        elif type==3:#Vertical arrows
            self.Sizer.Detach(self.closebutton)
            self.Sizer.Add(self.closebutton, 0, wx.CENTER|wx.ALL, 5)
            self.Sizer.SetOrientation(wx.VERTICAL)
            self.Sizer.Add(self.vsizer, 1, wx.EXPAND)
            self.upb.Show(True)
            self.downb.Show(True)
        elif type==4:#sidebar mode, no arrows as they are part of TabBar
            self.prevb.Show(False)
            self.nextb.Show(False)
            self.Sizer.Detach(self.closebutton)
            self.Sizer.Add(self.closebutton, 0, wx.CENTER)

        self.type=type

        #self.Layout()



    def OnButton(self, event):
        """
            Handels all events for any button clciked in the navi
        """
        if event.GetId()==CLOSEID:
            self.Parent.Parent.pagecontainer.active.tab.Close()
        elif event.GetId()==PREVID:
            if self.Parent.tabindex>0:
                self.Parent.tabindex-=1
                self.Parent.Regenerate(True)
        elif event.GetId()==NEXTID:
            endex=self.Parent.tabendex
            if endex<self.Parent.GetTabCount()-1:
                while self.Parent.tabendex==endex:
                    self.Parent.tabindex+=1
                    self.Parent.Regenerate(True)
        elif event.GetId()==UPID:
            if self.Parent.rowindex>0:
                self.Parent.rowindex-=1
                self.Parent.Regenerate(True)
        elif event.GetId()==DOWNID:
            if self.Parent.rowindex<len(self.Parent.rows)-pref('tabs.rows',2):#self.Parent.visible:
                self.Parent.rowindex+=1
                self.Parent.Regenerate(True)
        self.Enabler()

#        SmokeAndMirrorsBomb(self,[self.prevb,self.nextb,self.upb,self.downb,self.closebutton])

        self.Parent.Refresh()

        self.Parent.UpdateNotify()

    def OnPaint(self,event):
        dc=wx.PaintDC(self)
        rect=wx.RectS(self.Size)

        dc.Brush=wx.WHITE_BRUSH
        dc.Pen=wx.TRANSPARENT_PEN

        dc.DrawRectangleRect(rect)
Пример #25
0
    def construct_gui(self):
        self.Sizer = wx.BoxSizer(wx.VERTICAL)

        s = self.subject_bar = UberBar(self, skinkey=self.subjectskin)

        self.subject_input = SkinTextCtrl(
            s,
            skinkey=('EmailSubjectBar', 'SubjectField'),
            skinkey_bg='EmailSubjectBar.FieldBackgroundColor',
            validator=LengthLimit(1024),
        )
        self.subject_label = ClearText(s,
                                       _('Subject:'),
                                       alignment=wx.ALIGN_CENTER_VERTICAL
                                       | wx.ALIGN_RIGHT)
        self.subject_label.Font = self.subjectfont
        self.subject_label.FontColor = self.subjectfc

        s.Add(self.subject_label)
        s.Add(self.subject_input, 1)

        # construct email buttons panel
        email_buttons = self.email_buttons = UberBar(
            self, skinkey=self.buttonbarskin)

        ept = self.email_progress_text = ClearText(
            email_buttons, '', alignment=wx.ALIGN_CENTER_VERTICAL)
        ept.SetFont(self.buttonbarfont)
        ept.SetFontColor(self.buttonnarfc)

        # email body text input
        self.email_input_area = wx.TextCtrl(
            self,
            style=wx.TE_MULTILINE,
            validator=LengthLimit(20480),
        )

        # "open in" and "send"
        self.openin = UberButton(email_buttons,
                                 -1,
                                 _('Edit...'),
                                 onclick=self.OnEditEmail)
        self.send_button = UberButton(email_buttons,
                                      -1,
                                      _('Send'),
                                      onclick=self.OnSendClicked)

        # layout email buttons
        email_buttons.Add(ept)
        email_buttons.Add(wx.Size(1, 1), 1)  #StretchSpacer(1)
        email_buttons.Add(self.openin)
        email_buttons.Add(self.send_button)

        # Make sure Tab from the subject input goes to the body input.
        self.email_input_area.MoveAfterInTabOrder(self.subject_bar)

        s = self.Sizer
        s.AddMany([(self.subject_bar, 0, wx.EXPAND),
                   (self.email_input_area, 1, wx.EXPAND),
                   (self.email_buttons, 0, wx.EXPAND)])

        self.gui_constructed = True
Пример #26
0
class CapabilitiesBar(SimplePanel):
    '''
    A specialized UberBar used used in the infobox and the IM window
    has a subbar with to/from combos.
    '''
    def __init__(self,
                 parent,
                 buddy_callback,
                 showCapabilities=True,
                 infoboxmode=False):
        SimplePanel.__init__(self, parent)

        self.buddy_callback = buddy_callback

        self.Bind(wx.EVT_PAINT, lambda e: wx.PaintDC(self))

        self.infoboxmode = infoboxmode
        self._lastcaps = None

        self.UpdateSkin()
        self.Sizer = wx.BoxSizer(wx.VERTICAL)

        # create delegates for callbacks
        for action in ('OnSendFiles', 'OnSendFolder', 'OnViewPastChats',
                       'OnAlert', 'OnBlock', 'OnAddContact'):
            setattr(self, action, Delegate())

        # Create the uberbar for the capabilities.
        self.cbar = bar = UberBar(self,
                                  skinkey=self.capabilitiesskin,
                                  overflowmode=True)
        # FIXME: we should simply not allow the capabilities bar to be created for native mode
        if not showCapabilities or nativeIMWindow:
            self.cbar.Hide()

        if not infoboxmode:
            self.cbar.Bind(wx.EVT_CONTEXT_MENU,
                           lambda e: self.ActionsBarMenu.PopupMenu(event=e))

        # Create all the buttons for the capabilities bar.

        iconsize = skin.get('ActionsBar.IconSize')
        icons = skin.get('ActionsBar.Icons')

        for attr, title, tooltip in buttons:
            icon = getattr(icons, attr).Resized(iconsize)
            if attr == 'files':
                # "files" has a dropdown menu
                button = UberButton(bar,
                                    -1,
                                    title,
                                    icon=icon,
                                    type='menu',
                                    menu=self.FileMenu)

                # Change the label and action of the files button when it's overflowed into
                # the menu on the right.
                button.overflow_label = _('Send File')
                button.overflow_callback = self.OnSendFiles
            else:
                # hack until I fix this :[ -kevin
                if attr == 'video' and infoboxmode: continue

                button = UberButton(bar, -1, title, icon=icon)
                button.overflow_label = title

            button.SetToolTipString(tooltip)

            setattr(self, 'b' + attr, button)
            bar.Add(button, calcSize=False)

        bar.OnUBSize()

        #TODO Add button logics

        #        if not self.infoboxmode:
        #            self.badd = UberButton(bar,-1,'',icon = getattr(icons, 'add').Resized(iconsize))
        #            bar.AddStatic(self.badd)
        #            self.badd.Bind(wx.EVT_BUTTON,lambda e: self.OnAddContact())

        # Create multichat icon for the roomlist
        if pref('messaging.groupchat.enabled', False) and not self.infoboxmode:
            self.bmultichat = UberButton(
                bar,
                -1,
                icon=skin.get('actionsbar.icons.roomlist').Resized(16),
                type='toggle')
            self.bmultichat.SetToolTipString(_('Group Chat'))
            bar.AddStatic(self.bmultichat)

        self.ihistory = SimpleMenuItem(_('View Past Chats'),
                                       method=self.OnViewPastChats)

        def show_prefs_notifications(a):
            import gui.pref.prefsdialog as prefsdialog
            prefsdialog.show('notifications')

        self.ialert = SimpleMenuItem(_("Alert Me When..."),
                                     method=show_prefs_notifications)
        self.iblock = SimpleMenuItem(_("Block"), method=self.OnBlock)

        if not self.infoboxmode:
            self.iadd = SimpleMenuItem(_("Add Contact"),
                                       method=self.OnAddContact)
            bar.AddMenuItem(self.iadd)
        bar.AddMenuItem(self.ihistory)
        bar.AddMenuItem(self.ialert)

        if not self.infoboxmode:
            bar.AddMenuItem(SimpleMenuItem(id=-1))
            bar.AddMenuItem(self.iblock)

        self.Sizer.Add(bar, 0, wx.EXPAND)

        # create the To/From bar
        self.tfbar = tfbar = UberBar(self, skinkey=self.tofromskin)
        self.tfbar.Hide()

        tofrom_font = skin.get('tofrombar.font', default_font)
        tofrom_color = skin.get('tofrombar.fontcolor', wx.BLACK)

        talign = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT

        self.to_label = ClearText(tfbar, _('To:'), alignment=talign)
        self.to_label.Font = tofrom_font
        self.to_label.FontColor = tofrom_color
        self.from_label = ClearText(tfbar, _('From:'), alignment=talign)
        self.from_label.Font = tofrom_font
        self.from_label.FontColor = tofrom_color

        self.cto = UberCombo(tfbar,
                             skinkey=self.tofromcomboskin,
                             typeable=False,
                             size=(100, 20),
                             minmenuwidth=200)
        self.cfrom = UberCombo(tfbar,
                               skinkey=self.tofromcomboskin,
                               typeable=False,
                               size=(100, 20),
                               minmenuwidth=200)

        tfbar.Add(self.to_label, calcSize=False)
        tfbar.Add(self.cto, True, calcSize=False)
        tfbar.Add(self.from_label, calcSize=False)
        tfbar.Add(self.cfrom, True)

        self.Sizer.Add(tfbar, 0, wx.EXPAND)

        profile.prefs.link(action_icons_key, self.UpdateIcons)

        self.cbar.overflowmenu.BeforeDisplay += self.ApplyCaps

    ToCombo = property(lambda self: self.cto)
    FromCombo = property(lambda self: self.cfrom)

    def UpdateSkin(self):
        'Tells the subbars what skins they should load.'

        sget = skin.get
        self.capabilitiesskin = sget('actionsbar.toolbarskin', None)
        self.tofromskin = sget('tofrombar.toolbarskin', None)

        self.menuskin = sget('%s.menuskin' % self.capabilitiesskin, None)

        self.tofromcomboskin = sget("tofrombar.comboboxskin", None)

        self.iconsize = sget('ActionsBar.IconSize')
        self.icons = sget('ActionsBar.Icons')

        if hasattr(self, 'to_label'):
            tofrom_font = sget('tofrombar.font', lambda: default_font())
            tofrom_color = sget('tofrombar.fontcolor', lambda: wx.BLACK)

            self.to_label.Font = self.from_label.Font = tofrom_font
            self.to_label.FontColor = self.from_label.FontColor = tofrom_color

        if hasattr(self, 'cbar'): self.cbar.SetSkinKey(self.capabilitiesskin)
        if hasattr(self, 'tfbar'): self.tfbar.SetSkinKey(self.tofromskin)
        if hasattr(self, 'cto'): self.cto.SetSkinKey(self.tofromcomboskin)
        if hasattr(self, 'cfrom'): self.cfrom.SetSkinKey(self.tofromcomboskin)

        self.UpdateIcons()

    def UpdateIcons(self, *a):
        'Updates icon sizes for buttons.'

        icons_pref = pref(action_icons_key)
        textonly = icons_pref == 'text'

        icons = self.icons
        size = self.iconsize
        #TODO: Add Button logics
        #        allbuttons = list(buttons)
        #        allbuttons.append(('add',''))

        with self.Frozen():
            for attr, title, tooltip in buttons:
                icon = None if textonly else getattr(icons, attr).Resized(size)
                button = getattr(self, 'b' + attr, None)
                if button is not None:
                    button.SetIcon(icon)
                    button.SetAlignment(wx.VERTICAL if icons_pref ==
                                        'above' else wx.HORIZONTAL)
                    button.SetLabel('' if icons_pref == 'icons' else title)

        self.Parent.Layout()
        self.Refresh()

    def ShowToFrom(self, show=True):
        'Show or hide the to/from bar.'

        return self.tfbar.Show(show)

    @property
    def RoomListButtonShown(self):
        bmultichat = getattr(self, 'bmultichat', None)
        return bmultichat is not None and bmultichat.IsShown()

    @property
    def ToFromShown(self):
        'Returns True if the To/From bar is shown.'

        return self.tfbar.IsShown()

    def ShowCapabilities(self, show=True):
        'Show/Hide the capabilities bar.'

        return self.cbar.Show(show)
        #self.Layout()

    def CapabilitiesIsShown(self):
        'Returns True if the capabilities bar is shown.'

        return self.cbar.IsShown()

    def GetButton(self, button):
        'Returns one of the butons by name.'

        return getattr(self, 'b' + button, None)

    def ApplyCaps(self, contact=None, convo=None):
        'Those shows and hides options depending on the capabilities the Contact reports.'

        if contact is None and convo is None:
            convo = self.buddy_callback()
            from common.Conversation import Conversation
            if not isinstance(convo, Conversation):
                contact = convo
                convo = None

        c = None
        if convo is not None:
            if convo.ischat:
                c = set([caps.IM])
            elif contact is None:
                contact = convo.buddy

        if c is None:
            c = set(contact.caps)

        if contact is not None:
            c.add(('blocked', contact.blocked))

        # early exit if capabilities are the same.
        if c == self._lastcaps: return

        buttons_caps = [('binfo', contact is not None and not any(
            (contact.sms and contact.mobile, self.infoboxmode))),
                        ('bim', caps.IM in c), ('bfiles', caps.FILES in c),
                        ('bemail', caps.EMAIL in c), ('bsms', caps.SMS in c),
                        ('bvideo', caps.VIDEO in c)]

        for name, val in buttons_caps:
            ctrl = getattr(self, name, None)
            if ctrl is not None:
                ctrl.Show(ctrl, val, False)

        cbar = self.cbar
        menu = cbar.overflowmenu
        count = menu.spine.items.count
        iblock = self.iblock

        if caps.BLOCKABLE in c and not count(iblock):
            cbar.AddMenuItem(SimpleMenuItem(id=-1))
            cbar.AddMenuItem(iblock)
        elif not caps.BLOCKABLE in c and count(iblock):
            cbar.overflowmenu.RemoveItem(iblock)

        if contact is not None:
            if contact.blocked:
                content = _('Unblock {name}')
            else:
                content = _('Block {name}')

            iblock.content = [content.format(name=contact.name)]

        self.set_groupchat_visibility(contact, convo)

        i = len(menu.spine.items) - 1
        if menu.GetItem(i).id == -1:
            menu.RemoveItem(i)

        # don't show the dropdown on the right for widgets.
        self.cbar.overflowbutton.Show(not getattr(contact, 'iswidget', False))

        self._lastcaps = c

        cbar.GenWidthRestriction(True)

        self.update_add_contact_shown(convo)

        self.Parent.Layout()

    def update_add_contact_shown(self, convo):
        if not hasattr(self, 'iadd'):
            return

        ischat = convo is not None and convo.ischat
        overflow = self.cbar.overflowmenu

        if ischat:
            if overflow.GetIndex(self.iadd) != -1:
                overflow.RemoveItem(self.iadd)
        else:
            if overflow.GetIndex(self.iadd) == -1:
                overflow.InsertItem(overflow.GetIndex(self.ihistory),
                                    self.iadd)

    def set_groupchat_visibility(self, contact, convo):
        if not hasattr(self, 'bmultichat'):
            return

        proto = getattr(contact, 'protocol', getattr(convo, 'protocol', None))
        groupchat = False
        if proto is not None:
            groupchat = getattr(proto,
                                'supports_group_chat', False) and getattr(
                                    contact, 'supports_group_chat', False)
            self.bmultichat.Show(groupchat)

    @property
    def FileMenu(self):

        self._filemenu = SimpleMenu(self, self.menuskin)
        self.send_file_item = SimpleMenuItem(_('Send File'),
                                             lambda *a: self.OnSendFiles())
        #            if b and b.online:
        self._filemenu.AppendItem(self.send_file_item)
        self._filemenu.AppendItem(
            SimpleMenuItem(_('Transfer History'),
                           lambda *a: FileTransferDialog.Display()))

        return self._filemenu

#        try:
#            return self._filemenu
#        except AttributeError:
#            self._filemenu = self.build_file_menu()
#            return self._filemenu

    @property
    def ActionsBarMenu(self):
        try:
            return self._actionsbarmenu
        except AttributeError:
            self._actionsbarmenu = self.build_actionsbar_menu()
            return self._actionsbarmenu

    def build_actionsbar_menu(self):
        m = UMenu(self, onshow=self.update_actionsbar_menu)

        c = self._actionsbar_checks = {}
        for name, label in [('icons', _('Icons Only')),
                            ('text', _('Text Only')),
                            ('next', _('Icons Next to Text')),
                            ('above', _('Icons Above Text'))]:

            def cb(name=name):
                with self.Frozen():
                    setpref(action_icons_key, name)

            c[name] = m.AddCheckItem(label, callback=cb)

        m.AddSep()
        m.AddItem(
            _('Hide Actions Bar'),
            callback=lambda: setpref('messaging.show_actions_bar', False))

        return m

    def update_actionsbar_menu(self, menu):
        p = pref(action_icons_key)
        for name, item in self._actionsbar_checks.iteritems():
            item.Check(p == name)
Пример #27
0
    def __init__(self, parent, textctrl, skinkey, formatOptions):

        ToolBar.__init__(self, parent, skinkey = None, alignment = wx.ALIGN_LEFT)

        self.SetSkinKey(skinkey, FormattingBarSkinDefaults)

        self.textctrl = textctrl
        if sys.platform.startswith("win"):
            textctrl.Bind(EVT_SELECTION_CHANGED, self.OnCursorMove)
        textctrl.Bind(EVT_TEXT_FORMAT_CHANGED, self.OnCursorMove)

        self.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenu)

        self.fontdd = FontDropDown(self, skinkey = self.skinTB['buttonskin'])
        self.fontdd.SetMenuSkinKey(self.skinTB["menuskin"])
        self.fontdd.Bind(wx.EVT_COMMAND_CHOICE_SELECTED, self.OnFontSelected)

        icons = self.icons

        self.msize = SimpleMenu(self, self.skinTB['menuskin'], maxheight = 10)
        self.msize.SetItems(self.GenSizeItems(DEFAULT_SIZES)) #TODO: None default sizes
#        self.msize.Bind(wx.EVT_COMMAND_CHOICE_SELECTED, self.OnSizeSelected)

        self.bsize = UberButton(self, -1, '10', menu = self.msize, type = 'menu')
        self.bsize.SetStaticWidth(self.skinFB['sizedropdownwidth'])
        self.msize.SetWidth(self.skinFB['sizedropdownwidth'])

        self.bbold = UberButton(self, -1, icon = icons['bold'], type = 'toggle')
        self.bbold.Bind(wx.EVT_TOGGLEBUTTON, self.OnBoldButton)

        self.bitalic = UberButton(self, -1, icon = icons['italic'], type="toggle")
        self.bitalic.Bind(wx.EVT_TOGGLEBUTTON, self.OnItalicButton)

        self.bunderline = UberButton(self, -1, icon = icons['underline'],  type="toggle")
        self.bunderline.Bind(wx.EVT_TOGGLEBUTTON, self.OnUnderlineButton)

        self.bcolor = UberButton(self, -1, icon = icons['foregroundcolor'] )
        self.bcolor.Bind(wx.EVT_BUTTON, self.OnColorButton)

        self.bbgcolor = UberButton(self,-1, icon = icons['backgroundcolor'])
        self.bbgcolor.Bind(wx.EVT_BUTTON, self.OnBGColorButton)

        self.bemote = UberButton(self, -1, icon = icons['emote'])
        self.bemote.Bind(wx.EVT_BUTTON, self.OnEmoteButton)

#        import pdb
#        pdb.set_trace()
        self.AddMany([self.fontdd,
                      self.bsize,
                      self.bbold,
                      self.bitalic,
                      self.bunderline,
                      self.bcolor,
                      self.bbgcolor,
                      self.bemote])


        self.initover = True
        self.EnableFormattingButtons(formatOptions)
        self.UpdateDisplay()
Пример #28
0
    def __init__(self,
                 parent,
                 buddy_callback,
                 showCapabilities=True,
                 infoboxmode=False):
        SimplePanel.__init__(self, parent)

        self.buddy_callback = buddy_callback

        self.Bind(wx.EVT_PAINT, lambda e: wx.PaintDC(self))

        self.infoboxmode = infoboxmode
        self._lastcaps = None

        self.UpdateSkin()
        self.Sizer = wx.BoxSizer(wx.VERTICAL)

        # create delegates for callbacks
        for action in ('OnSendFiles', 'OnSendFolder', 'OnViewPastChats',
                       'OnAlert', 'OnBlock', 'OnAddContact'):
            setattr(self, action, Delegate())

        # Create the uberbar for the capabilities.
        self.cbar = bar = UberBar(self,
                                  skinkey=self.capabilitiesskin,
                                  overflowmode=True)
        # FIXME: we should simply not allow the capabilities bar to be created for native mode
        if not showCapabilities or nativeIMWindow:
            self.cbar.Hide()

        if not infoboxmode:
            self.cbar.Bind(wx.EVT_CONTEXT_MENU,
                           lambda e: self.ActionsBarMenu.PopupMenu(event=e))

        # Create all the buttons for the capabilities bar.

        iconsize = skin.get('ActionsBar.IconSize')
        icons = skin.get('ActionsBar.Icons')

        for attr, title, tooltip in buttons:
            icon = getattr(icons, attr).Resized(iconsize)
            if attr == 'files':
                # "files" has a dropdown menu
                button = UberButton(bar,
                                    -1,
                                    title,
                                    icon=icon,
                                    type='menu',
                                    menu=self.FileMenu)

                # Change the label and action of the files button when it's overflowed into
                # the menu on the right.
                button.overflow_label = _('Send File')
                button.overflow_callback = self.OnSendFiles
            else:
                # hack until I fix this :[ -kevin
                if attr == 'video' and infoboxmode: continue

                button = UberButton(bar, -1, title, icon=icon)
                button.overflow_label = title

            button.SetToolTipString(tooltip)

            setattr(self, 'b' + attr, button)
            bar.Add(button, calcSize=False)

        bar.OnUBSize()

        #TODO Add button logics

        #        if not self.infoboxmode:
        #            self.badd = UberButton(bar,-1,'',icon = getattr(icons, 'add').Resized(iconsize))
        #            bar.AddStatic(self.badd)
        #            self.badd.Bind(wx.EVT_BUTTON,lambda e: self.OnAddContact())

        # Create multichat icon for the roomlist
        if pref('messaging.groupchat.enabled', False) and not self.infoboxmode:
            self.bmultichat = UberButton(
                bar,
                -1,
                icon=skin.get('actionsbar.icons.roomlist').Resized(16),
                type='toggle')
            self.bmultichat.SetToolTipString(_('Group Chat'))
            bar.AddStatic(self.bmultichat)

        self.ihistory = SimpleMenuItem(_('View Past Chats'),
                                       method=self.OnViewPastChats)

        def show_prefs_notifications(a):
            import gui.pref.prefsdialog as prefsdialog
            prefsdialog.show('notifications')

        self.ialert = SimpleMenuItem(_("Alert Me When..."),
                                     method=show_prefs_notifications)
        self.iblock = SimpleMenuItem(_("Block"), method=self.OnBlock)

        if not self.infoboxmode:
            self.iadd = SimpleMenuItem(_("Add Contact"),
                                       method=self.OnAddContact)
            bar.AddMenuItem(self.iadd)
        bar.AddMenuItem(self.ihistory)
        bar.AddMenuItem(self.ialert)

        if not self.infoboxmode:
            bar.AddMenuItem(SimpleMenuItem(id=-1))
            bar.AddMenuItem(self.iblock)

        self.Sizer.Add(bar, 0, wx.EXPAND)

        # create the To/From bar
        self.tfbar = tfbar = UberBar(self, skinkey=self.tofromskin)
        self.tfbar.Hide()

        tofrom_font = skin.get('tofrombar.font', default_font)
        tofrom_color = skin.get('tofrombar.fontcolor', wx.BLACK)

        talign = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT

        self.to_label = ClearText(tfbar, _('To:'), alignment=talign)
        self.to_label.Font = tofrom_font
        self.to_label.FontColor = tofrom_color
        self.from_label = ClearText(tfbar, _('From:'), alignment=talign)
        self.from_label.Font = tofrom_font
        self.from_label.FontColor = tofrom_color

        self.cto = UberCombo(tfbar,
                             skinkey=self.tofromcomboskin,
                             typeable=False,
                             size=(100, 20),
                             minmenuwidth=200)
        self.cfrom = UberCombo(tfbar,
                               skinkey=self.tofromcomboskin,
                               typeable=False,
                               size=(100, 20),
                               minmenuwidth=200)

        tfbar.Add(self.to_label, calcSize=False)
        tfbar.Add(self.cto, True, calcSize=False)
        tfbar.Add(self.from_label, calcSize=False)
        tfbar.Add(self.cfrom, True)

        self.Sizer.Add(tfbar, 0, wx.EXPAND)

        profile.prefs.link(action_icons_key, self.UpdateIcons)

        self.cbar.overflowmenu.BeforeDisplay += self.ApplyCaps
Пример #29
0
class ImWinEmailPanel(SimplePanel):
    def __init__(self, parent):
        SimplePanel.__init__(self, parent)

        self.OnEditEmail = Delegate()
        self.OnSendEmail = Delegate()

        self.gui_constructed = False

        self.UpdateSkin()

        self.construct_gui()

    def SetEmailClient(self, email_account):
        '''
        Changes the "Edit In..." button to show the name of an email client.

        If None, the button becomes disabled.
        '''

        client = email_account.client_name if email_account is not None else None

        if client is not None:
            self.send_button.Enable(True)
            self.openin.Enable(True)

            if client:
                label = _('Edit in {client}...').format(client=client)
            else:
                label = _('Edit...')

            self.openin.SetLabel(label)
        else:
            self.send_button.Enable(False)
            self.openin.Enable(False)
            self.openin.SetLabel(_('Edit...'))

    def UpdateSkin(self):

        g = skin.get
        self.buttonbarskin = g('SendBar.ToolBarSkin', None)
        self.subjectskin = g('EmailSubjectBar.ToolBarSkin', None)

        self.subjectfont = g('EmailSubjectBar.Fonts.SubjectLabel',
                             lambda: default_font())
        self.subjectfc = g('EmailSubjectBar.FontColors.SubjectLabel', wx.BLACK)

        self.buttonbarfont = g('SendBar.Font', default_font)
        self.buttonnarfc = g('SendBar.FontColor', wx.BLACK)

        if self.gui_constructed:

            self.subject_bar.SetSkinKey(self.subjectskin)
            self.email_buttons.SetSkinKey(self.buttonbarskin)

            ept = self.email_progress_text
            ept.SetFont(self.buttonbarfont)
            ept.SetFontColor(self.buttonnarfc)

            sl = self.subject_label
            sl.SetFont(self.subjectfont)
            sl.SetFontColor(self.subjectfc)

    def construct_gui(self):
        self.Sizer = wx.BoxSizer(wx.VERTICAL)

        s = self.subject_bar = UberBar(self, skinkey=self.subjectskin)

        self.subject_input = SkinTextCtrl(
            s,
            skinkey=('EmailSubjectBar', 'SubjectField'),
            skinkey_bg='EmailSubjectBar.FieldBackgroundColor',
            validator=LengthLimit(1024),
        )
        self.subject_label = ClearText(s,
                                       _('Subject:'),
                                       alignment=wx.ALIGN_CENTER_VERTICAL
                                       | wx.ALIGN_RIGHT)
        self.subject_label.Font = self.subjectfont
        self.subject_label.FontColor = self.subjectfc

        s.Add(self.subject_label)
        s.Add(self.subject_input, 1)

        # construct email buttons panel
        email_buttons = self.email_buttons = UberBar(
            self, skinkey=self.buttonbarskin)

        ept = self.email_progress_text = ClearText(
            email_buttons, '', alignment=wx.ALIGN_CENTER_VERTICAL)
        ept.SetFont(self.buttonbarfont)
        ept.SetFontColor(self.buttonnarfc)

        # email body text input
        self.email_input_area = wx.TextCtrl(
            self,
            style=wx.TE_MULTILINE,
            validator=LengthLimit(20480),
        )

        # "open in" and "send"
        self.openin = UberButton(email_buttons,
                                 -1,
                                 _('Edit...'),
                                 onclick=self.OnEditEmail)
        self.send_button = UberButton(email_buttons,
                                      -1,
                                      _('Send'),
                                      onclick=self.OnSendClicked)

        # layout email buttons
        email_buttons.Add(ept)
        email_buttons.Add(wx.Size(1, 1), 1)  #StretchSpacer(1)
        email_buttons.Add(self.openin)
        email_buttons.Add(self.send_button)

        # Make sure Tab from the subject input goes to the body input.
        self.email_input_area.MoveAfterInTabOrder(self.subject_bar)

        s = self.Sizer
        s.AddMany([(self.subject_bar, 0, wx.EXPAND),
                   (self.email_input_area, 1, wx.EXPAND),
                   (self.email_buttons, 0, wx.EXPAND)])

        self.gui_constructed = True

    def OnSendClicked(self, e):
        self.OnSendEmail(e)

    def Clear(self):
        self.subject_input.Clear()
        self.email_input_area.Clear()

    def SetStatusMessage(self, msg):
        self.email_progress_text.SetLabel(msg)

    def EnableSendButton(self, enabled):
        self.send_button.Enable(enabled)
Пример #30
0
    def __init__(self,parent):
        SimplePanel.__init__(self, parent, wx.FULL_REPAINT_ON_RESIZE)

        self.BackgroundColour = wx.WHITE

        self.Sizer = wx.BoxSizer(HORIZONTAL)
        sz = wx.BoxSizer(HORIZONTAL)

        self.Sizer.Add(sz,1,EXPAND|ALL,3)

        leftcol = wx.BoxSizer(VERTICAL)

        acctcombo = self.acctcombo = UberCombo(self, value='',skinkey='AppDefaults.PrefCombo')
        acctcont = PrefPanel(self,acctcombo,_('Account'))


        leftcol.Add(acctcont,0,EXPAND|ALL,3)

        buddylist = self.buddylist = ListOBuddies(self)
        self.buddies_panel = buddycont = PrefPanel(self, buddylist, _('Buddy'))
        leftcol.Add(buddycont, 1, EXPAND | TOPLESS, 3)

        style = wx.NO_BORDER | CAL_SUNDAY_FIRST | CAL_SEQUENTIAL_MONTH_SELECTION | CAL_SHOW_HOLIDAYS
        cal = self.cal = CalendarCtrl(self, -1, wx.DateTime.Now(), wx.DefaultPosition, wx.DefaultSize, style)

        cal.SetForegroundColour(wx.Color(160, 160, 160))
        cal.SetHolidayColours(wx.BLACK, wx.WHITE)
        cal.SetHeaderColours(Color(160, 160, 160), Color(239, 239, 239))

        calcont = PrefPanel(self,cal,_('Date'))
        leftcol.Add(calcont, 0, EXPAND | TOPLESS, 3)

        sz.Add(leftcol, 0, EXPAND)

        viewpanel = wx.Panel(self)

        viewer = self.viewer = PastBrowserWebkitWindow(viewpanel)
#        viewer.SetMouseWheelZooms(True)
        finder = self.finder = FindBar(viewpanel,viewer)

        menu = UMenu(viewer)
        menu.AddItem(_('Copy'),  id = wx.ID_COPY,  callback = lambda *a: viewer.Copy())

        viewer.BindWheel(self)
        viewer.BindScrollWin(self)
        viewer.Bind(wx.EVT_CONTEXT_MENU,
                    lambda e: (menu.GetItemById(wx.ID_COPY).Enable(viewer.CanCopy()),
                               menu.PopupMenu(event = e)))

        viewer.Bind(wx.EVT_KEY_DOWN,self.OnKeyDown)
        finder.TextControl.Bind(wx.EVT_KEY_DOWN,self.OnKeyDown)

        nav  = BoxSizer(wx.HORIZONTAL)

        prev = self.prev = UberButton(viewpanel, label = '<-', skin = BUTTON_SKIN)
        next = self.next = UberButton(viewpanel, label = '->', skin = BUTTON_SKIN)

        datelabel = wx.StaticText(viewpanel, -1, style = wx.ALIGN_CENTER| wx.ST_NO_AUTORESIZE)
        datelabel.SetMinSize((140, -1))


        prev.Bind(wx.EVT_BUTTON, lambda e: self.Flip(-1))
        next.Bind(wx.EVT_BUTTON, lambda e: self.Flip( 1))

        nav.AddStretchSpacer(1)
        nav.AddMany([(prev, 0, wx.EXPAND | wx.ALIGN_CENTER),
                     (datelabel, 0, wx.EXPAND | wx.ALIGN_CENTER),
                     (next, 0, wx.EXPAND | wx.ALIGN_CENTER)])
        nav.AddStretchSpacer(1)


        viewpanel.Sizer = wx.BoxSizer(wx.VERTICAL)
        viewpanel.Sizer.AddMany([ (nav,    0, EXPAND),
                                  (viewer, 1, EXPAND),
                                  (finder, 0, EXPAND) ])

        sz.Add(PrefPanel(self, viewpanel, _('Conversation Log')), 1, EXPAND | ALL, 3)

        Bind = self.Bind
        Bind(wx.EVT_PAINT, self.OnPaint)

        def OnAcct(*a):
            '''
            Handle selection of a new account from the Account drop down
            '''
            if self.GroupChatsSelected():
                from collections import defaultdict
                self.groupchats = defaultdict(list)
                for g in GetGroupChats():
                    d = g['time']
                    key = DateTimeFromDMY(d.day, d.month-1, d.year)
                    self.groupchats[key].append(g)

                #dates = sorted((g['date'], g) for g in
                self.dates = sorted(self.groupchats.keys())
                UpdateCal()
                self.buddies_panel.SetTitle(_('Chats'))
            else:
                buddylist.SetList(GetBuddies(acctcombo.Value.id), BuddyRenderer())
                OnBuddy()
                self.buddies_panel.SetTitle(_('Buddy'))

        def OnBuddy(*a):
            '''
            Handels selection of a buddy from the buddy pannel
            '''

            if not self.GroupChatsSelected():
                self.dates = GetDates(buddylist.SelectedBuddy.dir)
                UpdateCal()
            else:
                ViewLogForFile(buddylist.SelectedItem['file'], do_aliases=False)

        def UpdateCal():
            '''
            Switches the date to the last date conversed with the selected budy
            '''
            self.next.Enable(True)
            self.prev.Enable(True)
            if self.dates:
                self.cal.Date = self.dates[-1]

            self.cal.Enable(True)
            OnCalChange()

        def OnCalChange(*a):
            '''
            Update the Calendar UI to a new date
            '''
            caldate = cal.Date

            currentyear   = caldate.GetYear()
            currentmonth  = caldate.GetMonth()
            relevantdates = frozenset(date.GetDay() for date in self.dates
                                      if date.GetYear() == currentyear and
                                      date.GetMonth() == currentmonth and date.GetDay())
            SetHoliday, SetAttr = cal.SetHoliday, cal.SetAttr

            for i in xrange(1, 32):
                if i in relevantdates:
                    SetHoliday(i)
                else:
                    SetAttr(i, CalendarDateAttr(Color(160,160,160)))


            OnDayChange()

        self.OnCalChange = OnCalChange

        def ViewLogForDay(date):
            '''
            Load the log file for the specified date for the currently selected buddy
            '''
            logpath = logpath_for_date(buddylist.SelectedBuddy, date)
            ViewLogForFile(logpath)

        def ViewLogForFile(logpath, do_aliases=True):
            '''
            Update the log viewer with the file specified
            '''
            with viewer.Frozen():
                viewer.SetPageSource(logpath.text('utf-8', 'replace'), logpath.url())
                viewer.RunScript('window.scroll(0, 0);')

                if do_aliases:
                    substitue_aliases()

                import hooks
                hooks.notify('digsby.statistics.logviewer.log_viewed')

        def substitue_aliases():
            '''
            Swap out buddy names with their allies
            '''
            import gui
            with open(gui.skin.resourcedir() / 'html' / 'jquery-1.3.2.js', 'rb') as f:
                viewer.RunScript(f.read())
            buddy = buddylist.SelectedBuddy
            aliases = IAliasProvider(profile())
            import simplejson as json
            names = set(json.loads(viewer.RunScript("var foo = []; $('.buddy').each(function(){foo.push($(this).html())}); JSON.stringify(foo);")))
            for name in names:
                alias = aliases.get_alias(name, buddy.service, buddy.protocol) or name
                viewer.RunScript(SUBHTML % (json.dumps(name), json.dumps(alias)))

        def OnDayChange(*a):
            '''
            Show the log for the day selected in the clander
            '''
            date = cal.Date
            self.date = date

            datelabel.SetLabel(date.FormatDate())

            if cal.GetAttr(date.GetDay()).IsHoliday():
                if self.GroupChatsSelected():
                    chats = sorted(self.groupchats[date], key=lambda g: g['time'], reverse=True)
                    buddylist.SetList(chats, GroupChatRenderer())
                    if chats:
                        ViewLogForFile(chats[0]['file'], do_aliases=False)
                else:
                    ViewLogForDay(date)
            else:
                year  = str(date.GetYear())
                month = date.GetMonth()
                month = wx.DateTime.GetMonthName(int(month))
                day   = str(date.GetDay())

                specific_day_string = _('{month}, {day}, {year}').format(month=month, day=day, year=year)

                if self.GroupChatsSelected():
                    msg = _("There are no chat logs for {specific_day_string}.").format(specific_day_string=specific_day_string)
                else:
                    msg = _("There are no chat logs for {specific_day_string} with {name}.").format(specific_day_string=specific_day_string, name=buddylist.SelectedBuddy.name)

                viewer.SetPageSource(msg, 'file:///C:/')

            viewer.SetFocus()


            wx.CallAfter(cal.Refresh)
        self.OnDayChange = OnDayChange

        acctcombo.SetCallbacks(value = OnAcct)
        buddylist.Bind(wx.EVT_LISTBOX, OnBuddy)

        cBind = cal.Bind
        cBind(EVT_CALENDAR_YEAR, OnCalChange)
        cBind(EVT_CALENDAR_MONTH, OnCalChange)
        cBind(EVT_CALENDAR_SEL_CHANGED, OnDayChange)

        acctcombo.SetItems(MakeAccountItems(), 0)