Skip to content

Commit

Permalink
Merge branch 'develop' into add-translate-command
Browse files Browse the repository at this point in the history
  • Loading branch information
sdassow committed Oct 16, 2024
2 parents 65858fe + af35ba6 commit 0e9a7ff
Show file tree
Hide file tree
Showing 33 changed files with 328 additions and 25 deletions.
3 changes: 3 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ func (a *fyneApp) Icon() fyne.Resource {
return a.icon
}

if a.Metadata().Icon == nil || len(a.Metadata().Icon.Content()) == 0 {
return nil
}
return a.Metadata().Icon
}

Expand Down
2 changes: 1 addition & 1 deletion app/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestFyneApp_UniqueID(t *testing.T) {
func TestFyneApp_SetIcon(t *testing.T) {
app := NewWithID("io.fyne.test")

metaIcon := &fyne.StaticResource{StaticName: "Metadata"}
metaIcon := &fyne.StaticResource{StaticName: "Metadata", StaticContent: []byte("?PNG...")}
SetMetadata(fyne.AppMetadata{
Icon: metaIcon,
})
Expand Down
34 changes: 34 additions & 0 deletions app/icon_cache_file_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package app

import (
_ "embed"
"os"
"testing"

"fyne.io/fyne/v2"
"github.com/stretchr/testify/assert"
)

//go:embed testdata/fyne.png
var iconData []byte

func TestCachedIcon_PATH(t *testing.T) {
SetMetadata(fyne.AppMetadata{})
a := &fyneApp{uniqueID: "icontest"}
assert.Equal(t, "", a.cachedIconPath())

a.SetIcon(fyne.NewStaticResource("dummy", iconData))
path := a.cachedIconPath()
if path == "" {
t.Error("cache path not constructed")
return
} else {
defer os.Remove(path)
}

info, err := os.Stat(path)
assert.Nil(t, err)
assert.Equal(t, "icon.png", info.Name())

assert.Nil(t, err)
}
7 changes: 1 addition & 6 deletions app/preferences.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,7 @@ func convertLists(values map[string]any) {
floats[i] = item.(float64)
}
values[k] = floats
case int:
ints := make([]int, len(items))
for i, item := range items {
ints[i] = item.(int)
}
values[k] = ints
//case int: // json has no int!
case string:
strings := make([]string, len(items))
for i, item := range items {
Expand Down
15 changes: 15 additions & 0 deletions app/preferences_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func TestPreferences_Save(t *testing.T) {
val["keyFloatList"] = []float64{1.1, 2.2, 3.3}
val["keyBool"] = true
val["keyBoolList"] = []bool{true, false, true}
val["keyEmptyList"] = []string{}
})

path := p.storagePath()
Expand Down Expand Up @@ -97,4 +98,18 @@ func TestPreferences_Load(t *testing.T) {
assert.Equal(t, []float64{1.1, 2.2, 3.3}, p.FloatList("keyFloatList"))
assert.Equal(t, true, p.Bool("keyBool"))
assert.Equal(t, []bool{true, false, true}, p.BoolList("keyBoolList"))
assert.Equal(t, 0, len(p.StringList("keyEmptyList")))
}

func TestPreferences_EmptyLoad(t *testing.T) {
p := newPreferences(&fyneApp{uniqueID: ""})

count := 0
p.ReadValues(func(v map[string]any) {
for range v {
count++
}
})

assert.Zero(t, count)
}
Binary file added app/testdata/fyne.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion app/testdata/preferences.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
"keyFloat": 3.5,
"keyFloatList": [1.1, 2.2, 3.3],
"keyBool": true,
"keyBoolList": [true, false, true]
"keyBoolList": [true, false, true],
"keyEmptyList": []
}
8 changes: 8 additions & 0 deletions cmd/fyne/internal/commands/package-unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ type unixData struct {
Comment string
Keywords string
ExecParams string

SourceRepo, SourceDir string
}

func (p *Packager) packageUNIX() error {
Expand Down Expand Up @@ -74,6 +76,12 @@ func (p *Packager) packageUNIX() error {
Categories: formatDesktopFileList(linuxBSD.Categories),
ExecParams: linuxBSD.ExecParams,
}

if p.sourceMetadata != nil {
tplData.SourceRepo = p.sourceMetadata.Repo
tplData.SourceDir = p.sourceMetadata.Dir
}

err = templates.DesktopFileUNIX.Execute(deskFile, tplData)
if err != nil {
return fmt.Errorf("failed to write desktop entry string: %w", err)
Expand Down
23 changes: 23 additions & 0 deletions cmd/fyne/internal/commands/package-unix_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package commands

import (
"bytes"
"strings"
"testing"

"fyne.io/fyne/v2/cmd/fyne/internal/templates"
"github.com/stretchr/testify/assert"
)

Expand All @@ -11,3 +14,23 @@ func TestFormatDesktopFileList(t *testing.T) {
assert.Equal(t, "One;", formatDesktopFileList([]string{"One"}))
assert.Equal(t, "One;Two;", formatDesktopFileList([]string{"One", "Two"}))
}

func TestDesktopFileSource(t *testing.T) {
tplData := unixData{
Name: "Testing",
}
buf := &bytes.Buffer{}

err := templates.DesktopFileUNIX.Execute(buf, tplData)
assert.Nil(t, err)
assert.False(t, strings.Contains(buf.String(), "[X-Fyne"))

tplData.SourceRepo = "https://example.com"
tplData.SourceDir = "cmd/name"

err = templates.DesktopFileUNIX.Execute(buf, tplData)
assert.Nil(t, err)
assert.True(t, strings.Contains(buf.String(), "[X-Fyne"))
assert.True(t, strings.Contains(buf.String(), "Repo=https://example.com"))
assert.True(t, strings.Contains(buf.String(), "Dir=cmd/name"))
}
3 changes: 3 additions & 0 deletions cmd/fyne/internal/commands/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ type Packager struct {

customMetadata keyValueFlag
linuxAndBSDMetadata *metadata.LinuxAndBSD
sourceMetadata *metadata.AppSource
}

// NewPackager returns a command that can handle the packaging a GUI apps built using Fyne from local source code.
Expand Down Expand Up @@ -342,6 +343,8 @@ func (p *Packager) validate() (err error) {
}

p.appData.mergeMetadata(data)
p.sourceMetadata = data.Source

p.linuxAndBSDMetadata = data.LinuxAndBSD
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/fyne/internal/templates/bundled.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion cmd/fyne/internal/templates/data/app.desktop
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@ Icon={{.Name}}
Comment={{.Comment}}{{end}}
{{- if ne .Categories ""}}
Categories={{.Categories}}{{end}}
{{if ne .Keywords ""}}Keywords={{.Keywords}}{{else}}Keywords=fyne;{{end}}
Keywords={{if ne .Keywords ""}}{{.Keywords}}{{else}}fyne;{{end}}

{{if or (ne .SourceRepo "") (ne .SourceDir "") -}}
[X-Fyne Source]
Repo={{.SourceRepo}}
Dir={{.SourceDir}}

{{end -}}
4 changes: 4 additions & 0 deletions cmd/fyne_demo/FyneApp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
Version = "2.4.0"
Build = 11

[Source]
Repo = "https://github.com/fyne-io/fyne"
Dir = "cmd/fyne_demo"

[Development]
HelperText = "This binary was built with debug symbols"

Expand Down
6 changes: 4 additions & 2 deletions cmd/fyne_demo/tutorials/widget.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ func makeInputTab(_ fyne.Window) fyne.CanvasObject {
dateEntry.PlaceHolder = "Choose a date"
disabledCheck := widget.NewCheck("Disabled check", func(bool) {})
disabledCheck.Disable()
partialCheck := widget.NewCheck("Partial check", func(bool) {})
partialCheck.Partial = true
checkGroup := widget.NewCheckGroup([]string{"CheckGroup Item 1", "CheckGroup Item 2"}, func(s []string) { fmt.Println("selected", s) })
checkGroup.Horizontal = true
radio := widget.NewRadioGroup([]string{"Radio Item 1", "Radio Item 2"}, func(s string) { fmt.Println("selected", s) })
Expand All @@ -392,10 +394,10 @@ func makeInputTab(_ fyne.Window) fyne.CanvasObject {
selectEntry,
dateEntry,
widget.NewCheck("Check", func(on bool) { fmt.Println("checked", on) }),
disabledCheck,
partialCheck,
checkGroup,
radio,
disabledRadio,
container.NewGridWithColumns(2, disabledCheck, disabledRadio),
container.NewBorder(nil, nil, widget.NewLabel("Slider"), nil, widget.NewSlider(0, 1000)),
container.NewBorder(nil, nil, widget.NewLabel("Disabled slider"), nil, disabledSlider),
)
Expand Down
15 changes: 11 additions & 4 deletions internal/cache/text.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cache

import (
"image/color"
"sync"
"time"

Expand All @@ -19,10 +20,16 @@ type fontMetric struct {
}

type fontSizeEntry struct {
text string
size float32
style fyne.TextStyle
custom string
Text string
Size float32
Style fyne.TextStyle
Source string
}

type FontCacheEntry struct {
fontSizeEntry

Color color.Color
}

// GetFontMetrics looks up a calculated size and baseline required for the specified text parameters.
Expand Down
37 changes: 37 additions & 0 deletions internal/cache/texture_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,17 @@ func DeleteTexture(obj fyne.CanvasObject) {
textures.Delete(obj)
}

// GetTextTexture gets cached texture for a text run.
func GetTextTexture(ent FontCacheEntry) (TextureType, bool) {
return load(ent)
}

// GetTexture gets cached texture.
func GetTexture(obj fyne.CanvasObject) (TextureType, bool) {
return load(obj)
}

func load(obj any) (TextureType, bool) {
t, ok := textures.Load(obj)
if t == nil || !ok {
return NoTexture, false
Expand All @@ -31,6 +40,17 @@ func GetTexture(obj fyne.CanvasObject) (TextureType, bool) {
func RangeExpiredTexturesFor(canvas fyne.Canvas, f func(fyne.CanvasObject)) {
now := timeNow()
textures.Range(func(key, value any) bool {
if _, ok := key.(FontCacheEntry); ok {
tinfo := value.(*textureInfo)

// just free text directly when that string/style combo is done
if tinfo.isExpired(now) && tinfo.canvas == canvas {
textures.Delete(key)
tinfo.textFree()
}

return true
}
obj, tinfo := key.(fyne.CanvasObject), value.(*textureInfo)
if tinfo.isExpired(now) && tinfo.canvas == canvas {
f(obj)
Expand All @@ -40,11 +60,16 @@ func RangeExpiredTexturesFor(canvas fyne.Canvas, f func(fyne.CanvasObject)) {
}

// RangeTexturesFor range over the textures for the specified canvas.
// It will not return the texture for a `canvas.Text` as their render lifecycle is handled separately.
//
// Note: If this is used to free textures, then it should be called inside a current
// gl context to ensure textures are deleted from gl.
func RangeTexturesFor(canvas fyne.Canvas, f func(fyne.CanvasObject)) {
textures.Range(func(key, value any) bool {
if _, ok := key.(FontCacheEntry); ok {
return true // do nothing, text cache lives outside the scope of an object
}

obj, tinfo := key.(fyne.CanvasObject), value.(*textureInfo)
if tinfo.canvas == canvas {
f(obj)
Expand All @@ -53,9 +78,21 @@ func RangeTexturesFor(canvas fyne.Canvas, f func(fyne.CanvasObject)) {
})
}

// SetTextTexture sets cached texture for a text run.
func SetTextTexture(ent FontCacheEntry, texture TextureType, canvas fyne.Canvas, free func()) {
store(ent, texture, canvas, free)
}

// SetTexture sets cached texture.
func SetTexture(obj fyne.CanvasObject, texture TextureType, canvas fyne.Canvas) {
store(obj, texture, canvas, nil)
}

func store(obj any, texture TextureType, canvas fyne.Canvas, free func()) {
texInfo := &textureInfo{texture: texture}
if free != nil {
texInfo.textFree = free
}
texInfo.canvas = canvas
texInfo.setAlive()
textures.Store(obj, texInfo)
Expand Down
4 changes: 3 additions & 1 deletion internal/cache/texture_desktop.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ var NoTexture = TextureType(0)

type textureInfo struct {
textureCacheBase
texture TextureType

texture TextureType
textFree func()
}

// IsValid will return true if the passed texture is potentially a texture
Expand Down
4 changes: 3 additions & 1 deletion internal/cache/texture_gomobile.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ var NoTexture = gl.Texture{0}

type textureInfo struct {
textureCacheBase
texture TextureType

texture TextureType
textFree func()
}

// IsValid will return true if the passed texture is potentially a texture
Expand Down
6 changes: 4 additions & 2 deletions internal/cache/texture_goxjs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

package cache

import gl "github.com/fyne-io/gl-js"
import "github.com/fyne-io/gl-js"

// TextureType represents an uploaded GL texture
type TextureType = gl.Texture
Expand All @@ -11,7 +11,9 @@ var NoTexture = gl.NoTexture

type textureInfo struct {
textureCacheBase
texture TextureType

texture TextureType
textFree func()
}

// IsValid will return true if the passed texture is potentially a texture
Expand Down
5 changes: 5 additions & 0 deletions internal/metadata/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type FyneApp struct {
Details AppDetails
Development map[string]string `toml:",omitempty"`
Release map[string]string `toml:",omitempty"`
Source *AppSource `toml:",omitempty"`
LinuxAndBSD *LinuxAndBSD `toml:",omitempty"`
}

Expand All @@ -17,6 +18,10 @@ type AppDetails struct {
Build int `toml:",omitempty"`
}

type AppSource struct {
Repo, Dir string `toml:",omitempty"`
}

// LinuxAndBSD describes specific metadata for desktop files on Linux and BSD.
type LinuxAndBSD struct {
GenericName string `toml:",omitempty"`
Expand Down
Loading

0 comments on commit 0e9a7ff

Please sign in to comment.