PDA

View Full Version : Multiple selection, regular listbox style



Phil
02-12-2013, 01:48 PM
Matt pointed me at the multilist example, but I've been unable to grok how to get a regular single column listbox that supports multi-selection in Python. Any ideas? :)

EDIT : Actually, I guess the idea is to simply feed this a 1D array and to ignore the column handling. Something like this :



#! /usr/bin/env python
# -*- Mode: Python -*-
# -*- coding: ascii -*-

"""
This is a LightWave Generic plug-in that has the sole purpose
of testing the lwsdk.Panels 'multilist_ctl' mechanics, with all of
its callbacks.
"""

__author__ = "Bob Hood"
__date__ = "Dec 1 2011"
__copyright__ = "Copyright (C) 2011 NewTek, Inc."
__version__ = "1.0"
__maintainer__ = "Bob Hood"
__email__ = "[email protected]"
__status__ = "Example"
__lwver__ = "11"

import lwsdk

# The LW Panels system does not make copies of control text elements. Therefore,
# when returning text elements to the wrapper layer from callbacks, they must have
# anchorage within Python to retain their reference counts. Returning text
# directly will cause reclamation to occcur, and garbage will be displayed on the
# interface (best case) or the application may crash (worst case).

multi_text = ["one", "two", "three"] # [ ["first", "text"], ["second", "text"], ["third", "text"] ]

class test_panels_multilist(lwsdk.IGeneric):
def __init__(self, context):
super(test_panels_multilist, self).__init__()

# Callbacks --------------------------------------
def name_2d(self, control, userdata, row, column):
return multi_text[row]

def count_2d(self, control, userdata):
return len(multi_text)

def column_width(self, control, userdata, row):
if row >= len(multi_text[0]):
return 0
return 200

def multi_select_event_func(self, control, user_data, row, selecting):
if row < 0:
return # list selections are being cleared

action = 'deselected'
if selecting:
action = action[2:]

print 'You %s: %s' % (action, ' '.join(multi_text[row]))

# LWGeneric -------------------------------------------
def process(self, generic_access):
ui = lwsdk.LWPanels()
panel = ui.create('Test Multilist')

c1 = panel.multilist_ctl('Testing', 200, 10, self.name_2d, self.count_2d, self.column_width)
c1.set_select(self.multi_select_event_func)

if panel.open(lwsdk.PANF_BLOCKING | lwsdk.PANF_RESIZE) == 0:
ui.destroy(panel)
return lwsdk.AFUNC_OK

ui.destroy(panel)

return lwsdk.AFUNC_OK

ServerTagInfo = [
( "Python Multilist Test", lwsdk.SRVTAG_USERNAME | lwsdk.LANGID_USENGLISH ),
( "Multilist Test", lwsdk.SRVTAG_BUTTONNAME | lwsdk.LANGID_USENGLISH ),
( "Utilities/Python", lwsdk.SRVTAG_MENU | lwsdk.LANGID_USENGLISH )
]

ServerRecord = { lwsdk.GenericFactory("LW_PyMultilistTest", test_panels_multilist) : ServerTagInfo }


The downside of this is that your expected listbox header is replaced by the last entry in the array. That doesn't seem quite right, does it?

artstorm
02-12-2013, 11:21 PM
The downside of this is that your expected listbox header is replaced by the last entry in the array. That doesn't seem quite right, does it?

The reason why you see your last entry in the array as the listbox header, is that multilistbox picks it header name for each column on index -1. As you don't catch index -1, python works like this that negative index, loops back in the array, so -1 is the last entry. Makes sense?
So by catching -1, you can set the column header.

Change your example code above to this:


def name_2d(self, control, userdata, row, column):
if row == -1:
return 'column name'
return multi_text[row]

Phil
02-13-2013, 06:39 AM
Ahhhh. Perfect, and it allows me the opportunity to be flexible about the source of the header text. The example python script doesn't appear to demonstrate this, hence my confusion. I'll file a bug to see if they will tweak it.

ernpchan
03-05-2015, 06:39 PM
How do you control the names of the columns? In the above example, all the columns are called 'column name'.

Sensei
03-06-2015, 06:10 AM
How do you control the names of the columns? In the above example, all the columns are called 'column name'.

if( row == -1 )
{
name = name column accordingly to column index..
if( col == 0 ) name = "1st col";
else if( col == 1 ) name = "2nd col";
// etc
}

ernpchan
03-06-2015, 08:23 AM
Thanks!