Multiple Selection List

"Michele Caramello" <[email protected]> Wed, 7 Oct 2009 10:01:26 -0700
Newsgroups gmane.comp.python.pythoncard
Message-ID <001801ca476f$cf4de110$6de9a330$@com>
Hi,
following the same approach of PythonCard's components, I
tried to add a multiselection list (as opposed to the single
selection one avaialable 'List') by simply copy-paste-modify
the code for List in list.py under components.  
Aside from the type field, which contains LB_MULTIPLE
instead of LB_SINGLE, a couple of changes in the getter and
setter and the class name not much was needed.
Problems arise though when I open the layout editor.  First
of all, the MultiSelList doesn't appear in the components
list.  Furthermore, when I click on List to instantiate a
new layout component, it actually instantiate a MultiSelList
instead of the usual List. I suppose there is something
going on with the registration of the class with the engine,
as the console spits an error out because the class key
lookup for MultiSelList in the component class dictionary
failed (in registry.py).

I also tried adding the new component in a another folder
appcomponents as that seems the way suggested.  No luck.

Do you have any hint on what it takes to add this new
class/component or alternatively extend the current 'List'
to be either ways (multi selection AND single selection
(default so that it does not clash with the tools already
developed)?

My Best Regards,
Thanks for this amazingly simple GUI framework.
Michele

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference

_______________________________________________
Pythoncard-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pythoncard-users
multisellist.py (text/plain, 4.2 KB)
"""
__version__ = "$Revision: 1.29 $"
__date__ = "$Date: 2005/12/25 13:44:50 $"
"""

import wx
from PythonCard import event, widget

class ContainerMixin:
    def _getSelection(self):
        return self.GetSelections()

    def _setSelection(self, index):
        self.SetSelection(index)

    def _getStringSelection(self):
        sellist= self.GetSelections()
        items= self.GetStrings()
        selected= []
        for i in sellist:
            selected.append(items[i])
        print '  :  '.join(selected)
        return '  :  '.join(selected)

    def _setStringSelection(self, s):
        # an arg of None or empty string will remove the selection
        if s is None or s == '':
            self.SetSelection(-1)
        else:
            self.SetStringSelection(s)

    selection = property(_getSelection, _setSelection)
    stringSelection = property(_getStringSelection, _setStringSelection)


class ListSelectEvent(event.SelectEvent):
    name = 'select'
    binding = wx.EVT_LISTBOX
    id = wx.wxEVT_COMMAND_LISTBOX_SELECTED

# can only have one CommandTypeEvent per component
class ListMouseDoubleClickEvent(event.Event):
    name = 'mouseDoubleClick'
    binding = wx.EVT_LISTBOX_DCLICK
    id = wx.wxEVT_COMMAND_LISTBOX_DOUBLECLICKED

ListEvents = (ListSelectEvent, ListMouseDoubleClickEvent)


class ListSpec(widget.WidgetSpec):
    def __init__(self):
##        events = [event.SelectEvent]
        # KEA 2004-05-03
        # how do we cleanly remove the MouseDoubleClickEvent
        # which the subclass is automatically going to add?
        events = list(ListEvents)
        attributes = { 
            'items' : { 'presence' : 'optional', 'default' : [] },
            'stringSelection' : { 'presence' : 'optional', 'default' : None } 
        }
        widget.WidgetSpec.__init__( self, 'List', 'Widget', events, attributes )
        # KEA 2004-09-04
        # this isn't particularly clean, but it does remove the extra event class
        # and since events unlike attributes don't get any further processing
        # in the spec this should be okay 
        self._events.remove(event.MouseDoubleClickEvent)


class MultiSelList(widget.Widget, wx.ListBox, ContainerMixin):
    """
    A list that allows multiple items to be selected by clickin on them
    """
    
    _spec = ListSpec()

    def __init__(self, aParent, aResource):
        print aResource
        wx.ListBox.__init__(
            self,
            aParent, 
            widget.makeNewId(aResource.id), 
            aResource.position, 
            aResource.size, 
            aResource.items,
            #style = wx.LB_SINGLE | wx.NO_FULL_REPAINT_ON_RESIZE | wx.CLIP_SIBLINGS,
            style = wx.LB_MULTIPLE | wx.NO_FULL_REPAINT_ON_RESIZE | wx.CLIP_SIBLINGS,
            name = aResource.name
        )

        widget.Widget.__init__(self, aParent, aResource)

        if aResource.stringSelection:
            self._setStringSelection(aResource.stringSelection)

        self._bindEvents(self._spec._events)

    def _getItems(self):
        items = []
        for i in range(self.GetCount()):
            items.append(self.GetString(i))
        return items

    def _setItems( self, aList ):
        self.Set(aList)

    def append(self, aString):
        self.Append(aString)

    def appendItems(self, aList):
        self.AppendItems(aList)

    def clear( self ) :
        self.Clear()

    def delete( self, aPosition ):
        self.Delete( aPosition )

    def findString( self, aString ) :
        return self.FindString( aString )

    def getString( self, aPosition ) :
        return self.GetString( aPosition )

    def insertItems( self, aList, aPosition ) :
        self.InsertItems( aList, aPosition )

    def getCount(self):
        return self.GetCount()

    # KEA was getSelected
    def isSelected(self, aPosition):
        """Determines whether an item is selected.
        aPosition is the zero-based item index
        Returns True if the given item is selected, False otherwise.
        """
        return self.IsSelected(aPosition)

    def setString( self, n, aString ) :
        self.SetString( n, aString )

    items = property(_getItems, _setItems)


import sys
from PythonCard import registry
registry.Registry.getInstance().register(sys.modules[__name__].MultiSelList)