Skip to content

Instantly share code, notes, and snippets.

ui library implementation information

All platform-specific functionality is isolated in a mega-type sysData that stores OS toolkit handles and provides methods that do the work for the frontend API. The file sysdata.go defines a type cSysData that contains everything all platforms have in common and dummy definitions of the sysData functions that panic.

The key sysData function is sysData.make(). It takes two arguments: the initial text of the control (if any), and a pointer to a sysData that represents the window that holds the control. If this pointer is nil, we are creating a window instead, so any window-specific actions are taken here.

cSysData contains the control type as a number, an event channel where the object's standard event (close button for Window, click for Button, etc.) is stored, and a resize() function variable that is called to resize child controls on window resize.

Controls need only two functions: a make() function that builds the control, and a `setRe

A Stack is a stack of controls arranged horizontally or vertically. If horizontal, all controls take the same heights, and use their preferred widths. If vertical, all controls take the same widths, and use their preferred heights.

PROBLEM We want to have controls that stretch with the window SOLUTION Delegate one control as the "stretchy" control. s := NewVerticalStack(c1, c2, c3) s.SetStretchy(1) // c2

Most GUI toolkits require you to use one thread. It doesn't matter which thread, so long as you only use one thread.

Cocoa, however, absolutely demands you use the very first OS thread created, called the "main thread", and provides no way to change which thread is used.

This basically means that instead of you saying

func main() {
    w := ui.NewWindow(blah blah blah)
    blah blah blah
 for { event loop }

Known To Have Ever Been Built Matrices

For convenience's sake, here are matrices of builds that I have personally done at least once. Each cell represents the run status. These matrices represent builds that I have done at any point in development; it is not a guarantee that the current version works. (I built this list to answer questions of whether or not ui works with a specific configuration.) Only configurations marked with a * are tested during active development.

| 386 | amd64 | arm ----- | ----- | ----- | ----- windows | works on windows; works on wine* | works on windows; fails on wine | (invalid) linux | see table below | see table below | Raspian: works darwin (Mac OS X) | works* (cross-compiled from 64-bit) | works* | (not applicable) dragonfly | untested | untested | ???? freebsd | untested (VM failure) | untested (VM failure) | untested

func (s *sysData) setProgress(percent int) {
ret := make(chan uiret)
defer close(ret)
style := classTypes[s.ctype].style
uitask <- &uimsg{
call: _setWindowLong,
p: []uintptr{
uintptr(s.hwnd),
uintptr(_GWL_STYLE),
uintptr(style | _PBS_MARQUEE),

bold

italic

strong

em

tt

  • 26 June 2014

    • Controls in Windows can now be spaced apart more naturally. Call w.SetSpaced(true) to opt in. Whether this will remain opt-in or whether the name will change is still unknown at this point.
    • There's a new function Layout() which provides high-level layout creation. The function was written by boppreh and details can be found here. Whether this function will stay in the main package or be moved to a subpackage is still unknown.
    • There is now Checkbox.SetChecked() to set the check state of a Checkbox programmatically.
  • 25 June 2014 Labels by default now align themselves relative to the control they are next to. There is a new function NewStandaloneLabel() which returns a label whose text is aligned to the top-left corner of the alloted space regardless.

  • 11 June 2014 I have decided to remove Mac OS X 10.6 support because it's only causing problems for building (and everyone el

@andlabs
andlabs / gist:740e742a28f41b81a7af
Last active August 29, 2015 14:03
Maybe we can salvage concurrent UI after all...

New proposal: rather than have methods do things, have methods create requests to do things.

At the top level, there is a channel ui.Do which accepts the results of setter methods:

ui.Do <- label.SetText("Hello")
ui.Do <- checkbox.SetChecked(true)

Getters, however, are a bit more work. Not only do we need to send a request, we need to get something back from it. So getters will require three lines:

ui

-- import "github.com/andlabs/ui/redo"

Usage

var Do = make(Doer)