From e432e6fecff4554ceccb0e9dbc7a8b915fc90d2b Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Mon, 9 Jun 2014 23:04:19 -0400 Subject: [PATCH] Declared the API as it stands now stable. --- README.md | 2 +- stable.md | 1041 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1042 insertions(+), 1 deletion(-) create mode 100644 stable.md diff --git a/README.md b/README.md index 117a456..182ed18 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Woah, lots of attention! Thanks! This is a placeholder README; the previous file (olddocs/oldREADME.md) was rather long and confusing. I'll be rewriting it properly soon. Until then, here's the important things you need to know: -- **this package is very much incomplete and until I clear out the existing set of TODOs has an API which may change without warning** (the API is stable for the most part) +- **this package is very much incomplete; see `stable.md` for a list of what is guaranteed to not change at the API level — for everything newer, you have been warned!** - this package requires Go 1.3, which is presently available as a RC build (source builds from go tip will work too) - I don't think the Windows side uses any Go 1.3 features, but just to be safe I'm going to say express caution - Unix builds need 1.3 to fix some type-checker bugs in cgo diff --git a/stable.md b/stable.md new file mode 100644 index 0000000..3041dd1 --- /dev/null +++ b/stable.md @@ -0,0 +1,1041 @@ +# ui +-- + import "github.com/andlabs/ui" + +Package ui is a simple package which provides a way to write portable GUI +programs quickly and easily. It aims to run on as many systems as Go itself, but +presently has support for Windows, Mac OS X, and other Unix systems using the +Windows API, Cocoa, and GTK+ 3, respectively. It also aims to be Go-like: events +are transmitted via channels, and the library is fully safe for concurrent use. + +To use the library, place your main program code in another function and call +Go(), passing that function as a parameter. (This is necessary due to threading +restrictions on some environments, such as Cocoa.) Once in the function you pass +to Go(), you can safely use the rest of the library. When this function returns, +so does Go(), and package functions become unavailable. + +Building GUIs is as simple as creating a Window, populating it with Controls, +and then calling Open() on the Window. A Window only has one Control: you pack +multiple Controls into a Window by arranging them in layouts (Layouts are also +Controls). There are presently two Layouts, Stack and Grid, each with different +semantics on sizing and placement. See their documentation. + +Once a Window is open, you cannot make layout or event channel changes. + +Once your Window is open, you can begin to handle events. Handling events is +simple: because all events are channels exposed as exported members of the +Window and Control types, simply select on them. Event channels are initialized +by default. However, before you Open a Window, you can freely reassign event +channels, such that multiple events trigger the same channel, making event logic +more compact. You may also choose not to handle events; events are sent +asynchronously so the GUI loop is not initerrupted. + +Here is a simple, complete program that asks the user for their name and greets +them after clicking a button. + + package main + + import ( + "github.com/andlabs/ui" + ) + + func myMain() { + w := ui.NewWindow("Hello", 400, 100) + ui.AppQuit = w.Closing // treat quitting the application like closing the main window + nameField := ui.NewLineEdit("Enter Your Name Here") + button := ui.NewButton("Click Here For a Greeting") + w.Open(ui.NewVerticalStack(nameField, button)) + + for { + select { + case <-w.Closing: // user tries to close the window or quit the program + return + case <-button.Clicked: // user clicked the button + ui.MsgBox(w, "Hello, " + nameField.Text() + "!", "") + } + } + } + + func main() { + err := ui.Go(myMain) + if err != nil { + panic(err) + } + } + + +### On Dialogs + +The following functions provide dialogs. They exist both in package scope and as +methods on Window. + + MsgBox() + MsgBoxError() + +Dialogs opened by using the package-scope functions are modal to the entire +application: the user cannot interact with any other window until they are +dismissed. Whether or not resizing Windows will still be allowed is +implementation-defined; if the implementation does allow it, resizes will still +work properly. Whether or not the dialog box stays above all other Windows in +the program is also implementation-defined. + +Dialogs opened by using the Window methods are modal to the receiver Window +only. Attempts to interact with the receiver Window will be blocked, but all +other Windows in the application can still be used properly. The dialog box will +also stay above the receiver Window. Whether the receiver Window can be resized +while the dialog box is displayed is implementation-defined, but will work +properly if allowed. If the receiver Window has not yet been created, the +methods panic. If the receiver Window has not been shown yet or is currently +hidden, what the methods do is implementation-defined. + +The return type also differs between the two types of functions. Both ultimately +either yield a signal that the dialog has been dismissed or a code specifying +what the user decided to do with the dialog (if it has multiple choices). The +package-scope functions wait for the dialog box to be dismissed and merely +return the code (or nothing if no code is needed). The Window methods return +immediately with a channel that will eventually receive either the signal or the +return code. Package ui does not close these channels, nor does it send multiple +values on the same channel. + + +### Scrollbars + +The following Controls have scrolling support built in: + + Listbox * + Area + +All of the above controls have both horizontal and vertical scrollbars. These +scrollbars hide themselves when not needed. + +[FUTURE DISCUSSIONS: scrolling programmatically, MouseEvent/KeyEvent scroll +overrides] + +[FUTURE PLAN: Controls that are not marked with a * in the above list can have +their scrollbars disabled completely in code.] + +The result of resizing the window such that the scrollbars consider themselves +too small is implementation-defined. + +autogenerated by windowsconstgen; do not edit + +autogenerated by windowsconstgen; do not edit + +## Usage + +```go +var AppQuit chan struct{} +``` +AppQuit is pulsed when the user decides to quit the program if their operating +system provides a facility for quitting an entire application, rather than +merely close all windows (for instance, Mac OS X via the Dock icon). You should +assign one of your Windows's Closing to this variable so the user choosing to +quit the application is treated the same as closing that window. If you do not +respond to this signal, nothing will happen; regardless of whether or not you +respond to this signal, the application will not quit. Do not merely check this +channel alone; it is not guaranteed to be pulsed on all systems or in all +conditions. + +#### func Go + +```go +func Go(main func()) error +``` +Go sets up the UI environment and runs main in a goroutine. If initialization +fails, Go returns an error and main is not called. Otherwise, Go does not return +to its caller until main does, at which point it returns nil. After it returns, +you cannot call future ui functions/methods meaningfully. + +It is not safe to call ui.Go() in a goroutine. It must be called directly from +main(). + +This model is undesirable, but Cocoa limitations require it. + +Go does not process the command line for flags (that is, it does not call +flag.Parse()), nor does package ui add any of the underlying toolkit's supported +command-line flags. If you must, and if the toolkit also has environment +variable equivalents to these flags (for instance, GTK+), use those instead. + +#### func MsgBox + +```go +func MsgBox(primaryText string, secondaryText string) +``` +MsgBox displays an informational message box to the user with just an OK button. +primaryText should be a short string describing the message, and will be +displayed with additional emphasis on platforms that support it. Optionally, +secondaryText can be used to show additional information. If you pass an empty +string for secondaryText, neither additional information nor space for +additional information will be shown. On platforms that allow for the message +box window to have a title, os.Args[0] is used. + +See "On Dialogs" in the package overview for behavioral information. + +#### func MsgBoxError + +```go +func MsgBoxError(primaryText string, secondaryText string) +``` +MsgBoxError displays a message box to the user with just an OK button and an +icon indicating an error. Otherwise, it behaves like MsgBox. + +See "On Dialogs" in the package overview for more information. + +#### type Area + +```go +type Area struct { +} +``` + +Area represents a blank canvas upon which programs may draw anything and receive +arbitrary events from the user. An Area has an explicit size, represented in +pixels, that may be different from the size shown in its Window. For information +on scrollbars, see "Scrollbars" in the Overview. The coordinate system of an +Area always has an origin of (0,0) which maps to the top-left corner; all +image.Points and image.Rectangles sent across Area's channels conform to this. +The size of an Area must be at least 1x1 (that is, neither its width nor its +height may be zero or negative). For control layout purposes, an Area prefers to +be at the size you set it to (so if an Area is not stretchy in its layout, it +will ask to have that size). + +To handle events to the Area, an Area must be paired with an AreaHandler. See +AreaHandler for details. + +Do not use an Area if you intend to read text. Area reads keys based on their +position on a standard 101-key keyboard, and does no character processing. +Character processing methods differ across operating systems; trying ot recreate +these yourself is only going to lead to trouble. [FOR FUTURE PLANNING Use +TextArea instead, providing a TextAreaHandler.] + +#### func NewArea + +```go +func NewArea(width int, height int, handler AreaHandler) *Area +``` +NewArea creates a new Area with the given size and handler. It panics if handler +is nil or if width or height is zero or negative. + +#### func (*Area) RepaintAll + +```go +func (a *Area) RepaintAll() +``` +RepaintAll signals the entirety of the Area for redraw. If called before the +Window containing the Area is created, RepaintAll does nothing. + +#### func (*Area) SetSize + +```go +func (a *Area) SetSize(width int, height int) +``` +SetSize sets the Area's internal drawing size. It has no effect on the actual +control size. SetSize is safe for concurrent use; if the Area is being repainted +or is handling an event, SetSize will wait for that to complete before changing +the Area's size. SetSize will also signal the entirety of the Area to be redrawn +as in RepaintAll. It panics if width or height is zero or negative. + +#### type AreaHandler + +```go +type AreaHandler interface { + // Paint is called when the Area needs to be redrawn. + // The part of the Area that needs to be redrawn is stored in cliprect. + // Before Paint() is called, this region is cleared with a system-defined background color. + // You MUST handle this event, and you MUST return a valid image, otherwise deadlocks and panicking will occur. + // The image returned must have the same size as rect (but does not have to have the same origin points). + // Example: + // imgFromFile, _, err := image.Decode(file) + // if err != nil { panic(err) } + // img := image.NewRGBA(imgFromFile.Rect) + // draw.Draw(img, img.Rect, imgFromFile, image.ZP, draw.Over) + // // ... + // func (h *myAreaHandler) Paint(rect image.Rectangle) *image.RGBA { + // return img.SubImage(rect).(*image.RGBA) + // } + Paint(cliprect image.Rectangle) *image.RGBA + + // Mouse is called when the Area receives a mouse event. + // You are allowed to do nothing in this handler (to ignore mouse events). + // See MouseEvent for details. + // If repaint is true, the Area is marked as needing to be redrawn. + // After handling the mouse event, package ui will decide whether to perform platform-dependent event chain continuation based on that platform's designated action (so it is not possible to override global mouse events this way). + Mouse(e MouseEvent) (repaint bool) + + // Key is called when the Area receives a keyboard event. + // You are allowed to do nothing in this handler (to ignore keyboard events). + // See KeyEvent for details. + // If repaint is true, the Area is marked as needing to be redrawn. + // After handling the key event, package ui will decide whether to perform platform-dependent event chain continuation based on that platform's designated action (so it is not possible to override global key events, such as Alt-Tab, this way). + Key(e KeyEvent) (repaint bool) +} +``` + +AreaHandler represents the events that an Area should respond to. These methods +are all executed on the main goroutine, not necessarily the same one that you +created the AreaHandler in; you are responsible for the thread safety of any +members of the actual type that implements ths interface. (Having to use this +interface does not strike me as being particularly Go-like, but the nature of +Paint makes channel-based event handling a non-option; in practice, deadlocks +occur.) + +#### type Button + +```go +type Button struct { + // Clicked gets a message when the button is clicked. + // You cannot change it once the Window containing the Button has been created. + // If you do not respond to this signal, nothing will happen. + Clicked chan struct{} +} +``` + +A Button represents a clickable button with some text. + +#### func NewButton + +```go +func NewButton(text string) (b *Button) +``` +NewButton creates a new button with the specified text. + +#### func (*Button) SetText + +```go +func (b *Button) SetText(text string) +``` +SetText sets the button's text. + +#### func (*Button) Text + +```go +func (b *Button) Text() string +``` +Text returns the button's text. + +#### type Checkbox + +```go +type Checkbox struct { +} +``` + +A Checkbox is a clickable square with a label. The square can be either checked +or unchecked. Checkboxes start out unchecked. + +#### func NewCheckbox + +```go +func NewCheckbox(text string) (c *Checkbox) +``` +NewCheckbox creates a new checkbox with the specified text. + +#### func (*Checkbox) Checked + +```go +func (c *Checkbox) Checked() bool +``` +Checked() returns whether or not the checkbox has been checked. + +#### func (*Checkbox) SetText + +```go +func (c *Checkbox) SetText(text string) +``` +SetText sets the checkbox's text. + +#### func (*Checkbox) Text + +```go +func (c *Checkbox) Text() string +``` +Text returns the checkbox's text. + +#### type Combobox + +```go +type Combobox struct { +} +``` + +A Combobox is a drop-down list of items, of which at most one can be selected at +any given time. You may optionally make the combobox editable to allow custom +items. Initially, no item will be selected (and no text entered in an editable +Combobox's entry field). What happens to the text shown in a Combobox if its +width is too small is implementation-defined. + +#### func NewCombobox + +```go +func NewCombobox(items ...string) *Combobox +``` +NewCombobox makes a new Combobox with the given items. + +#### func NewEditableCombobox + +```go +func NewEditableCombobox(items ...string) *Combobox +``` +NewEditableCombobox makes a new editable Combobox with the given items. + +#### func (*Combobox) Append + +```go +func (c *Combobox) Append(what ...string) +``` +Append adds items to the end of the Combobox's list. Append will panic if +something goes wrong on platforms that do not abort themselves. + +#### func (*Combobox) Delete + +```go +func (c *Combobox) Delete(index int) +``` +Delete removes the given item from the Combobox. It panics if the given index is +out of bounds. + +#### func (*Combobox) InsertBefore + +```go +func (c *Combobox) InsertBefore(what string, before int) +``` +InsertBefore inserts a new item in the Combobox before the item at the given +position. It panics if the given index is out of bounds. InsertBefore will also +panic if something goes wrong on platforms that do not abort themselves. + +#### func (*Combobox) Len + +```go +func (c *Combobox) Len() int +``` +Len returns the number of items in the Combobox. + +On platforms for which this function may return an error, it panics if one is +returned. + +#### func (*Combobox) SelectedIndex + +```go +func (c *Combobox) SelectedIndex() int +``` +SelectedIndex returns the index of the current selection in the Combobox. It +returns -1 either if no selection was made or if text was manually entered in an +editable Combobox. + +#### func (*Combobox) Selection + +```go +func (c *Combobox) Selection() string +``` +Selection returns the current selection. + +#### type Control + +```go +type Control interface { + // contains filtered or unexported methods +} +``` + +A Control represents an UI control. Note that Control contains unexported +members; this has the consequence that you can't build custom controls that +interface directly with the system-specific code (fo rinstance, to import an +unsupported control), or at least not without some hackery. If you want to make +your own controls, create an Area and provide an AreaHandler that does what you +need. + +#### func Space + +```go +func Space() Control +``` +Space returns a null Control intended for padding layouts with blank space. It +appears to its owner as a Control of 0x0 size. + +For a Stack, Space can be used to insert spaces in the beginning or middle of +Stacks (Stacks by nature handle spaces at the end themselves). In order for this +to work properly, make the Space stretchy. + +For a Grid, Space can be used to have an empty cell. A stretchy Grid cell with a +Space can be used to anchor the perimeter of a Grid to the respective Window +edges without making one of the other controls stretchy instead (leaving empty +space in the Window otherwise). Otherwise, you do not need to do anything +special for the Space to work (though remember that an entire row or column of +Spaces will appear as having height or width zero, respectively, unless one is +marked as stretchy). + +The value returned from Space() may or may not be unique. + +#### type ExtKey + +```go +type ExtKey uintptr +``` + +ExtKey represents keys that are not in the typewriter section of the keyboard. + +```go +const ( + Escape ExtKey = iota + 1 + Insert // equivalent to "Help" on Apple keyboards + Delete + Home + End + PageUp + PageDown + Up + Down + Left + Right + F1 // F1..F12 are guaranteed to be consecutive + F2 + F3 + F4 + F5 + F6 + F7 + F8 + F9 + F10 + F11 + F12 + N0 // numpad keys; independent of Num Lock state + N1 // N0..N9 are guaranteed to be consecutive + N2 + N3 + N4 + N5 + N6 + N7 + N8 + N9 + NDot + NEnter + NAdd + NSubtract + NMultiply + NDivide +) +``` + +#### type Grid + +```go +type Grid struct { +} +``` + +A Grid arranges Controls in a two-dimensional grid. The height of each row and +the width of each column is the maximum preferred height and width +(respectively) of all the controls in that row or column (respectively). +Controls are aligned to the top left corner of each cell. All Controls in a Grid +maintain their preferred sizes by default; if a Control is marked as being +"filling", it will be sized to fill its cell. Even if a Control is marked as +filling, its preferred size is used to calculate cell sizes. One Control can be +marked as "stretchy": when the Window containing the Grid is resized, the cell +containing that Control resizes to take any remaining space; its row and column +are adjusted accordingly (so other filling controls in the same row and column +will fill to the new height and width, respectively). A stretchy Control +implicitly fills its cell. All cooridnates in a Grid are given in (row,column) +form with (0,0) being the top-left cell. + +#### func NewGrid + +```go +func NewGrid(nPerRow int, controls ...Control) *Grid +``` +NewGrid creates a new Grid with the given Controls. NewGrid needs to know the +number of Controls in a row (alternatively, the number of columns); it will +determine the number in a column from the number of Controls given. NewGrid +panics if not given a full grid of Controls. Example: + + grid := NewGrid(3, + control00, control01, control02, + control10, control11, control12, + control20, control21, control22) + +#### func (*Grid) SetFilling + +```go +func (g *Grid) SetFilling(row int, column int) +``` +SetFilling marks the given Control of the Grid as filling its cell instead of +staying at its preferred size. This function cannot be called after the Window +that contains the Grid has been created. It panics if the given coordinate is +invalid. + +#### func (*Grid) SetStretchy + +```go +func (g *Grid) SetStretchy(row int, column int) +``` +SetStretchy marks the given Control of the Grid as stretchy. Stretchy implies +filling. Only one control can be stretchy per Grid; calling SetStretchy multiple +times merely changes which control is stretchy. This function cannot be called +after the Window that contains the Grid has been created. It panics if the given +coordinate is invalid. + +#### type KeyEvent + +```go +type KeyEvent struct { + // Key is a byte representing a character pressed + // in the typewriter section of the keyboard. + // The value, which is independent of whether the + // Shift key is held, is a constant with one of the + // following (case-sensitive) values, drawn according + // to the key's position on the keyboard. + // ` 1 2 3 4 5 6 7 8 9 0 - = + // q w e r t y u i o p [ ] \ + // a s d f g h j k l ; ' + // z x c v b n m , . / + // The actual key entered will be the key at the respective + // position on the user's keyboard, regardless of the actual + // layout. (Some keyboards move \ to either the row above + // or the row below but in roughly the same spot; this is + // accounted for. Some keyboards have an additonal key + // to the left of 'z' or additional keys to the right of '='; these + // cannot be read.) + // In addition, Key will contain + // - ' ' (space) if the spacebar was pressed + // - '\t' if Tab was pressed, regardless of Modifiers + // - '\n' if the typewriter Enter key was pressed + // - '\b' if the typewriter Backspace key was pressed + // If this value is zero, see ExtKey. + Key byte + + // If Key is zero, ExtKey contains a predeclared identifier + // naming an extended key. See ExtKey for details. + // If both Key and ExtKey are zero, a Modifier by itself + // was pressed. Key and ExtKey will not both be nonzero. + ExtKey ExtKey + + // If both Key and ExtKey are zero, Modifier will contain exactly one of its bits set, indicating which Modifier was pressed or released. + // As with Modifiers itself, there is no way to differentiate between left and right modifier keys. + // As such, the result of pressing and/or releasing both left and right of the same Modifier is system-defined. + // Furthermore, the result of holding down a Key or ExtKey, then pressing a Modifier, and then releasing the original key is system-defined. + // Under no condition shall Key, ExtKey, AND Modifier all be zero. + Modifier Modifiers + + // Modifiers contains all the modifier keys currently being held at the time of the KeyEvent. + // If Modifier is nonzero, Modifiers will not contain Modifier itself. + Modifiers Modifiers + + // If Up is true, the key was released; if not, the key was pressed. + // There is no guarantee that all pressed keys shall have + // corresponding release events (for instance, if the user switches + // programs while holding the key down, then releases the key). + // Keys that have been held down are reported as multiple + // key press events. + Up bool +} +``` + +A KeyEvent represents a keypress in an Area. + +Key presses are based on their positions on a standard 101-key keyboard found on +most computers. The names chosen for keys here are based on their names on US +English QWERTY keyboards; see Key for details. + +If a key is pressed that is not supported by Key, ExtKey, or Modifiers, no +KeyEvent will be produced. + +#### func (KeyEvent) EffectiveKey + +```go +func (e KeyEvent) EffectiveKey() byte +``` +EffectiveKey returns e.Key if it is set. Otherwise, if e.ExtKey denotes a numpad +key, EffectiveKey returns the equivalent e.Key value ('0'..'9', '.', '\n', '+', +'-', '*', or '/'). Otherwise, EffectiveKey returns zero. + +#### type Label + +```go +type Label struct { +} +``` + +A Label is a static line of text used to mark other controls. Label text is +drawn on a single line; text that does not fit is truncated. TODO vertical +alignment + +#### func NewLabel + +```go +func NewLabel(text string) *Label +``` +NewLabel creates a new Label with the specified text. + +#### func (*Label) SetText + +```go +func (l *Label) SetText(text string) +``` +SetText sets the Label's text. + +#### func (*Label) Text + +```go +func (l *Label) Text() string +``` +Text returns the Label's text. + +#### type LineEdit + +```go +type LineEdit struct { +} +``` + +A LineEdit is a control which allows you to enter a single line of text. + +#### func NewLineEdit + +```go +func NewLineEdit(text string) *LineEdit +``` +NewLineEdit makes a new LineEdit with the specified text. + +#### func NewPasswordEdit + +```go +func NewPasswordEdit() *LineEdit +``` +NewPasswordEdit makes a new LineEdit which allows the user to enter a password. + +#### func (*LineEdit) SetText + +```go +func (l *LineEdit) SetText(text string) +``` +SetText sets the LineEdit's text. + +#### func (*LineEdit) Text + +```go +func (l *LineEdit) Text() string +``` +Text returns the LineEdit's text. + +#### type Listbox + +```go +type Listbox struct { +} +``` + +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. +For information on scrollbars, see "Scrollbars" in the Overview. Due to +implementation issues, the presence of horizontal scrollbars is currently +implementation-defined. + +#### func NewListbox + +```go +func NewListbox(items ...string) *Listbox +``` +NewListbox creates a new single-selection Listbox with the given items loaded +initially. + +#### func NewMultiSelListbox + +```go +func NewMultiSelListbox(items ...string) *Listbox +``` +NewMultiSelListbox creates a new multiple-selection Listbox with the given items +loaded initially. + +#### func (*Listbox) Append + +```go +func (l *Listbox) Append(what ...string) +``` +Append adds items to the end of the Listbox's list. Append will panic if +something goes wrong on platforms that do not abort themselves. + +#### func (*Listbox) Delete + +```go +func (l *Listbox) Delete(index int) +``` +Delete removes the given item from the Listbox. It panics if the given index is +out of bounds. + +#### func (*Listbox) InsertBefore + +```go +func (l *Listbox) InsertBefore(what string, before int) +``` +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. InsertBefore will also +panic if something goes wrong on platforms that do not abort themselves. + +#### func (*Listbox) Len + +```go +func (l *Listbox) Len() int +``` +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 (*Listbox) SelectedIndices + +```go +func (l *Listbox) SelectedIndices() []int +``` +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 (*Listbox) Selection + +```go +func (l *Listbox) Selection() []string +``` +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. + +#### type Modifiers + +```go +type Modifiers uintptr +``` + +Modifiers indicates modifier keys being held during an event. There is no way to +differentiate between left and right modifier keys. As such, what KeyEvents get +sent if the user does something unusual with both of a certain modifier key at +once is undefined. + +```go +const ( + Ctrl Modifiers = 1 << iota // the keys labelled Ctrl or Control on all platforms + Alt // the keys labelled Alt or Option or Meta on all platforms + Shift // the Shift keys + Super // the Super keys on platforms that have one, or the Windows keys on Windows, or the Command keys on Mac OS X +) +``` + +#### type MouseEvent + +```go +type MouseEvent struct { + // Pos is the position of the mouse in the Area at the time of the event. + Pos image.Point + + // If the event was generated by a mouse button being pressed, Down contains the ID of that button. + // Otherwise, Down contains 0. + // If Down contains nonzero, the Area will also receive keyboard focus. + Down uint + + // If the event was generated by a mouse button being released, Up contains the ID of that button. + // Otherwise, Up contains 0. + // If both Down and Up are 0, the event represents mouse movement (with optional held buttons for dragging; see below). + // Down and Up shall not both be nonzero. + Up uint + + // If Down is nonzero, Count indicates the number of clicks: 1 for single-click, 2 for double-click, 3 for triple-click, and so on. + // The order of events will be Down:Count=1 -> Up -> Down:Count=2 -> Up -> Down:Count=3 -> Up -> ... + Count uint + + // Modifiers is a bit mask indicating the modifier keys being held during the event. + Modifiers Modifiers + + // Held is a slice of button IDs that indicate which mouse buttons are being held during the event. + // Held will not include Down and Up. + // Held will be sorted. + // Only buttons 1, 2, and 3 are guaranteed to be detected by Held properly; whether or not any others are is implementation-defined. + // + // If Held is non-empty but Up and Down are both zero, the mouse is being dragged, with all the buttons in Held being held. + // Whether or not a drag into an Area generates MouseEvents is implementation-defined. + // Whether or not a drag over an Area when the program is inactive generates MouseEvents is also implementation-defined. + // Moving the mouse over an Area when the program is inactive and no buttons are held will, however, generate MouseEvents. + Held []uint +} +``` + +MouseEvent contains all the information for a mous event sent by Area.Mouse. +Mouse button IDs start at 1, with 1 being the left mouse button, 2 being the +middle mouse button, and 3 being the right mouse button. If additional buttons +are supported, they will be returned with 4 being the first additional button. +For example, on Unix systems where mouse buttons 4 through 7 are pseudobuttons +for the scroll wheel directions, the next button, button 8, will be returned as +4, 9 as 5, etc. The association between button numbers and physical buttons are +system-defined. For example, on Windows, buttons 4 and 5 are mapped to what are +internally referred to as "XBUTTON1" and "XBUTTON2", which often correspond to +the dedicated back/forward navigation buttons on the sides of many mice. The +examples here are NOT a guarantee as to how many buttons maximum will be +available on a given system. + +If the user clicked on the Area to switch to the Window it is contained in from +another window in the OS, the Area will receive a MouseEvent for that click. + +#### func (MouseEvent) HeldBits + +```go +func (e MouseEvent) HeldBits() (h uintptr) +``` +HeldBits returns Held as a bit mask. Bit 0 maps to button 1, bit 1 maps to +button 2, etc. + +#### type ProgressBar + +```go +type ProgressBar struct { +} +``` + +A ProgressBar is a horizontal rectangle that fills up from left to right to +indicate the progress of a long-running task. This progress is represented by an +integer within the range [0,100], representing a percentage. Alternatively, a +progressbar can show an animation indicating that progress is being made but how +much is indeterminate. Newly-created ProgressBars default to showing 0% +progress. + +#### func NewProgressBar + +```go +func NewProgressBar() *ProgressBar +``` +NewProgressBar creates a new ProgressBar. + +#### func (*ProgressBar) SetProgress + +```go +func (p *ProgressBar) SetProgress(percent int) +``` +SetProgress sets the currently indicated progress amount on the ProgressBar. If +percent is in the range [0,100], the progressBar shows that much percent +complete. If percent is -1, the ProgressBar is made indeterminate. Otherwise, +SetProgress panics. Calling SetProgress(-1) repeatedly will neither leave +indeterminate mode nor stop any animation involved in indeterminate mode +indefinitely; any other side-effect of doing so is implementation-defined. + +#### type Stack + +```go +type Stack struct { +} +``` + +A Stack stacks controls horizontally or vertically within the Stack's parent. A +horizontal Stack gives all controls the same height and their preferred widths. +A vertical Stack gives all controls the same width and their preferred heights. +Any extra space at the end of a Stack is left blank. Some controls may be marked +as "stretchy": when the Window they are in changes size, stretchy controls +resize to take up the remaining space after non-stretchy controls are laid out. +If multiple controls are marked stretchy, they are alloted equal distribution of +the remaining space. + +#### func NewHorizontalStack + +```go +func NewHorizontalStack(controls ...Control) *Stack +``` +NewHorizontalStack creates a new Stack that arranges the given Controls +horizontally. + +#### func NewVerticalStack + +```go +func NewVerticalStack(controls ...Control) *Stack +``` +NewVerticalStack creates a new Stack that arranges the given Controls +vertically. + +#### func (*Stack) SetStretchy + +```go +func (s *Stack) SetStretchy(index int) +``` +SetStretchy marks a control in a Stack as stretchy. This cannot be called once +the Window containing the Stack has been created. It panics if index is out of +range. + +#### type Window + +```go +type Window struct { + // Closing gets a message when the user clicks the window's close button. + // You cannot change it once the Window has been created. + // If you do not respond to this signal, nothing will happen; regardless of whether you handle the signal or not, the window will not be closed. + Closing chan struct{} +} +``` + +Window represents an on-screen window. + +#### func NewWindow + +```go +func NewWindow(title string, width int, height int) *Window +``` +NewWindow allocates a new Window with the given title and size. The window is +not created until a call to Create() or Open(). + +#### func (*Window) Create + +```go +func (w *Window) Create(control Control) +``` +Create creates the Window, setting its control to the given control. It does not +show the window. This can only be called once per window, and finalizes all +initialization of the control. + +#### func (*Window) Hide + +```go +func (w *Window) Hide() +``` +Hide hides the window. + +#### func (*Window) MsgBox + +```go +func (w *Window) MsgBox(primaryText string, secondaryText string) (done chan struct{}) +``` +MsgBox is the Window method version of the package-scope function MsgBox. See +that function's documentation and "On Dialogs" in the package overview for more +information. + +#### func (*Window) MsgBoxError + +```go +func (w *Window) MsgBoxError(primaryText string, secondaryText string) (done chan struct{}) +``` +MsgBoxError is the Window method version of the package-scope function +MsgBoxError. See that function's documentation and "On Dialogs" in the package +overview for more information. + +#### func (*Window) Open + +```go +func (w *Window) Open(control Control) +``` +Open creates the Window with Create and then shows the Window with Show. As with +Create, you cannot call Open more than once per window. + +#### func (*Window) SetSize + +```go +func (w *Window) SetSize(width int, height int) (err error) +``` +SetSize sets the window's size. + +#### func (*Window) SetTitle + +```go +func (w *Window) SetTitle(title string) +``` +SetTitle sets the window's title. + +#### func (*Window) Show + +```go +func (w *Window) Show() +``` +Show shows the window.