impress.Application
is the basic struct of a GUI application. It defines the edges of the main rectangle, is a source of events from a user, and includes other functionalities under the hood.
To create an impress.Application
and close it:
app := impress.NewApplication(image.Rect(0, 0, 640, 480), "Main")
defer app.Close()
image.Rect()
specifies the coordinates of the main window. A rectangle contains the upper left corner (x = 0, y = 0) and the bottom right corner (x = 640, y = 480) coordinates. x
points to a column in pixels (from left to right), and y
points to a row (from top to bottom). The "Main" string is the window title.
app.Close()
at the end will hide the application window and perform necessary cleanup.
The app.Sync()
should finalize drawing calls.
app.Sync()
One more thing. We plan to wait until the user destroys something in the application:
for {
e := <-app.Chan()
if e == event.DestroyEvent || e == event.KeyExit {
break
}
}
Where e := <-app.Chan()
is an event like a mouse event, keyboard event, etc. app.Chan()
returns an event channel, by the way.
By default, all event types are sent to the event channel, no configuration is required. See documentation for event types and parameters.
A window is a rectangular space for drawing. The app.NewWindow()
parameters are the size and background color, for example:
w := app.NewWindow(image.Rect(0, 0, 320, 480), color.RGBA{255, 255, 255, 255})
defer w.Drop()
First, image.Rect
specifies a place within the application's bounds. Values of color.RGBA
are RGBA, as always 0..255 each.
Typically, an application opens and closes many windows during its lifetime. w.Drop()
is necessary to hide the window and release its resources.
In a real application, sizes and colors already exist inside the styles and palettes configuration. But in this example, they are created anew.
See example.
The GUI application redraws its state to keep the user in touch. The application receives events. An event can change the state of an application. And again, and again.
In general, the event loop looks like this:
for {
if len(app.Chan()) == 0 {
redrawAppState()
app.Sync()
}
e := <- app.Chan()
if isExitAppEvent(e) {
return
}
changeAppState(e)
}
len(app.Chan()) == 0
checks if a new event has arrived. There is no need to draw every intermediate state of the application if there is a new event. It is okay to draw the last state when the user quickly types a lot of characters.
Inside redrawAppState()
, application windows must be redrawn. No redraws are required if the state of the application remains the same.
The app.Sync()
should finalize the sequence of drawing calls. The last draw calls will wait forever in library buffers without app.Sync()
.
The event loop continues forever until the user closes the application. isExitAppEvent(e)
checks if the event caused the application to quit immediately.
If the application continues to run, then it's time to change the application's state in changeAppState(e)
. The state of the application may remain the same if it is a useless event.
See Recommended event propagation module.
A window is created to draw something to inform the user. The contents of the window may change from time to time.
To clear the previous contents of a window, call the Clear()
method.
You can draw lines, solid rectangles, text strings, or images. The element is drawn on top of the previous ones, so keep the correct drawing order.
The font for drawing a text string must be opened before and destroyed after everything. Font attributes such as font family and height can be specified upon opening. JSON with font parameters depends on the platform. The config file is a perfect place for font options like {"family": "Sans", "style": "italic", "variant": "normal", "weight": "bold", "stretch": "condensed"}
.
The image to draw must be opened before and destroyed after. Since an image takes up a lot of memory, destroy unused images as soon as possible.
To make the content visible, call the Show()
method after the window's content is ready.
There is no need to touch the contents of the window if the drawing should be the same. The library implements lazy mode
drawing.
To change the window position, call the Size()
method. This call does not change the contents of the window.
The created window is drawn on top of previous windows. To move any window on top, call the Raise()
method. This call does not change the contents of the window.
See the examples folder and documentation.