1. NEWT :: selecting an item from a listbox
- Posted by K_D_R Dec 25, 2012
- 2124 views
I have been having a rough time trying to "capture" an item selected from a newt listbox form.
Consider example6.ex: The value assigned to listboxState appears to be an arbitrarily assigned pointer. But how can that value be used to reference the element in the sequence to which it refers?
The documentation states that "Each entry in a listbox is a ordered pair of the text which should be displayed for that item and a key, which is a void * thatuniquely identifies that listbox item. Many applications pass integers in as keys, but using arbitrary pointers makes many applications significantly easier to code." But how exactly does an application pass an integer in as a key? http://gnewt.sourceforge.net/tutorial-4.html#ss4.12
Any assistance will be deeply appreciated.
Kenneth Rhodes
2. Re: NEWT :: selecting an item from a listbox
- Posted by ghaberek (admin) Dec 25, 2012
- 2143 views
I have been having a rough time trying to "capture" an item selected from a newt listbox form.
Consider example6.ex: The value assigned to listboxState appears to be an arbitrarily assigned pointer. But how can that value be used to reference the element in the sequence to which it refers?
The documentation states that "Each entry in a listbox is a ordered pair of the text which should be displayed for that item and a key, which is a void * that uniquely identifies that listbox item. Many applications pass integers in as keys, but using arbitrary pointers makes many applications significantly easier to code." But how exactly does an application pass an integer in as a key? http://gnewt.sourceforge.net/tutorial-4.html#ss4.12
Any assistance will be deeply appreciated.
The "arbitrary pointer" referred to in the documentation is simply the result of a call to allocate(). So it would seem that you could poke() any value you'd like into this pointer and pass it into newtListboxAppendEntry(), then get it back with a call to newtListboxGetCurrent(). I'm just coding from memory, but this should work just fine...
-- create a simple list of things sequence fruits = { "Apples", "Bananas", "Oranges" } -- create a new list box atom listbox = newtListbox( 2, 2, 5, NULL ) -- loop through the items for index = 1 to length( fruits ) do -- allocate some memory atom ptr = allocate( 4, 1 ) -- 1 = automatically free -- store the index of this item poke4( ptr, index ) -- add the item to the list box newtListboxAppendEntry( listbox, fruits[index], ptr ) end for --// run the form here //-- -- get the selected "item" (our pointer above) atom ptr = newtListboxGetCurrent( listbox ) -- fetch the index from the pointer integer index = peek4s( ptr ) -- display the result printf( 1, "you selected: %s\n", {fruits[index]} )
-Greg
3. Re: NEWT :: selecting an item from a listbox
- Posted by K_D_R Dec 26, 2012
- 2016 views
Thanks, Greg, for the sample code. I am still having problems - here is the code I have been working with, the comments will show variations I have tried.
include ../newt.e include std/machine.e procedure main() -- create a simple list of things sequence fruits = { "Apples", "Bananas", "Oranges" } newtComponent form, listbox, buttonSubmit newt:Init() newt:Cls() newt:CenteredWindow( 64, 24, "*Select Item" ) -- create a new list box listbox = newt:Listbox( 2, 2, 5, NULL ) -- listbox = newt:Listbox( 2, 2, 5, NEWT_FLAG_RETURNEXIT ) -- listbox = newt:Listbox( 18, 3, 10, NEWT_FLAG_SCROLL ) -- listbox = newt:Listbox( 18, 3, 10, NEWT_FLAG_SCROLL ) -- newt:ListboxAppendEntry(listbox, "", 0) -- newt:ListboxAppendEntries(listbox, fruits, 0) -- loop through the items for index = 1 to length( fruits ) do -- allocate some memory atom ptr = allocate( 4, 1 ) -- 1 = automatically free -- store the index of this item poke4( ptr, index ) -- add the item to the list box newt:ListboxAppendEntry( listbox, fruits[index], ptr ) end for buttonSubmit = newt:Button( 22, 20, "Submit" ) form = newt:Form( NULL, NULL, 0 ) newt:FormAddComponents( form, { listbox, buttonSubmit }) --// run the form here //-- newt:FormRun(form) -- get the selected "item" (our pointer above) atom ptr = newt:ListboxGetCurrent( listbox ) -- fetch the index from the pointer integer index = peek4s( ptr ) -- display the result printf( 1, "you selected: %s\n", fruits[index] ) newt:FormDestroy(form) newt:Finished() end procedure main()
This is the ex.err file: /home/ken/euphoria/euprogs/eunewt/demo/fruit_listbox.ex:57 in procedure main() subscript value 32880 is out of bounds, reading from a sequence of length 3 retval (from inlined routine 'Finished' at 213) = <no value> retval (from inlined routine 'Init' at 6) = <no value> fruits = { {65'A',112'p',112'p',108'l',101'e',115's'}, {66'B',97'a',110'n',97'a',110'n',97'a',115's'}, {79'O',114'r',97'a',110'n',103'g',101'e',115's'} } form = 18612064 listbox = 18755504 buttonSubmit = 18620320 index = 3 ptr = <no value> ptr = 16715776 index = 32880 ... called from /home/ken/euphoria/euprogs/eunewt/demo/fruit_listbox.ex:62 Public & Export & Global & Local Variables /home/ken/euphoria/include/std/memconst.e: DEP_really_works = 0 use_DEP = 1 FREE_RID = 2 kernel_dll = <no value> memDLL_id = <no value> VirtualAlloc_rid = <no value> VirtualLock_rid = <no value> VirtualUnlock_rid = <no value> VirtualProtect_rid = <no value> GetLastError_rid = <no value> GetSystemInfo_rid = <no value> /home/ken/euphoria/include/std/memory.e: edges_only = <no value> check_calls = 1 VirtualFree_rid = <no value> /home/ken/euphoria/include/std/types.e: Defined_Sets = { {98'b',99'c',100'd',102'f',103'g',104'h',106'j',107'k', 108'l',109'm',110'n',112'p',113'q',114'r',115's',116't',118'v',119'w',120'x', 121'y',122'z',66'B',67'C',68'D',70'F',71'G',72'H',74'J',75'K',76'L',77'M', 78'N',80'P',81'Q',82'R',83'S',84'T',86'V',87'W',88'X',89'Y',90'Z'}, {97'a',101'e',105'i',111'o',117'u',65'A',69'E',73'I', 79'O',85'U'}, { {48'0',57'9'}, {65'A',70'F'}, {97'a',102'f'} }, {32' ',9,10,13,11,160}, { {32' ',47'/'}, {58':',63'?'}, {91'[',96'`'}, {123'{',126'~'} }, { {32' ',126'~'} }, { {32' ',126'~'}, {32' ',32' '}, {9,9}, {10,10}, {13,13}, {8,8}, {7,7} }, { {97'a',122'z'} }, { {65'A',90'Z'} }, { {48'0',57'9'}, {97'a',122'z'}, {65'A',90'Z'} }, { {48'0',57'9'}, {97'a',122'z'}, {65'A',90'Z'}, {95'_',95'_'} }, { {97'a',122'z'}, {65'A',90'Z'} }, { {0,127} }, { {0,31}, {127,127} }, { {48'0',57'9'} }, { {33'!',126'~'} }, { {0,255} }, {95'_'}, {1,0} } /home/ken/euphoria/include/std/machine.e: FREE_ARRAY_RID = 1 page_size = 4096 /home/ken/euphoria/euprogs/eunewt/demo/../newt.e: libnewt = 16605808
Any suggestions will be appreciated!
Kennneth Rhodes
4. Re: NEWT :: selecting an item from a listbox
- Posted by ghaberek (admin) Dec 26, 2012
- 1963 views
Thanks, Greg, for the sample code. I am still having problems - here is the code I have been working with, the comments will show variations I have tried.
<snip>
Any suggestions will be appreciated!
Interesting. Maybe it's returning a string pointer? I'm completely unsure here. As the documentation states, the Listbox is the most complicated control in Newt. What happens if you do this instead?
-- get the selected "item" atom ptr = newt:ListboxGetCurrent( listbox ) -- peek the string from the pointer sequence item = peek_string( ptr ) -- display the result printf( 1, "you selected: %s\n", {item} )
-Greg
5. Re: NEWT :: selecting an item from a listbox
- Posted by K_D_R Dec 26, 2012
- 1932 views
Still no joy.
6. Re: NEWT :: selecting an item from a listbox
- Posted by K_D_R May 09, 2013
- 1828 views
Dirt simple, once you figure out what to do. I still have no idea how to used the pointer value which Newt would assign by default.
-- -- simple euphoria newt list box demo -- -- Demonstrates how to pass an integer "key" (sequence index) to the -- newt application which may be used to access a list box selection, -- instead of allowing the application to-- set an arbitrary pointer -- to the value selected. include ../newt.e include std/machine.e include std/console.e constant LIST = { "Apples", "Bannanas", "Oranges" } integer LIST_LENGTH = length(LIST) procedure main() -- create a simple list of things newtComponent form, ListBoxItem, buttonSubmit newt:Init() newt:Cls() -- create a new list box newt:CenteredWindow( 58, -- width 24, -- height "*Select Item" -- title ) ListBoxItem = newt:Listbox( 18, -- left 3, -- right LIST_LENGTH, -- height NEWT_FLAG_SCROLL -- flag ) -- loop through the items for index = 1 to length( LIST ) do -- add the item to the list box newt:ListboxAppendEntry( ListBoxItem, LIST[index], -- text index --<==== key, integer will now be returned ) -- instead of pointer assigned end for -- by application. buttonSubmit = newt:Button( 22, 20, "Submit" ) form = newt:Form( NULL, NULL, 0 ) newt:FormAddComponents( form, { ListBoxItem, buttonSubmit } ) --// run the form here //-- newt:FormRun(form) -- display the result printf( 1, "you selected: %s\n", {LIST[newt:ListboxGetCurrent( ListBoxItem )]} ) any_key() newt:FormDestroy(form) newt:Finished() end procedure main()
Ken
7. Re: NEWT :: selecting an item from a listbox
- Posted by gbonvehi May 09, 2013
- 1800 views
Hi Ken,
Here you've a working example using pointers as you first tried: http://openeuphoria.org/pastey/216.wc
Of course, your solution is the correct one, but to prove you could store a pointer as data I got this example working.
The problem was that you allocated memory and got a pointer to it but that memory was set to autofree. As the pointer is "forgotten" by Euphoria and passed to Newt, Euphoria deallocates it as thinks it's not used anymore. So the key was to allocate the memory and not free it until the end.
By the way, I've just realized my code has a memory leak since I only free the selected's item memory. So be sure to check that if you're going to store pointers as data in the listboxes :)
Cheers,
Guillermo
PS: Relevant documentation: http://openeuphoria.org/docs/std_machine.html#_5596_allocate_data
Automatically - If the cleanup parameter is non-zero, then the memory is returned when the variable that receives the address goes out of scope and is not referenced by anything else.
8. Re: NEWT :: selecting an item from a listbox
- Posted by K_D_R May 11, 2013
- 1796 views
Hi Ken,
Here you've a working example using pointers as you first tried: http://openeuphoria.org/pastey/216.wc
Of course, your solution is the correct one, but to prove you could store a pointer as data I got this example working.
The problem was that you allocated memory and got a pointer to it but that memory was set to autofree. As the pointer is "forgotten" by Euphoria and passed to Newt, Euphoria deallocates it as thinks it's not used anymore. So the key was to allocate the memory and not free it until the end.
By the way, I've just realized my code has a memory leak since I only free the selected's item memory. So be sure to check that if you're going to store pointers as data in the listboxes :)
Cheers,
Guillermo
PS: Relevant documentation: http://openeuphoria.org/docs/std_machine.html#_5596_allocate_data
Automatically - If the cleanup parameter is non-zero, then the memory is returned when the variable that receives the address goes out of scope and is not referenced by anything else.
Thanks for the info, Guillermo!
I have come up with this little listbox.e include file. It works very well
with my word/command auto-complete routine. Also, if you feed it the results of dir(*.*), you have a quick and dirty file selector.
-- -- listbox.e -- -- simple newt-euphoria list box demo -- -- Demonstrates how to pass an integer "key" (sequence index) to the -- newt application which may be used to access a list box selection, -- instead of allowing the application to set an arbitrary pointer -- to the value selected. -- -- Comments illustrate the alternate method of using pointers. include edx/newt.e -- include std/machine.e -- if you use "pointers" integer h = 4 sequence list = {} sequence selection= " " procedure main() newtComponent form, listbox, buttonSubmit newt:Init() newt:Cls() newt:CenteredWindow( 40, -- width 15, -- height "Press Return to Select Item" -- title ) -- create a new list box listbox = newt:Listbox( 2, -- left margin 2, -- top margin h, -- height -- NEWT_FLAG_SCROLL -- flag NEWT_FLAG_RETURNEXIT -- flag ) -- newt:ListboxAppendEntry( listbox, "", 0 ) -- loop through the items for index = 1 to length(list) do -- add the item to the list box newt:ListboxAppendEntry( listbox, list[index], -- text index --<==== key, integer will now be returned ) -- instead of pointer assigned end for -- by application. buttonSubmit = newt:Button( 5, 10, "Submit" ) form = newt:Form( NULL, NULL, 0 ) newt:FormAddComponents( form, { listbox, buttonSubmit } ) --// run the form here //-- newt:FormRun(form) -- get the selected "item" atom index = newt:ListboxGetCurrent( listbox ) newt:FormDestroy(form) newt:Finished() selection = sprintf("%s", {list[index]}) end procedure public function listbox( sequence items ) list = items main() return selection end function
9. Re: NEWT :: selecting an item from a listbox
- Posted by K_D_R May 12, 2013
- 1738 views
Here I have attempted to make a bit more generic eunewt listbox include file.
-- -- listbox.e -- Kenneth Rhodes -- wolfmanjacques@gmail.com -- simple newt-euphoria list box demo -- -- Newt for Euphoria by Greg Haberek -- https://bitbucket.org/ghaberek/eunewt/downloads/eunewt.zip -- -- http://gnewt.sourceforge.net/tutorial.html#toc1 -- -- Demonstrates how to pass an integer "key" (sequence index) to the -- newt application which may be used to access a list box selection, -- instead of allowing the application to set an arbitrary pointer -- to the value selected. -- -- Comments illustrate the alternate method of using pointers. include edx/newt.e sequence list = {} sequence selection= " " integer centered_window_width, centered_window_height, listbox_left_margin, listbox_top_margin, listbox_height, button_left_margin, button_top_margin, ll centered_window_height = 18 centered_window_width = 45 listbox_height = 10 listbox_left_margin = 2 listbox_top_margin = 2 button_left_margin = 5 button_top_margin = centered_window_height -3 procedure main() newtComponent form, listbox, buttonSubmit -- not needed, if NEWT_FLAG_RETURNEXIT flag is used newt:Init() newt:Cls() newt:CenteredWindow( centered_window_width, centered_window_height, "Arrow up/down/right/Enter to Submit" ) -- create a new list box listbox = newt:Listbox( listbox_left_margin, listbox_top_margin, listbox_height, NEWT_FLAG_SCROLL -- NEWT_FLAG_RETURNEXIT -- does not require submit button, scrolling slider -- is not shown ) -- loop through the items in the list sequence -- add the items to the list box, assigning the -- items sequence index as the "key", which would -- by default be a pointer automatically assigned by -- the application for index = 1 to length(list) do newt:ListboxAppendEntry( listbox, -- newt component list[index], -- text item index --<==== key, an integer, the sequence item index -- will now be returned, instead of a -- pointer assigned by the application ) end for -- not needed if NEWT_FLAG_RETURNEXIT flag is used buttonSubmit = newt:Button( button_left_margin, button_top_margin, "Submit" ) form = newt:Form( NULL, NULL, 0 ) newt:FormAddComponents( form, { listbox, buttonSubmit } ) -- newt:FormAddComponents( form, { listbox}) -- if NEWT_FLAG_RETURNEXIT flag is used --// run the form here //-- newt:FormRun(form) -- get the selected "item" atom index = newt:ListboxGetCurrent( listbox ) newt:FormDestroy(form) newt:Finished() selection = sprintf("%s", {list[index]}) end procedure public function listbox( sequence items ) list = items ll = length(list) for i = 1 to ll do if length(list[i])>centered_window_width then centered_window_width = length(list[i]) + 6 end if end for main() return selection end function