Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"files.associations": {
"lv_style.h": "c"
}
}
100 changes: 100 additions & 0 deletions lvgl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# LVGL Go Bindings

This package provides Go bindings for the LVGL graphics library, allowing you to create embedded GUI applications using Go.

## Prerequisites

Before using these bindings, you need to install the required dependencies:

1. Install SDL2 (for simulator support):
```bash
# macOS
brew install sdl2

# Ubuntu/Debian
sudo apt-get install libsdl2-dev

# Fedora
sudo dnf install SDL2-devel
```

## Installation

1. Clone the LVGL C library:
```bash
mkdir ext
cd ext/
git clone git@github.com:lvgl/lvgl.git
cd ../
```

2. Build the LVGL library:
```bash
sh scripts/build_lvgl.sh
```

## Usage

Here's a simple example of how to use the LVGL Go bindings:

```go
package main

import (
"github.com/yourusername/llgo/c/lvgl/display"
"github.com/yourusername/llgo/c/lvgl/widgets"
"time"
)

func main() {
// Initialize display
disp := display.LvDisplayCreate(800, 480)
display.LvDisplaySetDefault(disp)

// Create a label
label := widgets.LvLabelCreate(display.LvScreenActive())
widgets.LvLabelSetText(label, "Hello, LVGL from Go!")

// Main loop
for {
// Handle LVGL tasks
// ...
time.Sleep(10 * time.Millisecond)
}
}
```

## API Documentation

The Go bindings follow the same API structure as the original LVGL C library, with the following naming conventions:

- C function `lv_display_create` becomes Go function `display.LvDisplayCreate`
- C function `lv_label_set_text` becomes Go function `widgets.LvLabelSetText`

For detailed API documentation, refer to the [LVGL documentation](https://docs.lvgl.io/).

## Building for Different Platforms

### Desktop Simulator

The default build targets the desktop simulator using SDL2, which is useful for development and testing.

### Embedded Targets

To build for embedded targets, you'll need to:

1. Set up the appropriate cross-compiler for your target platform
2. Modify the build scripts to use the cross-compiler
3. Implement the appropriate display and input drivers for your hardware

## Contributing

Contributions to improve these Go bindings are welcome! Please feel free to submit issues and pull requests.

## License

This project is licensed under the MIT License - see the LICENSE file for details.




129 changes: 129 additions & 0 deletions lvgl/_demo/example/assert/img_cogwheel_argb.go

Large diffs are not rendered by default.

Binary file added lvgl/_demo/example/assert/img_cogwheel_argb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions lvgl/_demo/example/demo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package main

import (
"log"
"time"

"github.com/goplus/llgo/c"
"github.com/goplus/llpkg/lvgl"
"github.com/goplus/llpkg/lvgl/drivers/sdl"
)

func main() {
// Initialize LVGL
lvgl.LvglInit()

// Create a display
disp := sdl.LvSdlWindowCreate(480, 320)
sdl.LvSdlMouseCreate()
sdl.LvSdlKeyboardCreate()

sdl.LvSdlWindowSetZoom(disp, 1.0)
sdl.LvSdlWindowSetTitle(disp, c.Str("Profile Page"))
log.Println("disp", disp)

//lv_example_style_1() // 背景
//lv_example_style_2() // 渐变 -- 有问题
//lv_example_style_3() // 边框
//lv_example_style_4() // 轮廓
//lv_example_style_5() // 阴影
//lv_example_style_6() // 图片
lv_example_get_started_2() // 按钮
//lv_example_get_started_3() // 滑块
//lv_example_get_started_4() // 标签
//lv_example_anim_1() // 动画
// Main event loop
for {
lvgl.LvTimerHandler()
time.Sleep(time.Millisecond * 5)
}
}
56 changes: 56 additions & 0 deletions lvgl/_demo/example/lv_example_anim_1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package main

import (
"log"

"github.com/goplus/llgo/c"
"github.com/goplus/llpkg/lvgl/core"
"github.com/goplus/llpkg/lvgl/display"
"github.com/goplus/llpkg/lvgl/widgets"
)

func anim_x_cb(var_ c.Pointer, v int32) {
obj := (*core.LvObjT)(var_)
core.LvObjSetX(obj, c.Int32T(v))
}

func sw_event_cb(e *core.LvEventT) {
log.Println("sw_event_cb")
sw := (*core.LvObjT)(core.LvEventGetTarget(e))
label := (*core.LvObjT)(core.LvEventGetUserData(e))

if core.LvObjHasState(sw, (core.LvStateT)(core.LV_STATE_CHECKED)) {
a := core.LvAnimT{}
core.LvAnimInit(&a)
core.LvAnimSetVar(&a, label)
core.LvAnimSetValues(&a, core.LvObjGetX(label), 100)
core.LvAnimSetDuration(&a, 500)
core.LvAnimSetExecCb(&a, anim_x_cb)
core.LvAnimSetPathCb(&a, core.LvAnimPathOvershoot)
core.LvAnimStart(&a)
} else {
a := core.LvAnimT{}
core.LvAnimInit(&a)
core.LvAnimSetVar(&a, label)
core.LvAnimSetValues(&a, core.LvObjGetX(label), -core.LvObjGetWidth(label))
core.LvAnimSetDuration(&a, 500)
core.LvAnimSetExecCb(&a, anim_x_cb)
core.LvAnimSetPathCb(&a, core.LvAnimPathEaseIn)
core.LvAnimStart(&a)
}
}

/**
* Start animation on an event
*/
func lv_example_anim_1() {
label := widgets.LvLabelCreate(display.LvScreenActive())
widgets.LvLabelSetText(label, c.Str("Hello animations!"))
core.LvObjSetPos(label, 100, 10)

sw := widgets.LvSwitchCreate(display.LvScreenActive())
core.LvObjCenter(sw)
core.LvObjAddState(sw, core.LV_STATE_CHECKED)
core.LvObjAddEventCb(sw, sw_event_cb, core.LV_EVENT_VALUE_CHANGED, (c.Pointer)(label))

}
43 changes: 43 additions & 0 deletions lvgl/_demo/example/lv_example_get_started_2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package main

import (
"unsafe"

"github.com/goplus/llgo/c"
"github.com/goplus/llpkg/lvgl/core"
"github.com/goplus/llpkg/lvgl/display"
"github.com/goplus/llpkg/lvgl/widgets"
)

//var cnt uint8 = 0

func btn_event_cb(e *core.LvEventT) {
code := core.LvEventGetCode(e)
btn := core.LvEventGetTarget(e)
//fmt.Println("code", code)
if code == core.LV_EVENT_CLICKED {

//cnt++
/*Get the first child of the button which is the label and change its text*/
label := core.LvObjGetChild((*core.LvObjT)(unsafe.Pointer(btn)), 0)

// btnstr := fmt.Sprintf("Button: %d", cnt)
// c.Str(btnstr)

widgets.LvLabelSetTextFmt(label, c.Str("test"))
}
}

/**
* Create a button with a label and react on click event.
*/
func lv_example_get_started_2() {
btn := widgets.LvButtonCreate(display.LvScreenActive()) /*Add a button the current screen*/
core.LvObjSetPos(btn, 10, 10) /*Set its position*/
core.LvObjSetSize(btn, 120, 50) /*Set its size*/
core.LvObjAddEventCb(btn, btn_event_cb, core.LV_EVENT_ALL, nil) /*Assign a callback to the button*/

label := widgets.LvLabelCreate(btn) /*Add a label to the button*/
widgets.LvLabelSetText(label, c.Str("Button")) /*Set the labels text*/
core.LvObjCenter(label)
}
84 changes: 84 additions & 0 deletions lvgl/_demo/example/lv_example_get_started_3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package main

import (
"github.com/goplus/llgo/c"
"github.com/goplus/llpkg/lvgl/core"
"github.com/goplus/llpkg/lvgl/display"
"github.com/goplus/llpkg/lvgl/widgets"
)

var styleBtn core.LvStyleT
var styleButtonPressed core.LvStyleT
var styleButtonRed core.LvStyleT

func darken(dsc *core.LvColorFilterDscT, color core.LvColorT, opa core.LvOpaT) core.LvColorT {
// LV_UNUSED(dsc) in Go we just don't use the parameter
return core.LvColorDarken(color, opa)
}

func styleInit() {
/*Create a simple button style*/
core.LvStyleInit(&styleBtn)
core.LvStyleSetRadius(&styleBtn, 10)
core.LvStyleSetBgOpa(&styleBtn, core.LV_OPA_COVER)
core.LvStyleSetBgColor(&styleBtn, core.LvPaletteLighten(core.LV_PALETTE_GREY, c.Uint8T(3)))
core.LvStyleSetBgGradColor(&styleBtn, core.LvPaletteMain(core.LV_PALETTE_GREY))
core.LvStyleSetBgGradDir(&styleBtn, core.LV_GRAD_DIR_VER)

core.LvStyleSetBorderColor(&styleBtn, core.LvColorBlack())
core.LvStyleSetBorderOpa(&styleBtn, core.LV_OPA_20)
core.LvStyleSetBorderWidth(&styleBtn, c.Int(2))

core.LvStyleSetTextColor(&styleBtn, core.LvColorBlack())

/*Create a style for the pressed state.
*Use a color filter to simply modify all colors in this state*/
var colorFilter core.LvColorFilterDscT
core.LvColorFilterDscInit(&colorFilter, darken)
core.LvStyleInit(&styleButtonPressed)
core.LvStyleSetColorFilterDsc(&styleButtonPressed, &colorFilter)
core.LvStyleSetColorFilterOpa(&styleButtonPressed, core.LV_OPA_20)

/*Create a red style. Change only some colors.*/
core.LvStyleInit(&styleButtonRed)
core.LvStyleSetBgColor(&styleButtonRed, core.LvPaletteMain(core.LV_PALETTE_RED))
core.LvStyleSetBgGradColor(&styleButtonRed, core.LvPaletteLighten(core.LV_PALETTE_RED, 3))
}

/**
* Create core from scratch for buttons.
*/
func lv_example_get_started_3() {
/*Initialize the style*/
styleInit()

/*Create a button and use the new core*/
btn := widgets.LvButtonCreate(display.LvScreenActive())
/* Remove the core coming from the theme
* Note that size and position are also stored as style properties
* so lv_obj_remove_style_all will remove the set size and position too */
core.LvObjRemoveStyleAll(btn)
core.LvObjSetPos(btn, 10, 10)
core.LvObjSetSize(btn, 120, 50)
core.LvObjAddStyle(btn, &styleBtn, 0)
core.LvObjAddStyle(btn, &styleButtonPressed, core.LV_STATE_PRESSED)

/*Add a label to the button*/
label := widgets.LvLabelCreate(btn)
widgets.LvLabelSetText(label, c.Str("Button"))
core.LvObjCenter(label)

/*Create another button and use the red style too*/
btn2 := widgets.LvButtonCreate(display.LvScreenActive())
core.LvObjRemoveStyleAll(btn2) /*Remove the core coming from the theme*/
core.LvObjSetPos(btn2, 10, 80)
core.LvObjSetSize(btn2, 120, 50)
core.LvObjAddStyle(btn2, &styleBtn, 0)
core.LvObjAddStyle(btn2, &styleButtonRed, 0)
core.LvObjAddStyle(btn2, &styleButtonPressed, core.LV_STATE_PRESSED)
core.LvObjSetStyleRadius(btn2, c.Int32T(core.LV_RADIUS_CIRCLE), 0) /*Add a local style too*/

label = widgets.LvLabelCreate(btn2)
widgets.LvLabelSetText(label, c.Str("Button 2"))
core.LvObjCenter(label)
}
34 changes: 34 additions & 0 deletions lvgl/_demo/example/lv_example_get_started_4.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package main

import (
"github.com/goplus/llgo/c"
"github.com/goplus/llpkg/lvgl/core"
"github.com/goplus/llpkg/lvgl/display"
"github.com/goplus/llpkg/lvgl/widgets"
)

var label *core.LvObjT

func slider_event_cb(e *core.LvEventT) {
slider := core.LvEventGetTarget(e)

/*Refresh the text*/
widgets.LvLabelSetTextFmt(label, c.Str("%d"), widgets.LvSliderGetValue((*core.LvObjT)(slider)))
core.LvObjAlignTo(label, (*core.LvObjT)(slider), core.LV_ALIGN_OUT_TOP_MID, 0, -15) /*Align top of the slider*/
}

/**
* Create a slider and write its value on a label.
*/
func lv_example_get_started_4() {
/*Create a slider in the center of the display*/
slider := widgets.LvSliderCreate(display.LvScreenActive())
core.LvObjSetWidth(slider, 200) /*Set the width*/
core.LvObjCenter(slider) /*Align to the center of the parent (screen)*/
core.LvObjAddEventCb(slider, slider_event_cb, core.LV_EVENT_VALUE_CHANGED, nil) /*Assign an event function*/

/*Create a label above the slider*/
label = widgets.LvLabelCreate(display.LvScreenActive())
widgets.LvLabelSetText(label, c.Str("0"))
core.LvObjAlignTo(label, slider, core.LV_ALIGN_OUT_TOP_MID, 0, -15) /*Align top of the slider*/
}
Loading
Loading