gwu

package
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 2, 2018 License: GPL-3.0 Imports: 18 Imported by: 46

Documentation

Overview

Package gwu implements an easy to use, platform independent Web UI Toolkit in pure Go.

For documentation please visit the Gowut Wiki: https://github.com/icza/gowut/wiki

Introduction

Gowut (Go Web UI Toolkit) is a full-featured, easy to use, platform independent Web UI Toolkit written in pure Go, no platform dependent native code is linked or called.

The usage of the Gowut is similar to Google's GWT and the Java Swing toolkit. If you are familiar with those, you will get started very easily. The main difference compared to GWT is that this solution does not compile into JavaScript but remains and runs as Go code (on the server side). Remaining on the server side means you don't have to hassle with asynchronous event handlers like in GWT, you can write real synchronous event handlers (like in Java Swing).

You can use this toolkit and build user interfaces with writing Go code only: you can assemble the client interface in Go, and write event handlers in Go. You may optionally spice it and make it more customized with some HTML and CSS (also added from Go code), but that is not required.

The UI can be simply assembled hierarchically from containers and components. Components can generate events which are dispatched to event handlers - also written in pure Go. If there is no component for an HTML tag you wish to use, you can use the HTML component to wrap your custom HTML code. Components also allow you to specify custom HTML attributes that will be added for their (wrapper) HTML tags.

Creating user interfaces using Gowut does not require you to think like that the clients will view it and interact with it through a browser. The "browser" layer is hidden by Gowut. While styling the components is done through CSS (either by calling the style builder's methods or passing direct CSS codes), think of it like a way similar to formatting HTML tags with CSS.

The state of the components are stored on server side, in the memory. This means that if a browser is closed and reopened, or you navigate away and back, the same state will be rendered again. AJAX technology is used to automatically synchronize component's state from browser to server, and to dispatch events. AJAX technology is used also to refresh some parts (components) that change (during event handling) without having to reload the whole page to see the changes.

To quickly test it and see it in action, run the "Showcase of Features" application by typing:

go run $GOPATH/src/github.com/icza/gowut/_examples/showcase/showcase.go

Features of Gowut

-A component library to assemble your user interfaces with

-A GUI server which serves browser clients

-Session management

-Automatic event handling and dispatching

-(CSS) Style builder to easily manipulate the style of components

Server and Events and Sessions

The package contains a GUI server which is responsible to serve GUI clients which are standard browsers. The user interface can be viewed from any browsers (including smart phones) which makes this a cross platform solution. Starting the GUI server with a non-local address gives you the possibility to view the GUI from a remote computer. The server can be configured to run in normal mode (HTTP) or in secure mode (HTTPS).

The GUI server also has Session management. By default windows added to the server are public windows, and shared between all users (clients). This means if a user changes the content (e.g. enters a text into a text box), that text will be visible to all other users. This is suitable for most desktop applications.

Sessions can be created during event handling (by calling the Event.NewSession() method), and windows added to the session will only be visible to the client associated with the session. If other users request the same window, a new instance of the window is to be created and added to their sessions.

Event handling is possible via event handlers. An event handler is an implementation of the EventHandler interface. Event handlers have to be attached to the components which will be the source of the event. Event handlers are registered to event types or kinds (EventType) such as click event (ETypeClick), value change event (ETypeChange), key up event (ETypeKeyUp) etc.

The HandleEvent method of an event handler gets an Event value which has multiple purposes and functions. 1) The event contains the parameters of the event (such as the event type, the event source component, mouse position in case of a mouse event etc.). 2) The Event is an accessor to the Session associated with the client the event is originating from. Through the event an event handler may access the current Session, create a new Session or may remove it (invalidate it). 3) The event is also used to define actions to be executed (automatically by Gowut) after the event handling (post-event actions). For example if the event handler changes a component, the handler has to mark it dirty causing it to be re-rendered in the client browser, or an event handler can change the focused component, or reload another window.

Creating a session from an event handler during event dispatching requires a public window and an event source component (e.g. a Button). There is another handy way to create sessions. Sessions can also be created automatically by requesting pre-registered paths, paths of not-yet existing windows. When such a window is requested and no private session associated with the client exists, a new session will be created. A registered SessionHandler can be used then to create the window prior to it being served. Here's an example how to do it:

// A SessionHandler implementation:
type sessHandler struct {}
func (h sessHandler) Created(s gwu.Session) {
	win := gwu.NewWindow("login", "Login Window")
	// ...add content to the login window...
	h.AddWindow(win)
}
func (h sessHandler) Removed(s gwu.Session) {}

// And to auto-create sessions for the login window:
server := gwu.NewServer("guitest","")
server.AddSessCreatorName("login", "Login Window")
server.AddSHandler(sessHandler{})

Despite the use of sessions if you access the application remotely (e.g. not from localhost), security is only guaranteed if you configure the server to run in secure (HTTPS) mode.

Under the Hood

User interfaces are generated HTML documents which communicate with the server with AJAX calls. The GUI server is based on the web server integrated in Go.

When a Window is requested by its URL, the Window will render a complete HTML document. The Window will recursively include its child components. Components render themselves into HTML codes. When a component generates an event, the page in the browser will make an AJAX call sending the event to the server. The event will be passed to all the appropriate event handlers. Event handlers can mark components dirty, specifying that they may have changed and they must be re-rendered. When all the event handlers are done, the ids of the dirty components are sent back, and the browser will request only to render the dirty components, with AJAX calls, and the results will replace the old component nodes in the HTML DOM.

Since the clients are HTTP browsers, the GWU sessions are implemented and function as HTTP sessions. Cookies are used to maintain the browser sessions.

Styling

Styling the components is done through CSS. You can do this from Go code by calling the style builder's methods, or you can create external CSS files.

The Comp interface contains a Style() method which returns the style builder of the component. The builder can be used to set/manipulate the style class names of the component (e.g. SetClass(), AddClass(), RemoveClass() methods). The builder also has get and set methods for the common CSS attributes, and the GWU package contains many CSS constants for CSS attribute values. Many styling can be achieved using the builder's built-in methods and constants resulting in the Go code containing no direct CSS at all. You can use the general Get() and Set() methods of the style builder to manipulate any style attributes which it does not have predefined methods for.

Each Gowut component has its own CSS class derived from its name using the "gwu-" prefix, for example the Button component has the default CSS class "gwu-Button". Many components use multiple CSS classes for their internal structure. These classes are listed in the documentation of the components. Gowut has multiple built-in CSS themes. A CSS theme is basically the collection of the style definitions of the style classes used by the components. You can set the default theme with the Server.SetTheme() method. This will be used for all windows. You can set themes individually for windows too, using the Window.SetTheme() method.

You can create your own external CSS files where you can extend/override the definitions of the built-in style classes. For example you can define the "gwu-Button" style class to have red background, and the result will be that all Buttons will have red background without having to change their style individually.

Component Palette

Containers to group and lay out components:

Expander  - shows and hides a content comp when clicking on the header comp
(Link)    - allows only one optional child
Panel     - it has configurable layout
Table     - it is dynamic and flexible
TabPanel  - for tabbed displaying components (only 1 is visible at a time)
Window    - top of component hierarchy, it is an extension of the Panel

Input components to get data from users:

CheckBox
ListBox     (it's either a drop-down list or a multi-line/multi-select list box)
TextBox     (it's either a one-line text box or a multi-line text area)
PasswBox
RadioButton
SwitchButton

Other components:

Button
HTML
Image
Label
Link
SessMonitor
Timer

Full App Example

Let a full example follow here which is a complete application. It builds a simple window, adds components to it, registers event handlers which modify the content and starts the GUI server. Component modifications (including both individual components and component structure) will be seen without page reload. All written in Go.

Source of this application is available here: https://github.com/icza/gowut/blob/master/_examples/simple/simple_demo.go

type myButtonHandler struct {
	counter int
	text    string
}

func (h *myButtonHandler) HandleEvent(e gwu.Event) {
	if b, isButton := e.Src().(gwu.Button); isButton {
		b.SetText(b.Text() + h.text)
		h.counter++
		b.SetToolTip(fmt.Sprintf("You've clicked %d times!", h.counter))
		e.MarkDirty(b)
	}
}

func main() {
	// Create and build a window
	win := gwu.NewWindow("main", "Test GUI Window")
	win.Style().SetFullWidth()
	win.SetHAlign(gwu.HACenter)
	win.SetCellPadding(2)

	// Button which changes window content
	win.Add(gwu.NewLabel("I'm a label! Try clicking on the button=>"))
	btn := gwu.NewButton("Click me")
	btn.AddEHandler(&myButtonHandler{text: ":-)"}, gwu.ETypeClick)
	win.Add(btn)
	btnsPanel := gwu.NewNaturalPanel()
	btn.AddEHandlerFunc(func(e gwu.Event) {
		// Create and add a new button...
		newbtn := gwu.NewButton(fmt.Sprintf("Extra #%d", btnsPanel.CompsCount()))
		newbtn.AddEHandlerFunc(func(e gwu.Event) {
			btnsPanel.Remove(newbtn) // ...which removes itself when clicked
			e.MarkDirty(btnsPanel)
		}, gwu.ETypeClick)
		btnsPanel.Insert(newbtn, 0)
		e.MarkDirty(btnsPanel)
	}, gwu.ETypeClick)
	win.Add(btnsPanel)

	// ListBox examples
	p := gwu.NewHorizontalPanel()
	p.Style().SetBorder2(1, gwu.BrdStyleSolid, gwu.ClrBlack)
	p.SetCellPadding(2)
	p.Add(gwu.NewLabel("A drop-down list being"))
	widelb := gwu.NewListBox([]string{"50", "100", "150", "200", "250"})
	widelb.Style().SetWidth("50")
	widelb.AddEHandlerFunc(func(e gwu.Event) {
		widelb.Style().SetWidth(widelb.SelectedValue() + "px")
		e.MarkDirty(widelb)
	}, gwu.ETypeChange)
	p.Add(widelb)
	p.Add(gwu.NewLabel("pixel wide. And a multi-select list:"))
	listBox := gwu.NewListBox([]string{"First", "Second", "Third", "Forth", "Fifth", "Sixth"})
	listBox.SetMulti(true)
	listBox.SetRows(4)
	p.Add(listBox)
	countLabel := gwu.NewLabel("Selected count: 0")
	listBox.AddEHandlerFunc(func(e gwu.Event) {
		countLabel.SetText(fmt.Sprintf("Selected count: %d", len(listBox.SelectedIndices())))
		e.MarkDirty(countLabel)
	}, gwu.ETypeChange)
	p.Add(countLabel)
	win.Add(p)

	// Self-color changer check box
	greencb := gwu.NewCheckBox("I'm a check box. When checked, I'm green!")
	greencb.AddEHandlerFunc(func(e gwu.Event) {
		if greencb.State() {
			greencb.Style().SetBackground(gwu.ClrGreen)
		} else {
			greencb.Style().SetBackground("")
		}
		e.MarkDirty(greencb)
	}, gwu.ETypeClick)
	win.Add(greencb)

	// TextBox with echo
	p = gwu.NewHorizontalPanel()
	p.Add(gwu.NewLabel("Enter your name:"))
	tb := gwu.NewTextBox("")
	tb.AddSyncOnETypes(gwu.ETypeKeyUp)
	p.Add(tb)
	p.Add(gwu.NewLabel("You entered:"))
	nameLabel := gwu.NewLabel("")
	nameLabel.Style().SetColor(gwu.ClrRed)
	tb.AddEHandlerFunc(func(e gwu.Event) {
		nameLabel.SetText(tb.Text())
		e.MarkDirty(nameLabel)
	}, gwu.ETypeChange, gwu.ETypeKeyUp)
	p.Add(nameLabel)
	win.Add(p)

	// Create and start a GUI server (omitting error check)
	server := gwu.NewServer("guitest", "localhost:8081")
	server.SetText("Test GUI App")
	server.AddWin(win)
	server.Start("") // Also opens windows list in browser
}

Now start the application and open the http://localhost:8081/guitest/main URL in your browser to see the window. You can also try visiting http://localhost:8081/guitest/ which will render the available window list. Test the components. Now close the browser and reopen the page. Gowut remembers everything.

Limitations

1) Attaching onmouseover and onmouseout event handlers to a component and changing (re-rendering) the same component causes some trouble (the browsers generate multiple mouseover and mouseout events because the same HTML node is replaced under the mouse cursor).

2) Attaching onmousedown and onmouseup event handlers to a check box and re-rendering it prevents ETypeChange handlers being called when clicking on it.

Closing

From the MVC point of view looking at a Go application using Gowut, the Go components are the Model, the generated (and manipulated) HTML document in the browser is the View and the Controller is integrated in both.

Gowut is ideal to create (cross platform) user interfaces for desktop applications written in Go. It is also easy and handy to write the admin and also client interfaces of your Go web application using Gowut.

Happy UI coding in Go :-)

Index

Examples

Constants

View Source
const (
	HALeft   HAlign = "left"   // Horizontal left alignment
	HACenter        = "center" // Horizontal center alignment
	HARight         = "right"  // Horizontal right alignment

	HADefault = "" // Browser default (or inherited) horizontal alignment
)

Horizontal alignment constants.

View Source
const (
	VATop    VAlign = "top"    // Vertical top alignment
	VAMiddle        = "middle" // Vertical center alignment
	VABottom        = "bottom" // Vertical bottom alignment

	VADefault = "" // Browser default (or inherited) vertical alignment
)

Vertical alignment constants.

View Source
const (
	ThemeDefault = "default" // Default CSS theme
	ThemeDebug   = "debug"   // Debug CSS theme, useful for developing/debugging purposes.
)

Built-in CSS themes.

View Source
const (
	GowutVersion       = "v1.4.0"         // Gowut version: "v"major.minor.maintenance[-dev]
	GowutReleaseDate   = "2018-10-02 CET" // Gowut release date
	GowutRelDateLayout = "2006-01-02 MST" // Gowut release date layout (for time.Parse())
)

Gowut version information.

View Source
const (
	MouseBtnUnknown MouseBtn = -1 // Unknown mouse button (info not available)
	MouseBtnLeft             = 0  // Left mouse button
	MouseBtnMiddle           = 1  // Middle mouse button
	MouseBtnRight            = 2  // Right mouse button
)

Mouse buttons

View Source
const (
	KeyBackspace Key = 8
	KeyEnter         = 13
	KeyShift         = 16
	KeyCtrl          = 17
	KeyAlt           = 18
	KeyCapsLock      = 20
	KeyEscape        = 27
	KeySpace         = 32
	KeyPgUp          = 33
	KeyPgDown        = 34
	KeyEnd           = 35
	KeyHome          = 36
	KeyLeft          = 37
	KeyUp            = 38
	KeyRight         = 39
	KeyDown          = 40
	KeyPrintScrn     = 44
	KeyInsert        = 45
	KeyDel           = 46

	Key0 = 48
	Key9 = 57

	KeyA = 65
	KeyZ = 90

	KeyWin = 91

	KeyNumpad0     = 96
	KeyNumpad9     = 105
	KeyNumpadMul   = 106
	KeyNumpadPlus  = 107
	KeyNumpadMinus = 109
	KeyNumpadDot   = 110
	KeyNumpadDiv   = 111

	KeyF1  = 112
	KeyF2  = 113
	KeyF3  = 114
	KeyF4  = 115
	KeyF5  = 116
	KeyF6  = 117
	KeyF7  = 118
	KeyF8  = 119
	KeyF9  = 120
	KeyF10 = 121
	KeyF11 = 122
	KeyF12 = 123

	KeyNumLock    = 144
	KeyScrollLock = 145
)

Some key codes.

View Source
const (
	StBackground    = "background"     // Background (color)
	StBorder        = "border"         // Border
	StBorderLeft    = "border-left"    // Left border
	StBorderRight   = "border-right"   // Right border
	StBorderTop     = "border-top"     // Top border
	StBorderBottom  = "border-bottom"  // Bottom border
	StColor         = "color"          // (Foreground) color
	StCursor        = "cursor"         // Cursor
	StDisplay       = "display"        // Display
	StFontSize      = "font-size"      // Font size
	StFontStyle     = "font-style"     // Font style
	StFontWeight    = "font-weight"    // Font weight
	StHeight        = "height"         // Height
	StMargin        = "margin"         // Margin
	StMarginLeft    = "margin-left"    // Left margin
	StMarginRight   = "margin-right"   // Right margin
	StMarginTop     = "margin-top"     // Top margin
	StMarginBottom  = "margin-bottom"  // Bottom margin
	StPadding       = "padding"        // Padding
	StPaddingLeft   = "padding-left"   // Left padding
	StPaddingRight  = "padding-right"  // Right padding
	StPaddingTop    = "padding-top"    // Top padding
	StPaddingBottom = "padding-bottom" // Bottom padding
	StWhiteSpace    = "white-space"    // White-space
	StWidth         = "width"          // Width
)

Style attribute constants.

View Source
const (
	ClrAqua    = "Aqua"    // Aqua    (#00FFFF)
	ClrBlack   = "Black"   // Black   (#000000)
	ClrBlue    = "Blue"    // Blue    (#0000FF)
	ClrFuchsia = "Fuchsia" // Fuchsia (#FF00FF)
	ClrGray    = "Gray"    // Gray    (#808080)
	ClrGrey    = "Grey"    // Grey    (#808080)
	ClrGreen   = "Green"   // Green   (#008000)
	ClrLime    = "Lime"    // Lime    (#00FF00)
	ClrMaroon  = "Maroon"  // Maroon  (#800000)
	ClrNavy    = "Navy"    // Navy    (#000080)
	ClrOlive   = "Olive"   // Olive   (#808000)
	ClrPurple  = "Purple"  // Purple  (#800080)
	ClrRed     = "Red"     // Red     (#FF0000)
	ClrSilver  = "Silver"  // Silver  (#C0C0C0)
	ClrTeal    = "Teal"    // Teal    (#008080)
	ClrWhite   = "White"   // White   (#FFFFFF)
	ClrYellow  = "Yellow"  // Yellow  (#FFFF00)
)

The 17 standard color constants.

View Source
const (
	BrdStyleSolid  = "solid"  // Solid
	BrdStyleDashed = "dashed" // Dashed
	BrdStyleDotted = "dotted" // Dotted
	BrdStyleDouble = "double" // Double
	BrdStyleGroove = "groove" // 3D grooved border
	BrdStyleRidge  = "ridge"  // 3D ridged border
	BrdStyleInset  = "inset"  // 3D inset border
	BrdStyleOutset = "outset" // 3D outset border
)

Border style constants.

View Source
const (
	FontWeightNormal  = "normal"  // Normal
	FontWeightBold    = "bold"    // Bold
	FontWeightBolder  = "bolder"  // Bolder
	FontWeightLighter = "lighter" // Lighter
)

Font weight constants.

View Source
const (
	FontStyleNormal = "normal" // Normal
	FontStyleItalic = "italic" // Italic
)

Font style constants.

View Source
const (
	CursorAuto      = "auto"      // Default. Web browser sets the cursor.
	CursorCrosshair = "crosshair" // Crosshair
	CursorDefault   = "default"   // The default cursor.
	CursorHelp      = "help"      // Help
	CursorMove      = "move"      // Move
	CursorPointer   = "pointer"   // Pointer
	CursorProgress  = "progress"  // Progress
	CursorText      = "text"      // Text
	CursorWait      = "wait"      // Wait
	CursorInherit   = "inherit"   // The cursor should be inherited from the parent element.
)

Mouse cursor constants.

View Source
const (
	DisplayNone    = "none"    // The element will not be displayed.
	DisplayBlock   = "block"   // The element is displayed as a block.
	DisplayInline  = "inline"  // The element is displayed as an in-line element. This is the default.
	DisplayInherit = "inherit" // The display property value will be inherited from the parent element.
)

Display mode constants.

View Source
const (
	WhiteSpaceNormal  = "normal"   // Sequences of white spaces are collapsed into a single whitespace. Text will wrap when necessary. This is the default.
	WhiteSpaceNowrap  = "nowrap"   // Sequences of whitespace will collapse into a single whitespace. Text will never wrap to the next line (the text is in one line).
	WhiteSpacePre     = "pre"      // Whitespace is preserved. Text will only wrap on line breaks.
	WhiteSpacePreLine = "pre-line" // Sequences of whitespace will collapse into a single whitespace. Text will wrap when necessary and on line breaks.
	WhiteSpacePreWrap = "pre-wrap" // Whitespace is preserved. Text will wrap when necessary, and on line breaks.
	WhiteSpaceInherit = "inherit"  // Whitespace property will be inherited from the parent element.
)

White space constants.

View Source
const (
	// ETypeMouseDown is identical to ETypeMousedown
	ETypeMouseDown = ETypeMousedown
)
View Source
const EmptyEHandler emptyEventHandler = 0

EmptyEHandler is the empty event handler which does nothing.

Variables

This section is empty.

Functions

This section is empty.

Types

type AppRootHandlerFunc

type AppRootHandlerFunc func(w http.ResponseWriter, r *http.Request, sess Session)

AppRootHandlerFunc is the function type that handles the application root (when no window name is specified). sess is the shared, public session if no private session is created.

type Button

type Button interface {
	// Button is a component.
	Comp

	// Button has text.
	HasText

	// Button can be enabled/disabled.
	HasEnabled
}

Button interface defines a clickable button.

Suggested event type to handle actions: ETypeClick

Default style class: "gwu-Button"

Example

Example code determining which button was clicked.

package main

import (
	"github.com/icza/gowut/gwu"
)

func main() {
	b := gwu.NewButton("Click me")
	b.AddEHandlerFunc(func(e gwu.Event) {
		if e.MouseBtn() == gwu.MouseBtnMiddle {
			// Middle click
		}
	}, gwu.ETypeClick)
}
Output:

func NewButton

func NewButton(text string) Button

NewButton creates a new Button.

type CellFmt

type CellFmt interface {
	// CellFmt allows overriding horizontal and vertical alignment.
	HasHVAlign

	// Style returns the Style builder of the wrapper cell.
	Style() Style
	// contains filtered or unexported methods
}

CellFmt interface defines a cell formatter which can be used to format and style the wrapper cells of individual components such as child components of a PanelView or a Table.

type CheckBox

type CheckBox interface {
	// CheckBox is a StateButton.
	StateButton
}

CheckBox interface defines a check box, a button which has 2 states: selected/deselected.

Suggested event type to handle changes: ETypeClick

Default style classes: "gwu-CheckBox", "gwu-CheckBox-Disabled"

func NewCheckBox

func NewCheckBox(text string) CheckBox

NewCheckBox creates a new CheckBox. The initial state is false.

type Comp

type Comp interface {
	// ID returns the unique id of the component
	ID() ID

	// Equals tells if this component is equal to the specified another component.
	Equals(c2 Comp) bool

	// Parent returns the component's parent container.
	Parent() Container

	// Attr returns the explicitly set value of the specified HTML attribute.
	Attr(name string) string

	// SetAttr sets the value of the specified HTML attribute.
	// Pass an empty string value to delete the attribute.
	SetAttr(name, value string)

	// IAttr returns the explicitly set value of the specified HTML attribute
	// as an int.
	// -1 is returned if the value is not set explicitly or is not an int.
	IAttr(name string) int

	// SetAttr sets the value of the specified HTML attribute as an int.
	SetIAttr(name string, value int)

	// ToolTip returns the tool tip of the component.
	ToolTip() string

	// SetToolTip sets the tool tip of the component.
	SetToolTip(toolTip string)

	// Style returns the Style builder of the component.
	Style() Style

	// DescendantOf tells if this component is a descendant of the specified another component.
	DescendantOf(c2 Comp) bool

	// AddEHandler adds a new event handler.
	AddEHandler(handler EventHandler, etypes ...EventType)

	// AddEHandlerFunc adds a new event handler generated from a handler function.
	AddEHandlerFunc(hf func(e Event), etypes ...EventType)

	// HandlersCount returns the number of added handlers.
	HandlersCount(etype EventType) int

	// SyncOnETypes returns the event types on which to synchronize component value
	// from browser to the server.
	SyncOnETypes() []EventType

	// AddSyncOnETypes adds additional event types on which to synchronize
	// component value from browser to the server.
	AddSyncOnETypes(etypes ...EventType)

	// Render renders the component (as HTML code).
	Render(w Writer)
	// contains filtered or unexported methods
}

Comp interface: the base of all UI components.

type Container

type Container interface {
	// Container is a component.
	Comp

	// Remove removes a component from this container.
	// Return value indicates if the specified component was a child
	// and was removed successfully.
	// After a successful Remove the specified component's
	// Parent() method will return nil.
	Remove(c Comp) bool

	// ByID finds a component (recursively) by its ID and returns it.
	// nil is returned if no child component is found (recursively)
	// with the specified ID.
	ByID(id ID) Comp

	// Clear clears the container, removes all child components.
	Clear()
}

Container interface defines a component that can contain other components. Since a Container is a component itself, it can be added to other containers as well. The contained components are called the child components.

type Event

type Event interface {
	// Type returns the type of the event.
	Type() EventType

	// Src returns the source of the event,
	// the component the event is originating from
	Src() Comp

	// Parent returns the parent event if there's one.
	// Usually internal events have parent event for which the internal
	// event was created and dispatched.
	// The parent event can be used to identify the original source and event type.
	Parent() Event

	// Mouse returns the mouse x and y coordinates relative to the component.
	// If no mouse coordinate info is available, (-1, -1) is returned.
	Mouse() (x, y int)

	// MouseWin returns the mouse x and y coordinates inside the window.
	// If no mouse coordinate info is available, (-1, -1) is returned.
	MouseWin() (x, y int)

	// MouseBtn returns the mouse button.
	// If no mouse button info is available, MouseBtnUnknown is returned.
	MouseBtn() MouseBtn

	// ModKeys returns the states of the modifier keys.
	// The returned value contains the states of all modifier keys,
	// constants of type ModKey can be used to test a specific modifier key,
	// or use the ModKey method.
	ModKeys() int

	// ModKey returns the state of the specified modifier key.
	ModKey(modKey ModKey) bool

	// Key code returns the key code.
	KeyCode() Key

	// Requests the specified window to be reloaded
	// after processing the current event.
	// Tip: pass an empty string to reload the current window.
	ReloadWin(name string)

	// MarkDirty marks components dirty,
	// causing them to be re-rendered after processing the current event.
	// Component re-rendering happens without page reload in the browser.
	//
	// Note: the Window itself (which is a Comp) can also be marked dirty
	// causing the whole window content to be re-rendered without page reload!
	//
	// Marking a component dirty also marks all of its descendants dirty, recursively.
	//
	// Also note that components will not be re-rendered multiple times.
	// For example if a child component and its parent component are both
	// marked dirty, the child component will only be re-rendered once.
	MarkDirty(comps ...Comp)

	// SetFocusedComp sets the component to be focused after processing
	// the current event.
	SetFocusedComp(comp Comp)

	// Session returns the current session.
	// The Private() method of the session can be used to tell if the session
	// is a private session or the public shared session.
	Session() Session

	// NewSession creates a new (private) session.
	// If the current session (as returned by Session()) is private,
	// it will be removed first.
	NewSession() Session

	// RemoveSess removes (invalidates) the current session.
	// Only private sessions can be removed, calling this
	// when the current session (as returned by Session()) is public is a no-op.
	// After this method Session() will return the shared public session.
	RemoveSess()
	// contains filtered or unexported methods
}

Event interface defines the event originating from components.

type EventCategory

type EventCategory int

EventCategory is the event type category.

const (
	ECatGeneral  EventCategory = iota // General event type for all components
	ECatWindow                        // Window event type for Window only
	ECatInternal                      // Internal event generated and dispatched internally while processing another event

	ECatUnknown EventCategory = -1 // Unknown event category
)

Event type categories.

type EventHandler

type EventHandler interface {
	// Handles the event.
	//
	// If components are modified in a way that their view changes,
	// these components must be marked dirty in the event object
	// (so the client will see up-to-date state).
	//
	// If the component tree is modified (new component added
	// or removed for example), then the Container whose structure
	// was modified has to be marked dirty.
	HandleEvent(e Event)
}

EventHandler interface defines a handler capable of handling events.

type EventType

type EventType int

EventType is the event type (kind) type.

const (
	// General events for all components
	ETypeClick     EventType = iota // Mouse click event
	ETypeDblClick                   // Mouse double click event
	ETypeMousedown                  // Mouse down event
	ETypeMouseMove                  // Mouse move event
	ETypeMouseOver                  // Mouse over event
	ETypeMouseOut                   // Mouse out event
	ETypeMouseUp                    // Mouse up event
	ETypeKeyDown                    // Key down event
	ETypeKeyPress                   // Key press event
	ETypeKeyUp                      // Key up event
	ETypeBlur                       // Blur event (component loses focus)
	ETypeChange                     // Change event (value change)
	ETypeFocus                      // Focus event (component gains focus)

	// Window events (for Window only)
	ETypeWinLoad   // Window load event
	ETypeWinUnload // Window unload event

	// Internal events, generated and dispatched internally while processing another event
	ETypeStateChange // State change
)

Event types.

func (EventType) Category

func (etype EventType) Category() EventCategory

Category returns the event type category.

func (EventType) String

func (etype EventType) String() string

Converts an Event type to a string.

type Expander

type Expander interface {
	// Expander is a TableView.
	TableView

	// Header returns the header component of the expander.
	Header() Comp

	// SetHeader sets the header component of the expander.
	SetHeader(h Comp)

	// Content returns the content component of the expander.
	Content() Comp

	// SetContent sets the content component of the expander.
	SetContent(c Comp)

	// Expanded returns whether the expander is expanded.
	Expanded() bool

	// SetExpanded sets whether the expander is expanded.
	SetExpanded(expanded bool)

	// HeaderFmt returns the cell formatter of the header.
	HeaderFmt() CellFmt

	// ContentFmt returns the cell formatter of the content.
	ContentFmt() CellFmt
}

Expander interface defines a component which can show and hide another component when clicked on the header.

You can register ETypeStateChange event handlers which will be called when the user expands or collapses the expander by clicking on the header. The event source will be the expander. The event will have a parent event whose source will be the clicked header component and will contain the mouse coordinates.

Default style classes: "gwu-Expander", "gwu-Expander-Header", "gwuimg-collapsed", "gwu-Expander-Header-Expanded", "gwuimg-expanded", "gwu-Expander-Content"

func NewExpander

func NewExpander() Expander

NewExpander creates a new Expander. By default expanders are collapsed.

type HAlign

type HAlign string

HAlign is the horizontal alignment type.

type HTML added in v1.2.0

type HTML interface {
	// HTML is a component.
	Comp

	// HTML returns the HTML text.
	HTML() string

	// SetHTML sets the HTML text.
	SetHTML(html string)
}

HTML interface defines a component which wraps an HTML text into a component.

Default style class: "gwu-HTML"

func NewHTML added in v1.2.0

func NewHTML(html string) HTML

NewHTML creates a new HTML.

type HasEnabled

type HasEnabled interface {
	// Enabled returns the enabled property.
	Enabled() bool

	// SetEnabled sets the enabled property.
	SetEnabled(enabled bool)
}

HasEnabled interface defines an enabled property.

type HasHVAlign

type HasHVAlign interface {
	// HAlign returns the horizontal alignment.
	HAlign() HAlign

	// SetHAlign sets the horizontal alignment.
	SetHAlign(halign HAlign)

	// VAlign returns the vertical alignment.
	VAlign() VAlign

	// SetVAlign sets the vertical alignment.
	SetVAlign(valign VAlign)

	// SetAlign sets both the horizontal and vertical alignments.
	SetAlign(halign HAlign, valign VAlign)
}

HasHVAlign interfaces defines a horizontal and a vertical alignment property.

type HasRequestResponse

type HasRequestResponse interface {
	// ResponseWriter returns the associated HTTP response writer.
	ResponseWriter() http.ResponseWriter

	// Request returns the associated HTTP request.
	Request() *http.Request
}

HasRequestResponse defines methods to acquire / access http.ResponseWriter and http.Request from something that supports this.

The concrete type that implements Event does implement this too, but this is not added to the Event interface intentionally to not urge the use of this. Users should not rely on this as in a future implementation there might not be a response and request associated with an event. But this may be useful in certain scenarios, such as you need to know the client IP address, or you want to use custom authentication that needs the request/response.

To get access to these methods, simply use a type assertion, asserting that the event value implements this interface. For example:

someButton.AddEHandlerFunc(func(e gwu.Event) {
    if hrr, ok := e.(gwu.HasRequestResponse); ok {
        req := hrr.Request()
        log.Println("Client addr:", req.RemoteAddr)
    }
}, gwu.ETypeClick)

type HasText

type HasText interface {
	// Text returns the text.
	Text() string

	// SetText sets the text.
	SetText(text string)
}

HasText interface defines a modifiable text property.

type HasURL added in v1.2.0

type HasURL interface {
	// URL returns the URL string.
	URL() string

	// SetURL sets the URL string.
	SetURL(url string)
}

HasURL interface defines a URL string property.

type ID

type ID int

ID is the type of the ids of the components.

func AtoID

func AtoID(s string) (ID, error)

AtoID converts a string to ID.

func (ID) String

func (id ID) String() string

Converts an ID to a string.

type Image

type Image interface {
	// Image is a component.
	Comp

	// Image has text which is its description (alternate text).
	HasText

	// Image has URL string.
	HasURL
}

Image interface defines an image.

Default style class: "gwu-Image"

func NewImage

func NewImage(text, url string) Image

NewImage creates a new Image. The text is used as the alternate text for the image.

type Key

type Key int

Key (keyboard key) type.

type Label

type Label interface {
	// Label is a component.
	Comp

	// Label has text.
	HasText
}

Label interface defines a component which wraps a text into a component.

Default style class: "gwu-Label"

func NewLabel

func NewLabel(text string) Label

NewLabel creates a new Label.

type Layout

type Layout int

Layout strategy type.

const (
	LayoutNatural    Layout = iota // Natural layout: elements are displayed in their natural order.
	LayoutVertical                 // Vertical layout: elements are laid out vertically.
	LayoutHorizontal               // Horizontal layout: elements are laid out horizontally.
)

Layout strategies.

type Link interface {
	// Link is a Container.
	Container

	// Link has text.
	HasText

	// Link has URL string.
	HasURL

	// Target returns the target of the link.
	Target() string

	// SetTarget sets the target of the link.
	// Tip: pass "_blank" if you want the URL to open in a new window
	// (this is the default).
	SetTarget(target string)

	// Comp returns the optional child component, if set.
	Comp() Comp

	// SetComp sets the only child component
	// (which can be a Container of course).
	SetComp(c Comp)
}

Link interface defines a clickable link pointing to a URL. Links are usually used with a text, although Link is a container, and allows to set a child component which if set will also be a part of the clickable link.

Default style class: "gwu-Link"

func NewLink(text, url string) Link

NewLink creates a new Link. By default links open in a new window (tab) because their target is set to "_blank".

type ListBox

type ListBox interface {
	// ListBox is a component
	Comp

	// ListBox can be enabled/disabled.
	HasEnabled

	// Values returns the values.
	Values() []string

	// SetValues sets the values. Also clears the selection.
	SetValues(values []string)

	// Multi tells if multiple selections are allowed.
	Multi() bool

	// SetMulti sets whether multiple selections are allowed.
	SetMulti(multi bool)

	// Rows returns the number of displayed rows.
	Rows() int

	// SetRows sets the number of displayed rows.
	// rows=1 will make this ListBox a dropdown list (if multi is false!).
	// Note that if rows is greater than 1, most browsers enforce a visual minimum size
	// (about 4 rows) even if rows is less than that.
	SetRows(rows int)

	// SelectedValue retruns the first selected value.
	// Empty string is returned if nothing is selected.
	SelectedValue() string

	// SelectedValues retruns all the selected values.
	SelectedValues() []string

	// Selected tells if the value at index i is selected.
	Selected(i int) bool

	// SelectedIdx returns the first selected index.
	// Returns -1 if nothing is selected.
	SelectedIdx() int

	// SelectedIndices returns a slice of the indices of the selected values.
	SelectedIndices() []int

	// SetSelected sets the selection state of the value at index i.
	SetSelected(i int, selected bool)

	// SetSelectedIndices sets the (only) selected values.
	// Only values will be selected that are contained in the specified indices slice.
	SetSelectedIndices(indices []int)

	// ClearSelected deselects all values.
	ClearSelected()
}

ListBox interface defines a component which allows selecting one or multiple values from a predefined list.

Suggested event type to handle changes: ETypeChange

Default style class: "gwu-ListBox"

func NewListBox

func NewListBox(values []string) ListBox

NewListBox creates a new ListBox.

type ModKey

type ModKey int

ModKey is the modifier key type.

const (
	ModKeyAlt   ModKey = 1 << iota // Alt key
	ModKeyCtrl                     // Control key
	ModKeyMeta                     // Meta key
	ModKeyShift                    // Shift key
)

Modifier key masks.

type MouseBtn

type MouseBtn int

MouseBtn is the mouse button type.

type Panel

type Panel interface {
	// Panel is a PanelView.
	PanelView

	// Add adds a component to the panel.
	Add(c Comp)

	// Insert inserts a component at the specified index.
	// Returns true if the index was valid and the component is inserted
	// successfully, false otherwise. idx=CompsCount() is also allowed
	// in which case comp will be the last component.
	Insert(c Comp, idx int) bool

	// AddHSpace adds and returns a fixed-width horizontal space consumer.
	// Useful when layout is LayoutHorizontal.
	AddHSpace(width int) Comp

	// AddVSpace adds and returns a fixed-height vertical space consumer.
	// Useful when layout is LayoutVertical.
	AddVSpace(height int) Comp

	// AddSpace adds and returns a fixed-size space consumer.
	AddSpace(width, height int) Comp

	// AddHConsumer adds and returns a horizontal (free) space consumer.
	// Useful when layout is LayoutHorizontal.
	//
	// Tip: When adding a horizontal space consumer, you may set the
	// white space style attribute of other components in the the panel
	// to WhiteSpaceNowrap to avoid texts getting wrapped to multiple lines.
	AddHConsumer() Comp

	// AddVConsumer adds and returns a vertical (free) space consumer.
	// Useful when layout is LayoutVertical.
	AddVConsumer() Comp
}

Panel interface defines a container which stores child components associated with an index, and lays out its children based on a layout strategy. Default style class: "gwu-Panel"

func NewHorizontalPanel

func NewHorizontalPanel() Panel

NewHorizontalPanel creates a new Panel initialized with LayoutHorizontal layout. Default horizontal alignment is HADefault, default vertical alignment is VADefault.

func NewNaturalPanel

func NewNaturalPanel() Panel

NewNaturalPanel creates a new Panel initialized with LayoutNatural layout. Default horizontal alignment is HADefault, default vertical alignment is VADefault.

func NewPanel

func NewPanel() Panel

NewPanel creates a new Panel. Default layout strategy is LayoutVertical, default horizontal alignment is HADefault, default vertical alignment is VADefault.

func NewVerticalPanel

func NewVerticalPanel() Panel

NewVerticalPanel creates a new Panel initialized with LayoutVertical layout. Default horizontal alignment is HADefault, default vertical alignment is VADefault.

type PanelView

type PanelView interface {
	// PanelView is a TableView.
	TableView

	// Layout returns the layout strategy used to lay out components when rendering.
	Layout() Layout

	// SetLayout sets the layout strategy used to lay out components when rendering.
	SetLayout(layout Layout)

	// CompsCount returns the number of components added to the panel.
	CompsCount() int

	// CompAt returns the component at the specified index.
	// Returns nil if idx<0 or idx>=CompsCount().
	CompAt(idx int) Comp

	// CompIdx returns the index of the specified component in the panel.
	// -1 is returned if the component is not added to the panel.
	CompIdx(c Comp) int

	// CellFmt returns the cell formatter of the specified child component.
	// If the specified component is not a child, nil is returned.
	// Cell formatting has no effect if layout is LayoutNatural.
	CellFmt(c Comp) CellFmt
}

PanelView interface defines a container which stores child components sequentially (one dimensional, associated with an index), and lays out its children in a row or column using TableView based on a layout strategy, but does not define the way how child components can be added.

Default style class: "gwu-Panel"

type PasswBox

type PasswBox interface {
	// PasswBox is a TextBox.
	TextBox
}

PasswBox interface defines a text box for password input purpose.

Suggested event type to handle actions: ETypeChange

By default the value of the PasswBox is synchronized with the server on ETypeChange event which is when the PasswBox loses focus or when the ENTER key is pressed. If you want a PasswBox to synchronize values during editing (while you type in characters), add the ETypeKeyUp event type to the events on which synchronization happens by calling:

AddSyncOnETypes(ETypeKeyUp)

Default style class: "gwu-PasswBox"

type RadioButton

type RadioButton interface {
	// RadioButton is a StateButton.
	StateButton

	// Group returns the group of the radio button.
	Group() RadioGroup
	// contains filtered or unexported methods
}

RadioButton interface defines a radio button, a button which has 2 states: selected/deselected. In addition to the state, radio buttons belong to a group, and in each group only one radio button can be selected. Selecting an unselected radio button deselects the selected radio button of the group, if there was one.

Suggested event type to handle changes: ETypeClick

Default style classes: "gwu-RadioButton", "gwu-RadioButton-Disabled"

func NewRadioButton

func NewRadioButton(text string, group RadioGroup) RadioButton

NewRadioButton creates a new radio button. The initial state is false.

type RadioGroup

type RadioGroup interface {
	// Name returns the name of the radio group.
	Name() string

	// Selected returns the selected radio button of the group.
	Selected() RadioButton

	// PrevSelected returns the radio button that was selected
	// before the current selected radio button.
	PrevSelected() RadioButton
	// contains filtered or unexported methods
}

RadioGroup interface defines the group for grouping radio buttons.

func NewRadioGroup

func NewRadioGroup(name string) RadioGroup

NewRadioGroup creates a new RadioGroup.

type Server

type Server interface {
	// The Server implements the Session interface:
	// there is one public session which is shared between
	// the "sessionless" requests.
	// This is to maintain windows without a session.
	Session

	// A server has text which will be used as the title
	// of the server.
	HasText

	// Secure returns if the server is configured to run
	// in secure (HTTPS) mode or in HTTP mode.
	Secure() bool

	// AppURL returns the application URL string.
	AppURL() string

	// AppPath returns the application path string.
	AppPath() string

	// AddSessCreatorName registers a nonexistent window name
	// whose path auto-creates a new session.
	//
	// Normally sessions are created from event handlers during
	// event dispatching by calling Event.NewSession(). This
	// requires a public window and an event source component
	// (e.g. a Button) to create a session.
	// With AddSessCreatorName you can register nonexistent (meaning
	// not-yet added) window names whose path will trigger an automatic
	// session creation (if the current session is not private), and
	// with a registered SessionHandler you can build the window and
	// add it to the auto-created new session prior to it being served.
	//
	// The text linking to the name will be included in the window list
	// if text is a non-empty string.
	//
	// Tip: You can use this to pre-register a login window for example.
	// You can call
	// 		AddSessCreatorName("login", "Login Window")
	// and in the Created() method of a registered SessionHandler:
	//		func (h MySessHanlder) Created(s gwu.Session) {
	//			win := gwu.NewWindow("login", "Login Window")
	//			// ...add content to the login window...
	// 			s.AddWindow(win)
	// 		}
	AddSessCreatorName(name, text string)

	// AddSHandler adds a new session handler.
	AddSHandler(handler SessionHandler)

	// SetHeaders sets extra HTTP response headers that are added to all responses.
	// Supplied values are copied, so changes to the passed map afterwards have no effect.
	//
	// For example to add an extra "Gowut-Server" header whose value is the Gowut version:
	//     server.SetHeaders(map[string][]string{
	//         "Gowut-Server": {gwu.GowutVersion},
	//     })
	SetHeaders(headers map[string][]string)

	// Headers returns the extra HTTP response headers that are added to all repsonses.
	// A copy is returned, so changes to the returned map afterwards have no effect.
	Headers() map[string][]string

	// AddStaticDir registers a directory whose content (files) recursively
	// will be served by the server when requested.
	// path is an app-path relative path to address a file, dir is the root directory
	// to search in.
	// Note that the app name must be included in absolute request paths,
	// and it may be omitted if you want to use relative paths.
	// Extra headers set by SetHeaders() will also be included in responses serving the static files.
	//
	// Example:
	//     AddStaticDir("img", "/tmp/myimg")
	// Then request for absolute path "/appname/img/faces/happy.gif" will serve
	// "/tmp/myimg/faces/happy.gif", just as the the request for relative path "img/faces/happy.gif".
	AddStaticDir(path, dir string) error

	// Theme returns the default CSS theme of the server.
	Theme() string

	// SetTheme sets the default CSS theme of the server.
	SetTheme(theme string)

	// SetLogger sets the logger to be used
	// to log incoming requests.
	// Pass nil to disable logging. This is the default.
	SetLogger(logger *log.Logger)

	// Logger returns the logger that is used to log incoming requests.
	Logger() *log.Logger

	// AddRootHeadHTML adds an HTML text which will be included
	// in the HTML <head> section of the window list page (the app root).
	// Note that these will be ignored if you take over the app root
	// (by calling SetAppRootHandler).
	AddRootHeadHTML(html string)

	// RemoveRootHeadHTML removes an HTML head text
	// that was previously added with AddRootHeadHTML().
	RemoveRootHeadHTML(html string)

	// SetAppRootHandler sets a function that is called when the app root is requested.
	// The default function renders the window list, including authenticated windows
	// and session creators - with clickable links.
	// By setting your own hander, you will completely take over the app root.
	SetAppRootHandler(f AppRootHandlerFunc)

	// SessIDCookieName returns the cookie name used to store the Gowut
	// session ID.
	SessIDCookieName() string

	// session ID.
	SetSessIDCookieName(name string)

	// Start starts the GUI server and waits for incoming connections.
	//
	// Sessionless window names may be specified as optional parameters
	// that will be opened in the default browser.
	// Tip: Pass an empty string to open the window list.
	// Tip: Not passing any window names will start the server silently
	// without opening any windows.
	Start(openWins ...string) error
}

Server interface defines the GUI server which handles sessions, renders the windows, components and handles event dispatching.

func NewServer

func NewServer(appName, addr string) Server

NewServer creates a new GUI server in HTTP mode. The specified app name will be part of the application path (the first part). If addr is empty string, "localhost:3434" will be used.

Tip: Pass an empty string as appName to place the GUI server to the root path ("/").

func NewServerTLS

func NewServerTLS(appName, addr, certFile, keyFile string) Server

NewServerTLS creates a new GUI server in secure (HTTPS) mode. The specified app name will be part of the application path (the first part). If addr is empty string, "localhost:3434" will be used.

Tip: Pass an empty string as appName to place the GUI server to the root path ("/"). Tip: You can use generate_cert.go in crypto/tls to generate a test certificate and key file (cert.pem andkey.pem).

type SessMonitor

type SessMonitor interface {
	// SessMonitor is a Timer, but it does not generate Events!
	Timer

	// SetJsConverter sets the Javascript function name which converts
	// a float second time value to a displayable string.
	// The default value is "convertSessTimeout" whose implementation is:
	//     function convertSessTimeout(sec) {
	//         if (sec <= 0)
	//             return "Expired!";
	//         else if (sec < 60)
	//             return "<1 min";
	//         else
	//             return "~" + Math.round(sec / 60) + " min";
	//     }
	SetJsConverter(jsFuncName string)

	// JsConverter returns the name of the Javascript function which converts
	// float second time values to displayable strings.
	JsConverter() string
}

SessMonitor interface defines a component which monitors and displays the session timeout and network connectivity at client side without interacting with the session.

Default style classes: "gwu-SessMonitor", "gwu-SessMonitor-Expired", "gwu-SessMonitor-Error"

func NewSessMonitor

func NewSessMonitor() SessMonitor

NewSessMonitor creates a new SessMonitor. By default it is active repeats with 1 minute timeout duration.

type Session

type Session interface {
	// ID returns the ID of the session.
	ID() string

	// New tells if the session is new meaning the client
	// does not (yet) know about it.
	New() bool

	// Private tells if the session is a private session.
	// There is only one public session, and it is shared
	// between the "sessionless" users.
	Private() bool

	// AddWin adds a window to the session.
	// Returns an error if window name is empty or
	// a window with the same name has already been added.
	AddWin(w Window) error

	// RemoveWin removes a window from the session.
	// Returns if the window was removed from the session.
	RemoveWin(w Window) bool

	// SortedWins returns a sorted slice of windows.
	// The slice is sorted by window text (title).
	SortedWins() []Window

	// WinByName returns a window specified by its name.
	WinByName(name string) Window

	// Attr returns the value of an attribute stored in the session.
	// TODO use an interface type something like "serializable".
	Attr(name string) interface{}

	// SetAttr sets the value of an attribute stored in the session.
	// Pass the nil value to delete the attribute.
	SetAttr(name string, value interface{})

	// Created returns the time when the session was created.
	Created() time.Time

	// Accessed returns the time when the session was last accessed.
	Accessed() time.Time

	// Timeout returns the session timeout.
	Timeout() time.Duration

	// SetTimeout sets the session timeout.
	SetTimeout(timeout time.Duration)
	// contains filtered or unexported methods
}

Session interface defines the session to the GWU users (clients).

type SessionHandler

type SessionHandler interface {
	// Created is called when a new session is created.
	// At this time the client does not yet know about the session.
	Created(sess Session)

	// Removed is called when a session is being removed
	// from the server. After removal, the session id will become
	// an invalid session id.
	Removed(sess Session)
}

SessionHandler interface defines a callback to get notified for certain events related to session life-cycles.

type StateButton

type StateButton interface {
	// stateButton is a button
	Button

	// State returns the state of the button.
	State() bool

	// SetState sets the state of the button.
	// In case of RadioButton, the button's RadioGroup is managed
	// so that only one can be selected.
	SetState(state bool)
}

StateButton interface defines a button which has a boolean state: true/false or selected/deselected.

type Style

type Style interface {
	// AddClass adds a style class name to the class name list.
	AddClass(class string) Style

	// SetClass sets a style class name, removing all previously
	// added style class names.
	// Tip: set an empty string class name to remove all class names.
	SetClass(class string) Style

	// RemoveClass removes a style class name.
	// If the specified class is not found, this is a no-op.
	RemoveClass(class string) Style

	// Get returns the explicitly set value of the specified style attribute.
	// Explicitly set style attributes will be concatenated and rendered
	// as the "style" HTML attribute of the component.
	Get(name string) string

	// Set sets the value of the specified style attribute.
	// Pass an empty string value to delete the specified style attribute.
	Set(name, value string) Style

	// Size returns the size.
	Size() (width, height string)

	// SetSize sets the width and height.
	SetSize(width, height string) Style

	// SetSizePx sets the width and height, in pixels.
	SetSizePx(width, height int) Style

	// SetFullSize sets full width (100%) and height (100%).
	SetFullSize() Style

	// Padding returns the padding.
	// (The "padding" style attribute only.)
	Padding() string

	// SetPadding sets the padding.
	// (The "padding" style attribute only.)
	SetPadding(value string) Style

	// SetPadding2 sets the padding specified by parts.
	// (The "padding" style attribute only.)
	SetPadding2(top, right, bottom, left string) Style

	// SetPaddingPx sets the padding specified by parts, in pixels.
	// (The "padding" style attribute only.)
	SetPaddingPx(top, right, bottom, left int) Style

	// PaddingLeft returns the left padding.
	// (The "padding-left" style attribute only.)
	PaddingLeft() string

	// SetPaddingLeft sets the left padding.
	// (The "padding-left" style attribute only.)
	SetPaddingLeft(value string) Style

	// SetPaddingLeftPx sets the left padding, in pixels.
	// (The "padding-left" style attribute only.)
	SetPaddingLeftPx(width int) Style

	// PaddingRight returns the right padding.
	// (The "padding-right" style attribute only.)
	PaddingRight() string

	// SetPaddingRight sets the right padding.
	// (The "padding-right" style attribute only.)
	SetPaddingRight(value string) Style

	// SetPaddingRightPx sets the right padding, in pixels.
	// (The "padding-right" style attribute only.)
	SetPaddingRightPx(width int) Style

	// PaddingTop returns the top padding.
	// (The "padding-top" style attribute only.)
	PaddingTop() string

	// SetPaddingTop sets the top padding.
	// (The "padding-top" style attribute only.)
	SetPaddingTop(value string) Style

	// SetPaddingTopPx sets the top padding, in pixels.
	// (The "padding-top" style attribute only.)
	SetPaddingTopPx(height int) Style

	// PaddingBottom returns the bottom padding.
	// (The "padding-bottom" style attribute only.)
	PaddingBottom() string

	// SetPaddingBottom sets the bottom padding.
	// (The "padding-bottom" style attribute only.)
	SetPaddingBottom(value string) Style

	// SetPaddingBottomPx sets the bottom padding, in pixels.
	// (The "padding-bottom" style attribute only.)
	SetPaddingBottomPx(height int) Style

	// Margin returns the margin.
	// (The "margin" style attribute only.)
	Margin() string

	// SetMargin sets the margin.
	// (The "margin" style attribute only.)
	SetMargin(value string) Style

	// SetMargin2 sets the margin specified by parts.
	// (The "margin" style attribute only.)
	SetMargin2(top, right, bottom, left string) Style

	// SetMarginPx sets the margin specified by parts, in pixels.
	// (The "margin" style attribute only.)
	SetMarginPx(top, right, bottom, left int) Style

	// MarginLeft returns the left margin.
	// (The "margin-left" style attribute only.)
	MarginLeft() string

	// SetMarginLeft sets the left margin.
	// (The "margin-left" style attribute only.)
	SetMarginLeft(value string) Style

	// SetMarginLeftPx sets the left margin, in pixels.
	// (The "margin-left" style attribute only.)
	SetMarginLeftPx(width int) Style

	// MarginRight returns the right margin.
	// (The "margin-right" style attribute only.)
	MarginRight() string

	// SetMarginRight sets the right margin.
	// (The "margin-right" style attribute only.)
	SetMarginRight(value string) Style

	// SetMarginRightPx sets the right margin, in pixels.
	// (The "margin-right" style attribute only.)
	SetMarginRightPx(width int) Style

	// MarginTop returns the top margin.
	// (The "margin-top" style attribute only.)
	MarginTop() string

	// SetMarginTop sets the top margin.
	// (The "margin-top" style attribute only.)
	SetMarginTop(value string) Style

	// SetMarginTopPx sets the top margin, in pixels.
	// (The "margin-top" style attribute only.)
	SetMarginTopPx(height int) Style

	// MarginBottom returns the bottom margin.
	// (The "margin-bottom" style attribute only.)
	MarginBottom() string

	// SetMarginBottom sets the bottom margin.
	// (The "margin-bottom" style attribute only.)
	SetMarginBottom(value string) Style

	// SetMarginBottomPx sets the bottom margin, in pixels.
	// (The "margin-bottom" style attribute only.)
	SetMarginBottomPx(height int) Style

	// Background returns the background (color).
	Background() string

	// SetBackground sets the background (color).
	SetBackground(value string) Style

	// Border returns the border.
	Border() string

	// SetBorder sets the border.
	SetBorder(value string) Style

	// SetBorder2 sets the border specified by parts.
	// (The "border" style attribute only.)
	SetBorder2(width int, style, color string) Style

	// BorderLeft returns the left border.
	BorderLeft() string

	// SetBorderLeft sets the left border.
	SetBorderLeft(value string) Style

	// SetBorderLeft2 sets the left border specified by parts.
	// (The "border-left" style attribute only.)
	SetBorderLeft2(width int, style, color string) Style

	// BorderRight returns the right border.
	BorderRight() string

	// SetBorderRight sets the right border.
	SetBorderRight(value string) Style

	// SetBorderRight2 sets the right border specified by parts.
	// (The "border-right" style attribute only.)
	SetBorderRight2(width int, style, color string) Style

	// BorderTop returns the top border.
	BorderTop() string

	// SetBorderTop sets the top border.
	SetBorderTop(value string) Style

	// SetBorderTop2 sets the top border specified by parts.
	// (The "border-top" style attribute only.)
	SetBorderTop2(width int, style, color string) Style

	// BorderBottom returns the bottom border.
	BorderBottom() string

	// SetBorderBottom sets the bottom border.
	SetBorderBottom(value string) Style

	// SetBorderBottom2 sets the bottom border specified by parts.
	// (The "border-bottom" style attribute only.)
	SetBorderBottom2(width int, style, color string) Style

	// Color returns the (foreground) color.
	Color() string

	// SetColor sets the (foreground) color.
	SetColor(value string) Style

	// Cursor returns the (mouse) cursor.
	Cursor() string

	// SetCursor sets the (mouse) cursor.
	SetCursor(value string) Style

	// Display returns the display mode.
	Display() string

	// SetDisplay sets the display mode
	SetDisplay(value string) Style

	// FontSize returns the font size.
	FontSize() string

	// SetFontSize sets the font size.
	SetFontSize(value string) Style

	// FontStyle returns the font style.
	FontStyle() string

	// SetFontStyle sets the font style.
	SetFontStyle(value string) Style

	// FontWeight returns the font weight.
	FontWeight() string

	// SetFontWeight sets the font weight.
	SetFontWeight(value string) Style

	// Width returns the width.
	Width() string

	// SetWidth sets the width.
	SetWidth(value string) Style

	// SetWidthPx sets the width, in pixels.
	SetWidthPx(width int) Style

	// SetFullWidth sets full width (100%).
	SetFullWidth() Style

	// Height returns the height.
	Height() string

	// SetHeight sets the height.
	SetHeight(value string) Style

	// SetHeightPx sets the height.
	SetHeightPx(height int) Style

	// SetFullHeight sets full height (100%).
	SetFullHeight() Style

	// WhiteSpace returns the white space attribute value.
	WhiteSpace() string

	// SetWhiteSpace sets the white space attribute value.
	SetWhiteSpace(value string) Style
	// contains filtered or unexported methods
}

Style interface contains utility methods for manipulating the style of a component. You can think of it as the Style Builder. Set methods return the style reference so setting the values of multiple style attributes can be chained.

type SwitchButton

type SwitchButton interface {
	// SwitchButton is a component.
	Comp

	// SwitchButton can be enabled/disabled.
	HasEnabled

	// State returns the state of the switch button.
	State() bool

	// SetState sets the state of the switch button.
	SetState(state bool)

	// On returns the text displayed for the ON side.
	On() string

	// Off returns the text displayed for the OFF side.
	Off() string

	// SetOnOff sets the texts of the ON and OFF sides.
	SetOnOff(on, off string)
}

SwitchButton interface defines a button which can be switched ON and OFF.

Suggested event type to handle changes: ETypeClick

Default style classes: "gwu-SwitchButton", "gwu-SwitchButton-On-Active" "gwu-SwitchButton-On-Inactive", "gwu-SwitchButton-Off-Active", "gwu-SwitchButton-Off-Inactive"

func NewSwitchButton

func NewSwitchButton() SwitchButton

NewSwitchButton creates a new SwitchButton. Default texts for ON and OFF sides are: "ON" and "OFF". The initial state is false (OFF).

type TabBar

type TabBar interface {
	// TabBar is a PanelView.
	PanelView
}

TabBar interface defines the tab bar for selecting the visible component of a TabPanel.

Note: Removing a tab component through the tab bar also removes the content component from the tab panel of the tab bar.

Default style classes: "gwu-TabBar", "gwu-TabBar-Top", "gwu-TabBar-Bottom", "gwu-TabBar-Left", "gwu-TabBar-Right", "gwu-TabBar-NotSelected", "gwu-TabBar-Selected"

type TabBarPlacement

type TabBarPlacement int

TabBarPlacement is the Tab bar placement type.

const (
	TbPlacementTop    TabBarPlacement = iota // Tab bar placement to Top
	TbPlacementBottom                        // Tab bar placement to Bottom
	TbPlacementLeft                          // Tab bar placement to Left
	TbPlacementRight                         // Tab bar placement to Right
)

Tab bar placements.

type TabPanel

type TabPanel interface {
	// TabPanel is a Container.
	PanelView

	// TabBar returns the tab bar.
	TabBar() TabBar

	// TabBarPlacement returns the tab bar placement.
	TabBarPlacement() TabBarPlacement

	// SetTabBarPlacement sets tab bar placement.
	// Also sets the alignment of the tab bar according
	// to the tab bar placement.
	SetTabBarPlacement(tabBarPlacement TabBarPlacement)

	// TabBarFmt returns the cell formatter of the tab bar.
	TabBarFmt() CellFmt

	// Add adds a new tab (component) and an associated (content) component
	// to the tab panel.
	Add(tab, content Comp)

	// Add adds a new tab (string) and an associated (content) component
	// to the tab panel.
	// This is a shorthand for
	// 		Add(NewLabel(tab), content)
	AddString(tab string, content Comp)

	// Selected returns the selected tab idx.
	// Returns -1 if no tab is selected.
	Selected() int

	// PrevSelected returns the previous selected tab idx.
	// Returns -1 if no tab was previously selected.
	PrevSelected() int

	// SetSelected sets the selected tab idx.
	// If idx < 0, no tabs will be selected.
	// If idx > CompsCount(), this is a no-op.
	SetSelected(idx int)
}

TabPanel interface defines a PanelView which has multiple child components but only one is visible at a time. The visible child can be visually selected using an internal TabBar component.

Both the tab panel and its internal tab bar component are PanelViews. This gives high layout configuration possibilities. Usually you only need to set the tab bar placement with the SetTabBarPlacement() method which also sets other reasonable internal layout defaults. But you have many other options to override the layout settings. If the content component is bigger than the tab bar, you can set the tab bar horizontal and the vertical alignment, e.g. with the TabBar().SetAlignment() method. To apply cell formatting to individual content components, you can simply use the CellFmt() method. If the tab bar is bigger than the content component, you can set the content alignment, e.g. with the SetAlignment() method. You can also set different alignments for individual tab components using TabBar().CellFmt(). You can also set other cell formatting applied to the tab bar using TabBarFmt() method.

You can register ETypeStateChange event handlers which will be called when the user changes tab selection by clicking on a tab. The event source will be the tab panel. The event will have a parent event whose source will be the clicked tab and will contain the mouse coordinates.

Default style classes: "gwu-TabPanel", "gwu-TabPanel-Content"

func NewTabPanel

func NewTabPanel() TabPanel

NewTabPanel creates a new TabPanel. Default tab bar placement is TbPlacementTop, default horizontal alignment is HADefault, default vertical alignment is VADefault.

type Table

type Table interface {
	// Table is a TableView.
	TableView

	// EnsureSize ensures that the table will have at least the specified
	// rows, and at least the specified columns in rows whose index is < rows.
	EnsureSize(rows, cols int)

	// EnsureCols ensures that the table will have at least the specified
	// cols at the specified row.
	// This implicitly includes that the table must have at least (row+1) rows.
	// If the table have less than (row+1) rows, empty rows will be added first.
	EnsureCols(row, cols int)

	// CompsCount returns the number of components added to the table.
	CompsCount() int

	// CompAt returns the component at the specified row and column.
	// Returns nil if row or column are invalid.
	CompAt(row, col int) Comp

	// CompIdx returns the row and column of the specified component in the table.
	// (-1, -1) is returned if the component is not added to the table.
	CompIdx(c Comp) (row, col int)

	// RowFmt returns the row formatter of the specified table row.
	// If the table does not have a row specified by row, nil is returned.
	RowFmt(row int) CellFmt

	// CellFmt returns the cell formatter of the specified table cell.
	// If the table does not have a cell specified by row and col,
	// nil is returned.
	CellFmt(row, col int) CellFmt

	// Add adds a component to the table.
	// Return value indicates if the component was added successfully.
	// Returns false if row or col is negative.
	Add(c Comp, row, col int) bool

	// RowSpan returns the row span of the specified table cell.
	// -1 is returned if the table does not have a cell specified by row and col.
	RowSpan(row, col int) int

	// SetRowSpan sets the row span of the specified table cell.
	// If the table does not have a cell specified by row and col,
	// this is a no-op.
	SetRowSpan(row, col, rowSpan int)

	// ColSpan returns the col span of the specified table cell.
	// -1 is returned if the table does not have a cell specified by row and col.
	ColSpan(row, col int) int

	// SetColSpan sets the col span of the specified table cell.
	// If the table does not have a cell specified by row and col,
	// this is a no-op.
	SetColSpan(row, col, colSpan int)

	// Trim trims all the rows: removes trailing cells that has nil component
	// by making the rows shorter.
	// This comes handy for example if the table contains cells where colspan > 1 is set;
	// by calling this method we can ensure no empty cells will be rendered at the end of such rows.
	Trim()

	// TrimRow trims the specified row: removes trailing cells that has nil value
	// by making the row shorter.
	TrimRow(row int)
}

Table interface defines a container which lays out its children using a configurable, flexible table. The size of the table grows dynamically, on demand. However, if table size is known or can be guessed before/during building it, it is recommended to call EnsureSize to minimize reallocations in the background.

Default style class: "gwu-Table"

func NewTable

func NewTable() Table

NewTable creates a new Table. Default horizontal alignment is HADefault, default vertical alignment is VADefault.

type TableView

type TableView interface {
	// TableView is a Container.
	Container

	// Border returns the border width of the table.
	Border() int

	// SetBorder sets the border width of the table.
	SetBorder(width int)

	// TableView has horizontal and vertical alignment.
	// This is the default horizontal and vertical alignment for
	// all children inside their enclosing cells.
	HasHVAlign

	// CellSpacing returns the cell spacing.
	CellSpacing() int

	// SetCellSpacing sets the cell spacing.
	// Has no effect if layout is LayoutNatural.
	SetCellSpacing(spacing int)

	// CellPadding returns the cell spacing.
	CellPadding() int

	// SetCellPadding sets the cell padding.
	// Has no effect if layout is LayoutNatural.
	SetCellPadding(padding int)
}

TableView interface defines a component which is rendered into a table.

type TextBox

type TextBox interface {
	// TextBox is a component.
	Comp

	// TextBox has text.
	HasText

	// TextBox can be enabled/disabled.
	HasEnabled

	// ReadOnly returns if the text box is read-only.
	ReadOnly() bool

	// SetReadOnly sets if the text box is read-only.
	SetReadOnly(readOnly bool)

	// Rows returns the number of displayed rows.
	Rows() int

	// SetRows sets the number of displayed rows.
	// rows=1 will make this a simple, one-line input text box,
	// rows>1 will make this a text area.
	SetRows(rows int)

	// Cols returns the number of displayed columns.
	Cols() int

	// SetCols sets the number of displayed columns.
	SetCols(cols int)

	// MaxLength returns the maximum number of characters
	// allowed in the text box.
	// -1 is returned if there is no maximum length set.
	MaxLength() int

	// SetMaxLength sets the maximum number of characters
	// allowed in the text box.
	// Pass -1 to not limit the maximum length.
	SetMaxLength(maxLength int)
}

TextBox interface defines a component for text input purpose.

Suggested event type to handle actions: ETypeChange

By default the value of the TextBox is synchronized with the server on ETypeChange event which is when the TextBox loses focus or when the ENTER key is pressed. If you want a TextBox to synchronize values during editing (while you type in characters), add the ETypeKeyUp event type to the events on which synchronization happens by calling:

AddSyncOnETypes(ETypeKeyUp)

Default style class: "gwu-TextBox"

Example

Example code determining what kind of key is involved.

package main

import (
	"github.com/icza/gowut/gwu"
)

func main() {
	b := gwu.NewTextBox("")
	b.AddSyncOnETypes(gwu.ETypeKeyUp) // This is here so we will see up-to-date value in the event handler
	b.AddEHandlerFunc(func(e gwu.Event) {
		if e.ModKey(gwu.ModKeyShift) {
			// SHIFT is pressed
		}

		c := e.KeyCode()
		switch {
		case c == gwu.KeyEnter: // Enter
		case c >= gwu.Key0 && c <= gwu.Key9:
			fallthrough
		case c >= gwu.KeyNumpad0 && c <= gwu.KeyNumpad9: // Number
		case c >= gwu.KeyA && c <= gwu.KeyZ: // Letter
		case c >= gwu.KeyF1 && c <= gwu.KeyF12: // Function key
		}
	}, gwu.ETypeKeyUp)
}
Output:

func NewPasswBox

func NewPasswBox(text string) TextBox

NewPasswBox creates a new PasswBox.

func NewTextBox

func NewTextBox(text string) TextBox

NewTextBox creates a new TextBox.

type Timer

type Timer interface {
	// Timer is a component.
	Comp

	// Timeout returns the timeout duration of the timer.
	Timeout() time.Duration

	// SetTimeout sets the timeout duration of the timer.
	// Event will be generated after the timeout period. If timer is on repeat,
	// events will be generated periodically after each timeout.
	//
	// Note: while this method allows you to pass an arbitrary time.Duration,
	// implementation might be using less precision (most likely millisecond).
	// Durations less than 1 ms might be rounded up to 1 ms.
	SetTimeout(timeout time.Duration)

	// Repeat tells if the timer is on repeat.
	Repeat() bool

	// SetRepeat sets if the timer is on repeat.
	// If timer is on repeat, events will be generated periodically after
	// each timeout.
	SetRepeat(repeat bool)

	// Active tells if the timer is active.
	Active() bool

	// SetActive sets if the timer is active.
	// If the timer is not active, events will not be generated.
	// If a timer is deactivated and activated again, its countdown is reset.
	SetActive(active bool)

	// Reset will cause the timer to restart/reschedule.
	// A Timer does not reset the countdown when it is re-rendered,
	// only if the timer config is changed (e.g. timeout or repeat).
	// By calling Reset() the countdown will reset when the timer is
	// re-rendered.
	Reset()
}

Timer interface defines a component which can generate a timed event or a series of timed events periodically.

Timers don't have a visual part, they are used only to generate events. The generated events are of type ETypeStateChange.

Note that receiving an event from a Timer (like from any other components) updates the last accessed property of the associated session, causing a session never to expire if there are active timers on repeat at the client side.

Also note that the Timer component operates at the client side meaning if the client is closed (or navigates away), events will not be generated. (This can also be used to detect if a Window is still open.)

func NewTimer

func NewTimer(timeout time.Duration) Timer

NewTimer creates a new Timer. By default the timer is active and does not repeat.

type VAlign

type VAlign string

VAlign is the vertical alignment type.

type WinSlice

type WinSlice []Window

WinSlice is a slice of windows which implements sort.Interface so it can be sorted by window text (title).

func (WinSlice) Len

func (w WinSlice) Len() int

func (WinSlice) Less

func (w WinSlice) Less(i, j int) bool

func (WinSlice) Swap

func (w WinSlice) Swap(i, j int)

type Window

type Window interface {
	// Window is a Panel, child components can be added to it.
	Panel

	// A window has text which will be used as the title
	// of the browser window.
	HasText

	// Name returns the name of the window.
	// The name appears in the URL.
	Name() string

	// SetName sets the name of the window.
	SetName(name string)

	// AddHeadHTML adds an HTML text which will be included
	// in the HTML <head> section.
	AddHeadHTML(html string)

	// RemoveHeadHTML removes an HTML head text
	// that was previously added with AddHeadHtml().
	RemoveHeadHTML(html string)

	// SetFocusedCompID sets the ID of the currently focused component.
	SetFocusedCompID(id ID)

	// Theme returns the CSS theme of the window.
	// If an empty string is returned, the server's theme will be used.
	Theme() string

	// SetTheme sets the default CSS theme of the window.
	// If an empty string is set, the server's theme will be used.
	SetTheme(theme string)

	// RenderWin renders the window as a complete HTML document.
	RenderWin(w Writer, s Server)
}

The Window interface is the top of the component hierarchy. A Window defines the content seen in the browser window. Multiple windows can be created, but only one is visible at a time in the browser. The Window interface is the equivalent of the browser page.

Default style class: "gwu-Window"

func NewWindow

func NewWindow(name, text string) Window

NewWindow creates a new window. The default layout strategy is LayoutVertical.

type Writer

type Writer interface {
	io.Writer // Writer is an io.Writer

	// Writev writes a value. It is highly optimized for certain values/types.
	// Supported value types are string, int, []byte, bool.
	Writev(v interface{}) (n int, err error)

	// Writevs writes values. It is highly optimized for certain values/types.
	// For supported value types see Writev().
	Writevs(v ...interface{}) (n int, err error)

	// Writes writes a string.
	Writes(s string) (n int, err error)

	// Writess writes strings.
	Writess(ss ...string) (n int, err error)

	// Writees writes a string after html-escaping it.
	Writees(s string) (n int, err error)

	// WriteAttr writes an attribute in the form of:
	// ` name="value"`
	WriteAttr(name, value string) (n int, err error)
}

Writer is an improved and optimized io.Writer with additionial helper methods to easier write data we need to render components.

func NewWriter

func NewWriter(w io.Writer) Writer

NewWriter returns a new Writer, wrapping the specified io.Writer.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL