User interface toolkit for Go with support for SDL2 and HTML Canvas render targets.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
Noah Petherbridge b7190fe958 Frame: do not draw hidden widgets il y a 4 mois
docs Menus and Menu Bars il y a 11 mois
eg WIP Themes Support il y a 10 mois
style WIP Themes Support il y a 10 mois
theme WIP Themes Support il y a 10 mois
.gitignore Window Manager Buttons and Bugfixes il y a 1 an
LICENSE.md Add README, LICENSE and Examples il y a 1 an
README.md Add the Pager Widget il y a 10 mois
button.go WIP Themes Support il y a 10 mois
check_button.go CheckButton Styles, Supervisor fixes il y a 10 mois
checkbox.go Window Manager Basics, Work in Progress il y a 1 an
debug.go Menus and Menu Bars il y a 11 mois
docs.go Add version number and documentation il y a 1 an
dragdrop.go Window Manager Basics, Work in Progress il y a 1 an
enums.go Tooltip Widget and Event Refactor il y a 1 an
frame.go Frame: do not draw hidden widgets il y a 4 mois
frame_pack.go Tooltip Widget and Event Refactor il y a 1 an
frame_place.go Tooltip Widget and Event Refactor il y a 1 an
functions.go Menus and Menu Bars il y a 11 mois
go.mod CheckButton Styles, Supervisor fixes il y a 10 mois
go.sum CheckButton Styles, Supervisor fixes il y a 10 mois
image.go Tooltip Widget and Event Refactor il y a 1 an
label.go WIP Themes Support il y a 10 mois
main_window.go Window Manager Buttons and Bugfixes il y a 1 an
menu.go Menus and Menu Bars il y a 11 mois
menu_bar.go Menus and Menu Bars il y a 11 mois
menu_button.go Menus and Menu Bars il y a 11 mois
menu_test.go Menus and Menu Bars il y a 11 mois
pager.go Add MaxPageButtons to the Pager widget il y a 5 mois
supervisor.go CheckButton Styles, Supervisor fixes il y a 10 mois
theme.go WIP Themes Support il y a 10 mois
tooltip.go WIP Themes Support il y a 10 mois
tooltip_test.go Add version number and documentation il y a 1 an
version.go Add version number and documentation il y a 1 an
widget.go Menus and Menu Bars il y a 11 mois
window.go Add Size() method to ui.Window that returns the window body size il y a 5 mois
window_manager.go Menus and Menu Bars il y a 11 mois
window_test.go Window Manager Buttons and Bugfixes il y a 1 an

README.md

ui: User Interface Toolkit for Go

GoDoc

Package ui is a user interface toolkit for Go that targets desktop applications (SDL2, for Linux, MacOS and Windows) as well as web browsers (WebAssembly rendering to an HTML Canvas).

Screenshot

(Screenshot is from Project: Doodle’s GUITest debug screen showing a Window, several Frames, Labels, Buttons and a Checkbox widget.)

It is very much a work in progress and may contain bugs and its API may change as bugs are fixed or features added.

This library is being developed in conjunction with my drawing-based maze game, Project: Doodle. The rendering engine library is at go/render which provides the SDL2 and Canvas back-ends. (GitHub mirror: kirsle/render)

Notice: the canonical source repository for this project is at git.kirsle.net/go/ui with a mirror available on GitHub at kirsle/ui. Issues and pull requests are accepted on GitHub.

Example

package main

import (
    "fmt"

    "git.kirsle.net/go/render"
    "git.kirsle.net/go/ui"
)

func main() {
    mw, err := ui.NewMainWindow("Hello World")
    if err != nil {
        panic(err)
    }

    mw.SetBackground(render.White)

    // Draw a label.
    label := ui.NewLabel(ui.Label{
        Text: "Hello, world!",
        Font: render.Text{
            FontFilename: "../DejaVuSans.ttf",
            Size:         32,
            Color:        render.SkyBlue,
            Shadow:       render.SkyBlue.Darken(40),
        },
    })
    mw.Pack(label, ui.Pack{
        Side: ui.N,
        PadY:   12,
    })

    // Draw a button.
    button := ui.NewButton("My Button", ui.NewLabel(ui.Label{
        Text: "Click me!",
        Font: render.Text{
            FontFilename: "../DejaVuSans.ttf",
            Size:         12,
            Color:        render.Red,
            Padding:      4,
        },
    }))
    button.Handle(ui.Click, func(p render.Point) {
        fmt.Println("I've been clicked!")
    })
    mw.Pack(button, ui.Pack{
        Side: ui.N,
    })

    // Add a mouse-over tooltip to the button.
    ui.NewTooltip(button, ui.Tooltip{
        Text: "You know you want to click this button",
        Edge: ui.Right,
    })

    mw.MainLoop()
}

Widgets and Features

The following widgets have been implemented or are planned for the future.

Widgets are designed to be composable, making use of pre-existing widgets to create more complex ones. The widgets here are ordered from simplest to most complex.

Fully implemented widgets:

Work in progress widgets:

Wish list for the longer-term future:

Supervisor for Interaction

Some widgets that support user interaction (such as Button, CheckButton and Checkbox) need to be added to the Supervisor which watches over them and communicates events that they’re interested in.

func SupervisorSDL2Example() {
    // NOTE: using the render/sdl engine.
    window := sdl.New("Hello World", 800, 600)
    window.Setup()

    // One Supervisor is needed per UI.
    supervisor := ui.NewSupervisor()

    // A button for our UI.
    btn := ui.NewButton("Button1", ui.NewLabel(ui.Label{
        Text: "Click me!",
    }))

    // Add it to the Supervisor.
    supervisor.Add(btn)

    // Main loop
    for {
        // Check for keyboard/mouse events
        ev, _ := window.Poll()

        // Ping the Supervisor Loop function with the event state, so
        // it can trigger events on the widgets under its care.
        supervisor.Loop(ev)
    }
}

You only need one Supervisor instance per UI. Add() each interactive widget to it, and call its Loop() method in your main loop so it can update the state of the widgets under its care.

The MainWindow includes its own Supervisor, see below.

Window Manager

The ui.Window widget provides a simple frame with a title bar. But, you can use the Supervisor to provide Window Manager controls to your windows!

The key steps to convert a static Window widget into one that can be dragged around by its title bar are:

  1. Call window.Supervise(ui.Supervisor) and give it your Supervisor. It will register itself to be managed by the Supervisor.
  2. In your main loop, call Supervisor.Loop() as you normally would. It handles sending mouse and keyboard events to all managed widgets, including the children of the managed windows.
  3. In the “draw” part of your main loop, call Supervisor.Present() as the final step. Supervisor will draw the managed windows on top of everything else, with the current focused window on top of the others. Note: managed windows are the only widgets drawn by Supervisor; other widgets should be drawn by their parent widgets in their respective Present() methods.

You can also customize the colors and title bar controls of the managed windows.

Example:

func example() {
    engine, _ := sdl.New("Example", 800, 600)
    supervisor := ui.NewSupervisor()

    win := ui.NewWindow("My Window")

    // Customize the colors of the window. Here are the defaults:
    win.ActiveTitleBackground = render.Blue
    win.ActiveTitleForeground = render.White
    win.InactiveTitleBackground = render.DarkGrey
    win.InactiveTitleForeground = render.Grey

    // Customize the window buttons by ORing the options.
    // NOTE: Maximize behavior is still a work in progress, the window doesn't
    //       redraw itself at the new size correctly yet.
    // NOTE: Minimize button has no default behavior but does trigger a
    //       MinimizeWindow event that you can handle yourself.
    win.SetButtons(ui.CloseButton | ui.MaximizeButton | ui.MinimizeButton)

    // Add widgets to your window.
    label := ui.NewLabel(ui.Label{
       Text: "Hello world!",
    })
    win.Pack(label, ui.Pack{
        Side: ui.W,
    })

    // Compute the window and its children.
    win.Compute(engine)

    // This is the key step: give the window to the Supervisor.
    win.Supervise(supervisor)

    // And in your main loop:
    // NOTE: MainWindow.MainLoop() does this for you automatically.
    for {
        ev, _ = engine.Poll()  // poll render engine for mouse/keyboard events
        supervisor.Loop(ev)
        supervisor.Present(engine)
    }
}

See the eg/windows/ example in the git repository for a full example, including SDL2 and WebAssembly versions.

MainWindow for Simple Applications

The MainWindow widget may be used for “simple” UI applications where all you want is a GUI and you don’t want to manage your own SDL2 (or Canvas) engine.

MainWindow is only to be used one time per application, and it sets up its own SDL2 render context and creates the main window. It also contains a Frame widget for the window contents and you may Pack() widgets into the window the same as you would a Frame.

MainWindow includes its own Supervisor: just call the .Add(Widget) method to add interactive widgets to the supervisor. The MainLoop() of the window calls Supervisor.Loop() automatically.

License

MIT.