mirror of https://github.com/ehang-io/nps
test gui
parent
d930d9f003
commit
90ff08ed98
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
|
@ -0,0 +1,57 @@
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"fyne.io/fyne"
|
||||||
|
)
|
||||||
|
|
||||||
|
func bundleFile(name string, filepath string, f *os.File) {
|
||||||
|
res, err := fyne.LoadResourceFromPath(filepath)
|
||||||
|
if err != nil {
|
||||||
|
fyne.LogError("Unable to load file "+filepath, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = f.WriteString(fmt.Sprintf("var %s = %#v\n", name, res))
|
||||||
|
if err != nil {
|
||||||
|
fyne.LogError("Unable to write to bundled file", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func openFile(filename string) *os.File {
|
||||||
|
os.Remove(filename)
|
||||||
|
_, dirname, _, _ := runtime.Caller(0)
|
||||||
|
f, err := os.Create(path.Join(path.Dir(dirname), filename))
|
||||||
|
if err != nil {
|
||||||
|
fyne.LogError("Unable to open file "+filename, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = f.WriteString("// **** THIS FILE IS AUTO-GENERATED, PLEASE DO NOT EDIT IT **** //\n\npackage data\n\nimport \"fyne.io/fyne\"\n\n")
|
||||||
|
if err != nil {
|
||||||
|
fyne.LogError("Unable to write file "+filename, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
func iconDir() string {
|
||||||
|
_, dirname, _, _ := runtime.Caller(0)
|
||||||
|
return path.Join(path.Dir(dirname), "icons")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
f := openFile("bundled-scene.go")
|
||||||
|
|
||||||
|
bundleFile("fynescenedark", "fyne_scene_dark.png", f)
|
||||||
|
bundleFile("fynescenelight", "fyne_scene_light.png", f)
|
||||||
|
|
||||||
|
f.Close()
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package data
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fyne.io/fyne"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ThemedResource is a resource wrapper that will return an appropriate resource
|
||||||
|
// for the currently selected theme.
|
||||||
|
type ThemedResource struct {
|
||||||
|
dark, light fyne.Resource
|
||||||
|
}
|
||||||
|
|
||||||
|
func isLight() bool {
|
||||||
|
r, g, b, _ := fyne.CurrentApp().Settings().Theme().TextColor().RGBA()
|
||||||
|
return r < 0xaaaa && g < 0xaaaa && b < 0xaaaa
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns the underlying resource name (used for caching)
|
||||||
|
func (res *ThemedResource) Name() string {
|
||||||
|
if isLight() {
|
||||||
|
return res.light.Name()
|
||||||
|
}
|
||||||
|
return res.dark.Name()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Content returns the underlying content of the correct resource for the current theme
|
||||||
|
func (res *ThemedResource) Content() []byte {
|
||||||
|
if isLight() {
|
||||||
|
return res.light.Content()
|
||||||
|
}
|
||||||
|
return res.dark.Content()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewThemedResource creates a resource that adapts to the current theme setting.
|
||||||
|
func NewThemedResource(dark, light fyne.Resource) *ThemedResource {
|
||||||
|
return &ThemedResource{dark, light}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FyneScene contains the full fyne logo with background design
|
||||||
|
var FyneScene = NewThemedResource(fynescenedark, fynescenelight)
|
|
@ -0,0 +1,76 @@
|
||||||
|
// Package main provides various examples of Fyne API capabilities
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"fyne.io/fyne"
|
||||||
|
"fyne.io/fyne/app"
|
||||||
|
"fyne.io/fyne/canvas"
|
||||||
|
"fyne.io/fyne/layout"
|
||||||
|
"fyne.io/fyne/theme"
|
||||||
|
"fyne.io/fyne/widget"
|
||||||
|
"github.com/cnlh/nps/gui/fyne_demo/data"
|
||||||
|
"github.com/cnlh/nps/gui/fyne_demo/screens"
|
||||||
|
)
|
||||||
|
|
||||||
|
const preferenceCurrentTab = "currentTab"
|
||||||
|
|
||||||
|
func welcomeScreen(a fyne.App) fyne.CanvasObject {
|
||||||
|
logo := canvas.NewImageFromResource(data.FyneScene)
|
||||||
|
logo.SetMinSize(fyne.NewSize(228, 167))
|
||||||
|
|
||||||
|
link, err := url.Parse("https://fyne.io/")
|
||||||
|
if err != nil {
|
||||||
|
fyne.LogError("Could not parse URL", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return widget.NewVBox(
|
||||||
|
widget.NewLabelWithStyle("Welcome to the Fyne toolkit demo app", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}),
|
||||||
|
layout.NewSpacer(),
|
||||||
|
widget.NewHBox(layout.NewSpacer(), logo, layout.NewSpacer()),
|
||||||
|
widget.NewHyperlinkWithStyle("fyne.io", link, fyne.TextAlignCenter, fyne.TextStyle{}),
|
||||||
|
layout.NewSpacer(),
|
||||||
|
|
||||||
|
widget.NewGroup("Theme",
|
||||||
|
fyne.NewContainerWithLayout(layout.NewGridLayout(2),
|
||||||
|
widget.NewButton("Dark", func() {
|
||||||
|
a.Settings().SetTheme(theme.DarkTheme())
|
||||||
|
}),
|
||||||
|
widget.NewButton("Light", func() {
|
||||||
|
a.Settings().SetTheme(theme.LightTheme())
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
a := app.NewWithID("io.fyne.demo")
|
||||||
|
a.SetIcon(theme.FyneLogo())
|
||||||
|
|
||||||
|
w := a.NewWindow("Fyne Demo")
|
||||||
|
w.SetMainMenu(fyne.NewMainMenu(fyne.NewMenu("File",
|
||||||
|
fyne.NewMenuItem("New", func() { fmt.Println("Menu New") }),
|
||||||
|
// a quit item will be appended to our first menu
|
||||||
|
), fyne.NewMenu("Edit",
|
||||||
|
fyne.NewMenuItem("Cut", func() { fmt.Println("Menu Cut") }),
|
||||||
|
fyne.NewMenuItem("Copy", func() { fmt.Println("Menu Copy") }),
|
||||||
|
fyne.NewMenuItem("Paste", func() { fmt.Println("Menu Paste") }),
|
||||||
|
)))
|
||||||
|
w.SetMaster()
|
||||||
|
|
||||||
|
tabs := widget.NewTabContainer(
|
||||||
|
widget.NewTabItemWithIcon("Welcome", theme.HomeIcon(), welcomeScreen(a)),
|
||||||
|
widget.NewTabItemWithIcon("Widgets", theme.ContentCopyIcon(), screens.WidgetScreen()),
|
||||||
|
widget.NewTabItemWithIcon("Graphics", theme.DocumentCreateIcon(), screens.GraphicsScreen()),
|
||||||
|
widget.NewTabItemWithIcon("Windows", theme.ViewFullScreenIcon(), screens.DialogScreen(w)),
|
||||||
|
widget.NewTabItemWithIcon("Advanced", theme.SettingsIcon(), screens.AdvancedScreen(w)))
|
||||||
|
tabs.SetTabLocation(widget.TabLocationLeading)
|
||||||
|
tabs.SelectTabIndex(a.Preferences().Int(preferenceCurrentTab))
|
||||||
|
w.SetContent(tabs)
|
||||||
|
|
||||||
|
w.ShowAndRun()
|
||||||
|
a.Preferences().SetInt(preferenceCurrentTab, tabs.CurrentTabIndex())
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package screens
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"fyne.io/fyne"
|
||||||
|
"fyne.io/fyne/driver/desktop"
|
||||||
|
"fyne.io/fyne/layout"
|
||||||
|
"fyne.io/fyne/widget"
|
||||||
|
)
|
||||||
|
|
||||||
|
func scaleString(c fyne.Canvas) string {
|
||||||
|
return fmt.Sprintf("%0.2f", c.Scale())
|
||||||
|
}
|
||||||
|
|
||||||
|
func prependTo(g *widget.Group, s string) {
|
||||||
|
g.Prepend(widget.NewLabel(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdvancedScreen loads a panel that shows details and settings that are a bit
|
||||||
|
// more detailed than normally needed.
|
||||||
|
func AdvancedScreen(win fyne.Window) fyne.CanvasObject {
|
||||||
|
scale := widget.NewLabel("")
|
||||||
|
|
||||||
|
screen := widget.NewGroup("Screen", widget.NewForm(
|
||||||
|
&widget.FormItem{Text: "Scale", Widget: scale},
|
||||||
|
))
|
||||||
|
|
||||||
|
scale.SetText(scaleString(win.Canvas()))
|
||||||
|
|
||||||
|
label := widget.NewLabel("Just type...")
|
||||||
|
generic := widget.NewGroupWithScroller("Generic")
|
||||||
|
desk := widget.NewGroupWithScroller("Desktop")
|
||||||
|
|
||||||
|
win.Canvas().SetOnTypedRune(func(r rune) {
|
||||||
|
prependTo(generic, "Rune: "+string(r))
|
||||||
|
})
|
||||||
|
win.Canvas().SetOnTypedKey(func(ev *fyne.KeyEvent) {
|
||||||
|
prependTo(generic, "Key : "+string(ev.Name))
|
||||||
|
})
|
||||||
|
if deskCanvas, ok := win.Canvas().(desktop.Canvas); ok {
|
||||||
|
deskCanvas.SetOnKeyDown(func(ev *fyne.KeyEvent) {
|
||||||
|
prependTo(desk, "KeyDown: "+string(ev.Name))
|
||||||
|
})
|
||||||
|
deskCanvas.SetOnKeyUp(func(ev *fyne.KeyEvent) {
|
||||||
|
prependTo(desk, "KeyUp : "+string(ev.Name))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return widget.NewHBox(widget.NewVBox(screen,
|
||||||
|
widget.NewButton("Custom Theme", func() {
|
||||||
|
fyne.CurrentApp().Settings().SetTheme(newCustomTheme())
|
||||||
|
}),
|
||||||
|
widget.NewButton("Fullscreen", func() {
|
||||||
|
win.SetFullScreen(!win.FullScreen())
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
|
||||||
|
fyne.NewContainerWithLayout(layout.NewBorderLayout(label, nil, nil, nil),
|
||||||
|
label,
|
||||||
|
fyne.NewContainerWithLayout(layout.NewGridLayout(2),
|
||||||
|
generic, desk,
|
||||||
|
),
|
||||||
|
))
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package screens
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"fyne.io/fyne"
|
||||||
|
"fyne.io/fyne/canvas"
|
||||||
|
"fyne.io/fyne/layout"
|
||||||
|
"fyne.io/fyne/theme"
|
||||||
|
)
|
||||||
|
|
||||||
|
func rgbGradient(x, y, w, h int) color.Color {
|
||||||
|
g := int(float32(x) / float32(w) * float32(255))
|
||||||
|
b := int(float32(y) / float32(h) * float32(255))
|
||||||
|
|
||||||
|
return color.RGBA{uint8(255 - b), uint8(g), uint8(b), 0xff}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GraphicsScreen loads a graphics example panel for the demo app
|
||||||
|
func GraphicsScreen() fyne.CanvasObject {
|
||||||
|
gradient := canvas.NewHorizontalGradient(color.RGBA{0x80, 0, 0, 0xff}, color.RGBA{0, 0x80, 0, 0xff})
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
|
gradient.Angle += 45
|
||||||
|
if gradient.Angle >= 360 {
|
||||||
|
gradient.Angle -= 360
|
||||||
|
}
|
||||||
|
canvas.Refresh(gradient)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
content := fyne.NewContainerWithLayout(layout.NewFixedGridLayout(fyne.NewSize(90, 90)),
|
||||||
|
&canvas.Rectangle{FillColor: color.RGBA{0x80, 0, 0, 0xff},
|
||||||
|
StrokeColor: color.RGBA{0xff, 0xff, 0xff, 0xff},
|
||||||
|
StrokeWidth: 1},
|
||||||
|
canvas.NewImageFromResource(theme.FyneLogo()),
|
||||||
|
&canvas.Line{StrokeColor: color.RGBA{0, 0, 0x80, 0xff}, StrokeWidth: 5},
|
||||||
|
&canvas.Circle{StrokeColor: color.RGBA{0, 0, 0x80, 0xff},
|
||||||
|
FillColor: color.RGBA{0x30, 0x30, 0x30, 0x60},
|
||||||
|
StrokeWidth: 2},
|
||||||
|
canvas.NewText("Text", color.RGBA{0, 0x80, 0, 0xff}),
|
||||||
|
canvas.NewRasterWithPixels(rgbGradient),
|
||||||
|
gradient,
|
||||||
|
canvas.NewRadialGradient(color.RGBA{0x80, 0, 0, 0xff}, color.RGBA{0, 0x80, 0x80, 0xff}),
|
||||||
|
)
|
||||||
|
|
||||||
|
return fyne.NewContainerWithLayout(layout.NewAdaptiveGridLayout(2), content, IconsPanel())
|
||||||
|
}
|
|
@ -0,0 +1,144 @@
|
||||||
|
package screens
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
|
||||||
|
"fyne.io/fyne"
|
||||||
|
"fyne.io/fyne/canvas"
|
||||||
|
"fyne.io/fyne/layout"
|
||||||
|
"fyne.io/fyne/theme"
|
||||||
|
"fyne.io/fyne/widget"
|
||||||
|
)
|
||||||
|
|
||||||
|
type browser struct {
|
||||||
|
current int
|
||||||
|
|
||||||
|
name *widget.Select
|
||||||
|
icon *widget.Icon
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *browser) setIcon(index int) {
|
||||||
|
if index < 0 || index > len(icons)-1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.current = index
|
||||||
|
|
||||||
|
b.name.SetSelected(icons[index].name)
|
||||||
|
b.icon.SetResource(icons[index].icon)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IconsPanel loads a panel that shows the various icons available in Fyne
|
||||||
|
func IconsPanel() fyne.CanvasObject {
|
||||||
|
b := &browser{}
|
||||||
|
|
||||||
|
prev := widget.NewButtonWithIcon("", theme.NavigateBackIcon(), func() {
|
||||||
|
b.setIcon(b.current - 1)
|
||||||
|
})
|
||||||
|
next := widget.NewButtonWithIcon("", theme.NavigateNextIcon(), func() {
|
||||||
|
b.setIcon(b.current + 1)
|
||||||
|
})
|
||||||
|
b.name = widget.NewSelect(iconList(), func(name string) {
|
||||||
|
for i, icon := range icons {
|
||||||
|
if icon.name == name {
|
||||||
|
if b.current != i {
|
||||||
|
b.setIcon(i)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.name.SetSelected(icons[b.current].name)
|
||||||
|
bar := widget.NewHBox(prev, next, b.name)
|
||||||
|
|
||||||
|
background := canvas.NewRasterWithPixels(checkerPattern)
|
||||||
|
background.SetMinSize(fyne.NewSize(280, 280))
|
||||||
|
b.icon = widget.NewIcon(icons[b.current].icon)
|
||||||
|
|
||||||
|
return fyne.NewContainerWithLayout(layout.NewBorderLayout(
|
||||||
|
bar, nil, nil, nil), bar, background, b.icon)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkerPattern(x, y, _, _ int) color.Color {
|
||||||
|
x /= 20
|
||||||
|
y /= 20
|
||||||
|
|
||||||
|
if x%2 == y%2 {
|
||||||
|
return theme.BackgroundColor()
|
||||||
|
}
|
||||||
|
|
||||||
|
return theme.ButtonColor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func iconList() []string {
|
||||||
|
var ret []string
|
||||||
|
for _, icon := range icons {
|
||||||
|
ret = append(ret, icon.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
var icons = []struct {
|
||||||
|
name string
|
||||||
|
icon fyne.Resource
|
||||||
|
}{
|
||||||
|
{"CancelIcon", theme.CancelIcon()},
|
||||||
|
{"ConfirmIcon", theme.ConfirmIcon()},
|
||||||
|
{"DeleteIcon", theme.DeleteIcon()},
|
||||||
|
{"SearchIcon", theme.SearchIcon()},
|
||||||
|
{"SearchReplaceIcon", theme.SearchReplaceIcon()},
|
||||||
|
|
||||||
|
{"CheckButtonIcon", theme.CheckButtonIcon()},
|
||||||
|
{"CheckButtonCheckedIcon", theme.CheckButtonCheckedIcon()},
|
||||||
|
{"RadioButtonIcon", theme.RadioButtonIcon()},
|
||||||
|
{"RadioButtonCheckedIcon", theme.RadioButtonCheckedIcon()},
|
||||||
|
|
||||||
|
{"ContentAddIcon", theme.ContentAddIcon()},
|
||||||
|
{"ContentRemoveIcon", theme.ContentRemoveIcon()},
|
||||||
|
{"ContentClearIcon", theme.ContentClearIcon()},
|
||||||
|
{"ContentCutIcon", theme.ContentCutIcon()},
|
||||||
|
{"ContentCopyIcon", theme.ContentCopyIcon()},
|
||||||
|
{"ContentPasteIcon", theme.ContentPasteIcon()},
|
||||||
|
{"ContentRedoIcon", theme.ContentRedoIcon()},
|
||||||
|
{"ContentUndoIcon", theme.ContentUndoIcon()},
|
||||||
|
|
||||||
|
{"InfoIcon", theme.InfoIcon()},
|
||||||
|
{"QuestionIcon", theme.QuestionIcon()},
|
||||||
|
{"WarningIcon", theme.WarningIcon()},
|
||||||
|
|
||||||
|
{"DocumentCreateIcon", theme.DocumentCreateIcon()},
|
||||||
|
{"DocumentPrintIcon", theme.DocumentPrintIcon()},
|
||||||
|
{"DocumentSaveIcon", theme.DocumentSaveIcon()},
|
||||||
|
|
||||||
|
{"FolderIcon", theme.FolderIcon()},
|
||||||
|
{"FolderNewIcon", theme.FolderNewIcon()},
|
||||||
|
{"FolderOpenIcon", theme.FolderOpenIcon()},
|
||||||
|
{"HomeIcon", theme.HomeIcon()},
|
||||||
|
{"HelpIcon", theme.HelpIcon()},
|
||||||
|
{"SettingsIcon", theme.SettingsIcon()},
|
||||||
|
|
||||||
|
{"ViewFullScreenIcon", theme.ViewFullScreenIcon()},
|
||||||
|
{"ViewRestoreIcon", theme.ViewRestoreIcon()},
|
||||||
|
{"ViewRefreshIcon", theme.ViewRefreshIcon()},
|
||||||
|
{"VisibilityIcon", theme.VisibilityIcon()},
|
||||||
|
{"VisibilityOffIcon", theme.VisibilityOffIcon()},
|
||||||
|
{"ZoomFitIcon", theme.ZoomFitIcon()},
|
||||||
|
{"ZoomInIcon", theme.ZoomInIcon()},
|
||||||
|
{"ZoomOutIcon", theme.ZoomOutIcon()},
|
||||||
|
|
||||||
|
{"MoveDownIcon", theme.MoveDownIcon()},
|
||||||
|
{"MoveUpIcon", theme.MoveUpIcon()},
|
||||||
|
|
||||||
|
{"NavigateBackIcon", theme.NavigateBackIcon()},
|
||||||
|
{"NavigateNextIcon", theme.NavigateNextIcon()},
|
||||||
|
|
||||||
|
{"MenuDropDown", theme.MenuDropDownIcon()},
|
||||||
|
{"MenuDropUp", theme.MenuDropUpIcon()},
|
||||||
|
|
||||||
|
{"MailAttachmentIcon", theme.MailAttachmentIcon()},
|
||||||
|
{"MailComposeIcon", theme.MailComposeIcon()},
|
||||||
|
{"MailForwardIcon", theme.MailForwardIcon()},
|
||||||
|
{"MailReplyIcon", theme.MailReplyIcon()},
|
||||||
|
{"MailReplyAllIcon", theme.MailReplyAllIcon()},
|
||||||
|
{"MailSendIcon", theme.MailSendIcon()},
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package screens
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
|
||||||
|
"fyne.io/fyne"
|
||||||
|
"fyne.io/fyne/canvas"
|
||||||
|
"fyne.io/fyne/layout"
|
||||||
|
"fyne.io/fyne/widget"
|
||||||
|
)
|
||||||
|
|
||||||
|
func makeCell() fyne.CanvasObject {
|
||||||
|
rect := canvas.NewRectangle(&color.RGBA{128, 128, 128, 255})
|
||||||
|
rect.SetMinSize(fyne.NewSize(30, 30))
|
||||||
|
return rect
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeBorderLayout() *fyne.Container {
|
||||||
|
top := makeCell()
|
||||||
|
bottom := makeCell()
|
||||||
|
left := makeCell()
|
||||||
|
right := makeCell()
|
||||||
|
middle := widget.NewLabelWithStyle("BorderLayout", fyne.TextAlignCenter, fyne.TextStyle{})
|
||||||
|
|
||||||
|
borderLayout := layout.NewBorderLayout(top, bottom, left, right)
|
||||||
|
return fyne.NewContainerWithLayout(borderLayout,
|
||||||
|
top, bottom, left, right, middle)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeBoxLayout() *fyne.Container {
|
||||||
|
top := makeCell()
|
||||||
|
bottom := makeCell()
|
||||||
|
middle := widget.NewLabel("BoxLayout")
|
||||||
|
center := makeCell()
|
||||||
|
right := makeCell()
|
||||||
|
|
||||||
|
col := fyne.NewContainerWithLayout(layout.NewVBoxLayout(),
|
||||||
|
top, middle, bottom)
|
||||||
|
|
||||||
|
return fyne.NewContainerWithLayout(layout.NewHBoxLayout(),
|
||||||
|
col, center, right)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeFixedGridLayout() *fyne.Container {
|
||||||
|
box1 := makeCell()
|
||||||
|
box2 := widget.NewLabel("FixedGrid")
|
||||||
|
box3 := makeCell()
|
||||||
|
box4 := makeCell()
|
||||||
|
|
||||||
|
return fyne.NewContainerWithLayout(layout.NewFixedGridLayout(fyne.NewSize(75, 75)),
|
||||||
|
box1, box2, box3, box4)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeGridLayout() *fyne.Container {
|
||||||
|
box1 := makeCell()
|
||||||
|
box2 := widget.NewLabel("Grid")
|
||||||
|
box3 := makeCell()
|
||||||
|
box4 := makeCell()
|
||||||
|
|
||||||
|
return fyne.NewContainerWithLayout(layout.NewGridLayout(2),
|
||||||
|
box1, box2, box3, box4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LayoutPanel loads a panel that shows the layouts available for a container
|
||||||
|
func LayoutPanel() fyne.CanvasObject {
|
||||||
|
return widget.NewTabContainer(
|
||||||
|
widget.NewTabItem("Border", makeBorderLayout()),
|
||||||
|
widget.NewTabItem("Box", makeBoxLayout()),
|
||||||
|
widget.NewTabItem("Fixed Grid", makeFixedGridLayout()),
|
||||||
|
widget.NewTabItem("Grid", makeGridLayout()),
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
package screens
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
|
||||||
|
"fyne.io/fyne"
|
||||||
|
"fyne.io/fyne/theme"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
purple = &color.RGBA{R: 128, G: 0, B: 128, A: 255}
|
||||||
|
orange = &color.RGBA{R: 198, G: 123, B: 0, A: 255}
|
||||||
|
grey = &color.Gray{Y: 123}
|
||||||
|
)
|
||||||
|
|
||||||
|
// customTheme is a simple demonstration of a bespoke theme loaded by a Fyne app.
|
||||||
|
type customTheme struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) BackgroundColor() color.Color {
|
||||||
|
return purple
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) ButtonColor() color.Color {
|
||||||
|
return color.Black
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) DisabledButtonColor() color.Color {
|
||||||
|
return color.White
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) HyperlinkColor() color.Color {
|
||||||
|
return orange
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) TextColor() color.Color {
|
||||||
|
return color.White
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) DisabledTextColor() color.Color {
|
||||||
|
return color.Black
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) IconColor() color.Color {
|
||||||
|
return color.White
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) DisabledIconColor() color.Color {
|
||||||
|
return color.Black
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) PlaceHolderColor() color.Color {
|
||||||
|
return grey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) PrimaryColor() color.Color {
|
||||||
|
return orange
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) HoverColor() color.Color {
|
||||||
|
return orange
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) FocusColor() color.Color {
|
||||||
|
return orange
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) ScrollBarColor() color.Color {
|
||||||
|
return grey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) ShadowColor() color.Color {
|
||||||
|
return &color.RGBA{0xcc, 0xcc, 0xcc, 0xcc}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) TextSize() int {
|
||||||
|
return 12
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) TextFont() fyne.Resource {
|
||||||
|
return theme.DefaultTextBoldFont()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) TextBoldFont() fyne.Resource {
|
||||||
|
return theme.DefaultTextBoldFont()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) TextItalicFont() fyne.Resource {
|
||||||
|
return theme.DefaultTextBoldItalicFont()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) TextBoldItalicFont() fyne.Resource {
|
||||||
|
return theme.DefaultTextBoldItalicFont()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) TextMonospaceFont() fyne.Resource {
|
||||||
|
return theme.DefaultTextMonospaceFont()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) Padding() int {
|
||||||
|
return 10
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) IconInlineSize() int {
|
||||||
|
return 20
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) ScrollBarSize() int {
|
||||||
|
return 10
|
||||||
|
}
|
||||||
|
|
||||||
|
func (customTheme) ScrollBarSmallSize() int {
|
||||||
|
return 5
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCustomTheme() fyne.Theme {
|
||||||
|
return &customTheme{}
|
||||||
|
}
|
|
@ -0,0 +1,157 @@
|
||||||
|
package screens
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"fyne.io/fyne"
|
||||||
|
"fyne.io/fyne/canvas"
|
||||||
|
"fyne.io/fyne/layout"
|
||||||
|
"fyne.io/fyne/theme"
|
||||||
|
"fyne.io/fyne/widget"
|
||||||
|
)
|
||||||
|
|
||||||
|
func makeButtonTab() fyne.Widget {
|
||||||
|
disabled := widget.NewButton("Disabled", func() {})
|
||||||
|
disabled.Disable()
|
||||||
|
|
||||||
|
return widget.NewVBox(
|
||||||
|
widget.NewLabel("Text label"),
|
||||||
|
widget.NewButton("Text button", func() { fmt.Println("tapped text button") }),
|
||||||
|
widget.NewButtonWithIcon("With icon", theme.ConfirmIcon(), func() { fmt.Println("tapped icon button") }),
|
||||||
|
disabled,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeInputTab() fyne.Widget {
|
||||||
|
entry := widget.NewEntry()
|
||||||
|
entry.SetPlaceHolder("Entry")
|
||||||
|
entryReadOnly := widget.NewEntry()
|
||||||
|
entryReadOnly.SetText("Entry (disabled)")
|
||||||
|
entryReadOnly.Disable()
|
||||||
|
|
||||||
|
disabledCheck := widget.NewCheck("Disabled check", func(bool) {})
|
||||||
|
disabledCheck.Disable()
|
||||||
|
radio := widget.NewRadio([]string{"Radio Item 1", "Radio Item 2"}, func(s string) { fmt.Println("selected", s) })
|
||||||
|
radio.Horizontal = true
|
||||||
|
disabledRadio := widget.NewRadio([]string{"Disabled radio"}, func(string) {})
|
||||||
|
disabledRadio.Disable()
|
||||||
|
|
||||||
|
return widget.NewVBox(
|
||||||
|
entry,
|
||||||
|
entryReadOnly,
|
||||||
|
widget.NewSelect([]string{"Option 1", "Option 2", "Option 3"}, func(s string) { fmt.Println("selected", s) }),
|
||||||
|
widget.NewCheck("Check", func(on bool) { fmt.Println("checked", on) }),
|
||||||
|
disabledCheck,
|
||||||
|
radio,
|
||||||
|
disabledRadio,
|
||||||
|
widget.NewSlider(0, 100),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeProgressTab() fyne.Widget {
|
||||||
|
progress := widget.NewProgressBar()
|
||||||
|
infProgress := widget.NewProgressBarInfinite()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
num := 0.0
|
||||||
|
for num < 1.0 {
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
progress.SetValue(num)
|
||||||
|
num += 0.01
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.SetValue(1)
|
||||||
|
}()
|
||||||
|
|
||||||
|
return widget.NewVBox(
|
||||||
|
widget.NewLabel("Percent"), progress,
|
||||||
|
widget.NewLabel("Infinite"), infProgress)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeFormTab() fyne.Widget {
|
||||||
|
name := widget.NewEntry()
|
||||||
|
name.SetPlaceHolder("John Smith")
|
||||||
|
email := widget.NewEntry()
|
||||||
|
email.SetPlaceHolder("test@example.com")
|
||||||
|
password := widget.NewPasswordEntry()
|
||||||
|
password.SetPlaceHolder("Password")
|
||||||
|
largeText := widget.NewMultiLineEntry()
|
||||||
|
|
||||||
|
form := &widget.Form{
|
||||||
|
OnCancel: func() {
|
||||||
|
fmt.Println("Cancelled")
|
||||||
|
},
|
||||||
|
OnSubmit: func() {
|
||||||
|
fmt.Println("Form submitted")
|
||||||
|
fmt.Println("Name:", name.Text)
|
||||||
|
fmt.Println("Email:", email.Text)
|
||||||
|
fmt.Println("Password:", password.Text)
|
||||||
|
fmt.Println("Message:", largeText.Text)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
form.Append("Name", name)
|
||||||
|
form.Append("Email", email)
|
||||||
|
form.Append("Password", password)
|
||||||
|
form.Append("Message", largeText)
|
||||||
|
|
||||||
|
return form
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeScrollTab() fyne.CanvasObject {
|
||||||
|
logo := canvas.NewImageFromResource(theme.FyneLogo())
|
||||||
|
logo.SetMinSize(fyne.NewSize(320, 320))
|
||||||
|
list := widget.NewHBox()
|
||||||
|
list2 := widget.NewVBox()
|
||||||
|
|
||||||
|
for i := 1; i <= 20; i++ {
|
||||||
|
index := i // capture
|
||||||
|
list.Append(widget.NewButton(fmt.Sprintf("Button %d", index), func() {
|
||||||
|
fmt.Println("Tapped", index)
|
||||||
|
}))
|
||||||
|
list2.Append(widget.NewButton(fmt.Sprintf("Button %d", index), func() {
|
||||||
|
fmt.Println("Tapped", index)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
scroll := widget.NewScrollContainer(list)
|
||||||
|
scroll.Resize(fyne.NewSize(200, 300))
|
||||||
|
|
||||||
|
scroll2 := widget.NewScrollContainer(list2)
|
||||||
|
scroll2.Resize(fyne.NewSize(200, 100))
|
||||||
|
|
||||||
|
return fyne.NewContainerWithLayout(layout.NewGridLayout(1), scroll, scroll2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeScrollBothTab() fyne.CanvasObject {
|
||||||
|
logo := canvas.NewImageFromResource(theme.FyneLogo())
|
||||||
|
logo.SetMinSize(fyne.NewSize(800, 800))
|
||||||
|
|
||||||
|
scroll := widget.NewScrollContainer(logo)
|
||||||
|
scroll.Resize(fyne.NewSize(400, 400))
|
||||||
|
|
||||||
|
return scroll
|
||||||
|
}
|
||||||
|
|
||||||
|
// WidgetScreen shows a panel containing widget demos
|
||||||
|
func WidgetScreen() fyne.CanvasObject {
|
||||||
|
toolbar := widget.NewToolbar(widget.NewToolbarAction(theme.MailComposeIcon(), func() { fmt.Println("New") }),
|
||||||
|
widget.NewToolbarSeparator(),
|
||||||
|
widget.NewToolbarSpacer(),
|
||||||
|
widget.NewToolbarAction(theme.ContentCutIcon(), func() { fmt.Println("Cut") }),
|
||||||
|
widget.NewToolbarAction(theme.ContentCopyIcon(), func() { fmt.Println("Copy") }),
|
||||||
|
widget.NewToolbarAction(theme.ContentPasteIcon(), func() { fmt.Println("Paste") }),
|
||||||
|
)
|
||||||
|
|
||||||
|
return fyne.NewContainerWithLayout(layout.NewBorderLayout(toolbar, nil, nil, nil),
|
||||||
|
toolbar,
|
||||||
|
widget.NewTabContainer(
|
||||||
|
widget.NewTabItem("Buttons", makeButtonTab()),
|
||||||
|
widget.NewTabItem("Input", makeInputTab()),
|
||||||
|
widget.NewTabItem("Progress", makeProgressTab()),
|
||||||
|
widget.NewTabItem("Form", makeFormTab()),
|
||||||
|
widget.NewTabItem("Scroll", makeScrollTab()),
|
||||||
|
widget.NewTabItem("Full Scroll", makeScrollBothTab()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package screens
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"fyne.io/fyne"
|
||||||
|
"fyne.io/fyne/dialog"
|
||||||
|
"fyne.io/fyne/layout"
|
||||||
|
"fyne.io/fyne/widget"
|
||||||
|
)
|
||||||
|
|
||||||
|
func confirmCallback(response bool) {
|
||||||
|
fmt.Println("Responded with", response)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DialogScreen loads a panel that lists the dialog windows that can be tested.
|
||||||
|
func DialogScreen(win fyne.Window) fyne.CanvasObject {
|
||||||
|
dialogs := widget.NewGroup("Dialogs",
|
||||||
|
widget.NewButton("Info", func() {
|
||||||
|
dialog.ShowInformation("Information", "You should know this thing...", win)
|
||||||
|
}),
|
||||||
|
widget.NewButton("Error", func() {
|
||||||
|
err := errors.New("A dummy error message")
|
||||||
|
dialog.ShowError(err, win)
|
||||||
|
}),
|
||||||
|
widget.NewButton("Confirm", func() {
|
||||||
|
cnf := dialog.NewConfirm("Confirmation", "Are you enjoying this demo?", confirmCallback, win)
|
||||||
|
cnf.SetDismissText("Nah")
|
||||||
|
cnf.SetConfirmText("Oh Yes!")
|
||||||
|
cnf.Show()
|
||||||
|
}),
|
||||||
|
widget.NewButton("Progress", func() {
|
||||||
|
prog := dialog.NewProgress("MyProgress", "Nearly there...", win)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
num := 0.0
|
||||||
|
for num < 1.0 {
|
||||||
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
prog.SetValue(num)
|
||||||
|
num += 0.01
|
||||||
|
}
|
||||||
|
|
||||||
|
prog.SetValue(1)
|
||||||
|
prog.Hide()
|
||||||
|
}()
|
||||||
|
|
||||||
|
prog.Show()
|
||||||
|
}),
|
||||||
|
widget.NewButton("Custom", func() {
|
||||||
|
content := widget.NewEntry()
|
||||||
|
content.SetPlaceHolder("Type something here")
|
||||||
|
content.OnChanged = func(text string) {
|
||||||
|
fmt.Println("Entered", text)
|
||||||
|
}
|
||||||
|
dialog.ShowCustom("Custom dialog", "Done", content, win)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
windows := widget.NewVBox(dialogs, widget.NewGroup("Windows",
|
||||||
|
widget.NewButton("New window", func() {
|
||||||
|
w := fyne.CurrentApp().NewWindow("Hello")
|
||||||
|
w.SetContent(widget.NewLabel("Hello World!"))
|
||||||
|
w.Show()
|
||||||
|
}),
|
||||||
|
widget.NewButton("Fixed size window", func() {
|
||||||
|
w := fyne.CurrentApp().NewWindow("Fixed")
|
||||||
|
w.SetContent(fyne.NewContainerWithLayout(layout.NewCenterLayout(), widget.NewLabel("Hello World!")))
|
||||||
|
|
||||||
|
w.Resize(fyne.NewSize(240, 180))
|
||||||
|
w.SetFixedSize(true)
|
||||||
|
w.Show()
|
||||||
|
}),
|
||||||
|
widget.NewButton("Centered window", func() {
|
||||||
|
w := fyne.CurrentApp().NewWindow("Central")
|
||||||
|
w.SetContent(fyne.NewContainerWithLayout(layout.NewCenterLayout(), widget.NewLabel("Hello World!")))
|
||||||
|
|
||||||
|
w.CenterOnScreen()
|
||||||
|
w.Show()
|
||||||
|
})))
|
||||||
|
|
||||||
|
return fyne.NewContainerWithLayout(layout.NewAdaptiveGridLayout(2), windows, LayoutPanel())
|
||||||
|
}
|
Loading…
Reference in New Issue