2014-02-14 15:25:39 -06:00
// 14 february 2014
2014-03-12 20:55:45 -05:00
2014-02-19 10:41:10 -06:00
package ui
2014-02-14 15:25:39 -06:00
import (
2014-03-07 14:01:42 -06:00
"fmt"
2014-02-14 15:25:39 -06:00
"sync"
)
2014-03-07 18:28:25 -06:00
// A Listbox is a vertical list of items, of which either at most one or any number of items can be selected at any given time.
// On creation, no item is selected.
2014-06-09 21:37:43 -05:00
// For information on scrollbars, see "Scrollbars" in the Overview.
// Due to implementation issues, the presence of horizontal scrollbars is currently implementation-defined.
2014-02-14 15:25:39 -06:00
type Listbox struct {
2014-06-10 10:38:52 -05:00
lock sync . Mutex
created bool
sysData * sysData
initItems [ ] string
2014-02-14 15:25:39 -06:00
}
2014-03-11 19:44:04 -05:00
func newListbox ( multiple bool , items ... string ) ( l * Listbox ) {
2014-02-14 15:25:39 -06:00
l = & Listbox {
2014-06-10 10:38:52 -05:00
sysData : mksysdata ( c_listbox ) ,
initItems : items ,
2014-02-14 15:25:39 -06:00
}
l . sysData . alternate = multiple
return l
}
2014-03-11 19:44:04 -05:00
// NewListbox creates a new single-selection Listbox with the given items loaded initially.
func NewListbox ( items ... string ) * Listbox {
return newListbox ( false , items ... )
}
// NewMultiSelListbox creates a new multiple-selection Listbox with the given items loaded initially.
func NewMultiSelListbox ( items ... string ) * Listbox {
return newListbox ( true , items ... )
}
2014-03-07 14:01:42 -06:00
// Append adds items to the end of the Listbox's list.
2014-03-09 15:02:17 -05:00
// Append will panic if something goes wrong on platforms that do not abort themselves.
func ( l * Listbox ) Append ( what ... string ) {
2014-03-18 10:50:56 -05:00
l . lock . Lock ( )
defer l . lock . Unlock ( )
2014-02-15 16:59:12 -06:00
if l . created {
2014-03-09 15:56:45 -05:00
for _ , s := range what {
2014-03-09 15:02:17 -05:00
l . sysData . append ( s )
2014-03-07 14:01:42 -06:00
}
2014-03-09 15:02:17 -05:00
return
2014-02-15 16:59:12 -06:00
}
2014-03-07 14:01:42 -06:00
l . initItems = append ( l . initItems , what ... )
2014-02-15 16:59:12 -06:00
}
2014-03-09 09:51:01 -05:00
// InsertBefore inserts a new item in the Listbox before the item at the given position. It panics if the given index is out of bounds.
2014-03-09 15:02:17 -05:00
// InsertBefore will also panic if something goes wrong on platforms that do not abort themselves.
func ( l * Listbox ) InsertBefore ( what string , before int ) {
2014-03-18 10:50:56 -05:00
l . lock . Lock ( )
defer l . lock . Unlock ( )
2014-03-09 09:51:01 -05:00
var m [ ] string
2014-02-15 16:59:12 -06:00
if l . created {
2014-03-09 09:51:01 -05:00
if before < 0 || before >= l . sysData . len ( ) {
goto badrange
}
2014-03-09 15:02:17 -05:00
l . sysData . insertBefore ( what , before )
return
2014-02-15 16:59:12 -06:00
}
2014-03-09 09:51:01 -05:00
if before < 0 || before >= len ( l . initItems ) {
goto badrange
}
2014-06-10 10:38:52 -05:00
m = make ( [ ] string , 0 , len ( l . initItems ) + 1 )
2014-02-15 16:59:12 -06:00
m = append ( m , l . initItems [ : before ] ... )
m = append ( m , what )
l . initItems = append ( m , l . initItems [ before : ] ... )
2014-03-09 15:02:17 -05:00
return
2014-03-09 09:51:01 -05:00
badrange :
panic ( fmt . Errorf ( "index %d out of range in Listbox.InsertBefore()" , before ) )
2014-02-15 16:59:12 -06:00
}
2014-02-14 15:25:39 -06:00
2014-03-11 12:37:19 -05:00
// Delete removes the given item from the Listbox. It panics if the given index is out of bounds.
2014-03-11 12:50:02 -05:00
func ( l * Listbox ) Delete ( index int ) {
2014-03-18 10:50:56 -05:00
l . lock . Lock ( )
defer l . lock . Unlock ( )
2014-02-15 17:14:43 -06:00
if l . created {
2014-03-11 12:37:19 -05:00
if index < 0 || index >= l . sysData . len ( ) {
goto badrange
}
2014-03-11 12:50:02 -05:00
l . sysData . delete ( index )
return
2014-02-15 17:14:43 -06:00
}
2014-03-11 12:37:19 -05:00
if index < 0 || index >= len ( l . initItems ) {
goto badrange
}
2014-06-10 10:38:52 -05:00
l . initItems = append ( l . initItems [ : index ] , l . initItems [ index + 1 : ] ... )
2014-03-11 12:50:02 -05:00
return
2014-03-11 12:37:19 -05:00
badrange :
panic ( fmt . Errorf ( "index %d out of range in Listbox.Delete()" , index ) )
2014-02-15 17:14:43 -06:00
}
2014-02-15 17:36:14 -06:00
// Selection returns a list of strings currently selected in the Listbox, or an empty list if none have been selected. This list will have at most one item on a single-selection Listbox.
func ( l * Listbox ) Selection ( ) [ ] string {
2014-03-18 10:50:56 -05:00
l . lock . Lock ( )
defer l . lock . Unlock ( )
2014-02-15 17:36:14 -06:00
if l . created {
return l . sysData . selectedTexts ( )
}
return nil
}
2014-02-14 15:25:39 -06:00
2014-02-15 17:36:14 -06:00
// SelectedIndices returns a list of the currently selected indexes in the Listbox, or an empty list if none have been selected. This list will have at most one item on a single-selection Listbox.
func ( l * Listbox ) SelectedIndices ( ) [ ] int {
2014-03-18 10:50:56 -05:00
l . lock . Lock ( )
defer l . lock . Unlock ( )
2014-02-15 17:36:14 -06:00
if l . created {
return l . sysData . selectedIndices ( )
}
return nil
}
2014-02-14 15:25:39 -06:00
2014-03-08 15:42:57 -06:00
// Len returns the number of items in the Listbox.
//
// On platforms for which this function may return an error, it panics if one is returned.
func ( l * Listbox ) Len ( ) int {
2014-03-18 10:50:56 -05:00
l . lock . Lock ( )
defer l . lock . Unlock ( )
2014-03-08 15:42:57 -06:00
if l . created {
return l . sysData . len ( )
}
return len ( l . initItems )
}
2014-02-14 15:25:39 -06:00
func ( l * Listbox ) make ( window * sysData ) ( err error ) {
l . lock . Lock ( )
defer l . lock . Unlock ( )
2014-04-01 15:43:56 -05:00
err = l . sysData . make ( window )
2014-02-14 15:25:39 -06:00
if err != nil {
return err
}
for _ , s := range l . initItems {
2014-03-09 15:56:45 -05:00
l . sysData . append ( s )
2014-02-14 15:25:39 -06:00
}
2014-02-14 19:41:36 -06:00
l . created = true
2014-02-14 15:25:39 -06:00
return nil
}
2014-03-17 20:09:03 -05:00
func ( l * Listbox ) setRect ( x int , y int , width int , height int , rr * [ ] resizerequest ) {
* rr = append ( * rr , resizerequest {
2014-06-10 10:38:52 -05:00
sysData : l . sysData ,
x : x ,
y : y ,
width : width ,
height : height ,
2014-03-17 20:09:03 -05:00
} )
2014-02-14 15:25:39 -06:00
}
2014-02-24 09:56:35 -06:00
2014-03-09 18:44:41 -05:00
func ( l * Listbox ) preferredSize ( ) ( width int , height int ) {
return l . sysData . preferredSize ( )
2014-02-24 09:56:35 -06:00
}