代码拉取完成,页面将自动刷新
同步操作将从 全糖咖啡/B站缓存转视频工具-Golang 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
package main
import (
"encoding/json"
"image"
"image/color"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"time"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/tools/playground"
"fyne.io/fyne/v2/widget"
)
// MySettings gives access to user interfaces to control Fyne settings
type MySettings struct {
fyneSettings app.SettingsSchema
preview *canvas.Image
colors []fyne.CanvasObject
userTheme fyne.Theme
}
// NewSettings returns a new settings instance with the current configuration loaded
func NewSettings() *MySettings {
s := &MySettings{}
s.load()
if s.fyneSettings.Scale == 0 {
s.fyneSettings.Scale = 1
}
return s
}
// LoadAppearanceScreen creates a new settings screen to handle appearance configuration
func (s *MySettings) LoadAppearanceScreen(w fyne.Window) fyne.CanvasObject {
s.userTheme = fyne.CurrentApp().Settings().Theme()
if s.userTheme == nil {
s.userTheme = theme.DefaultTheme()
}
s.preview = canvas.NewImageFromImage(s.createPreview())
s.preview.FillMode = canvas.ImageFillContain
def := s.fyneSettings.ThemeName
themeNames := []string{"dark", "light"}
if runtime.GOOS == "darwin" || runtime.GOOS == "windows" {
themeNames = append(themeNames)
if s.fyneSettings.ThemeName == "" {
def = "light"
}
}
themes := widget.NewSelect(themeNames, s.chooseTheme)
themes.SetSelected(def)
scale := s.makeScaleGroup(w.Canvas().Scale())
box := container.NewVBox(scale)
for _, c := range theme.PrimaryColorNames() {
b := newColorButton(c, theme.PrimaryColorNamed(c), s)
s.colors = append(s.colors, b)
}
swatch := container.NewGridWithColumns(len(s.colors), s.colors...)
appearance := widget.NewForm(widget.NewFormItem("主色彩", swatch),
widget.NewFormItem("主题", themes))
box.Add(widget.NewCard("外观", "", appearance))
bottom := container.NewHBox(layout.NewSpacer(),
&widget.Button{Text: "应用", Importance: widget.HighImportance, OnTapped: func() {
if s.fyneSettings.Scale == 0.0 {
s.chooseScale(1.0)
}
err := s.save()
if err != nil {
fyne.LogError("Failed on saving", err)
}
s.appliedScale(s.fyneSettings.Scale)
}})
return container.NewBorder(box, bottom, nil, nil, s.preview)
}
func (s *MySettings) appliedScale(value float32) {
for _, scale := range scales {
scale.preview.TextSize = theme.TextSize() * scale.scale / value
}
}
func (s *MySettings) chooseTheme(name string) {
if name == "" {
name = "light"
}
s.fyneSettings.ThemeName = name
s.preview.Image = s.createPreview()
canvas.Refresh(s.preview)
}
type overrideTheme interface {
OverrideTheme(fyne.Theme, string)
}
func (s *MySettings) createPreview() image.Image {
c := playground.NewSoftwareCanvas()
oldTheme := fyne.CurrentApp().Settings().Theme()
oldColor := fyne.CurrentApp().Settings().PrimaryColor()
variant := theme.VariantDark
if s.fyneSettings.ThemeName == "light" {
variant = theme.VariantLight
}
fyne.CurrentApp().Settings().(overrideTheme).OverrideTheme(&previewTheme{s.userTheme, variant}, s.fyneSettings.PrimaryColor)
empty := widget.NewLabel("")
tabs := container.NewAppTabs(
container.NewTabItemWithIcon("Home", theme.HomeIcon(), widget.NewLabel("Home")),
container.NewTabItemWithIcon("Browse", theme.ComputerIcon(), empty),
container.NewTabItemWithIcon("MySettings", theme.SettingsIcon(), empty),
container.NewTabItemWithIcon("Help", theme.HelpIcon(), empty))
tabs.SetTabLocation(container.TabLocationLeading)
showOverlay(c)
c.SetContent(tabs)
c.Resize(fyne.NewSize(380, 380))
// wait for indicator animation
time.Sleep(canvas.DurationShort)
img := c.Capture()
fyne.CurrentApp().Settings().(overrideTheme).OverrideTheme(oldTheme, oldColor)
return img
}
func (s *MySettings) chooseScale(value float32) {
s.fyneSettings.Scale = value
for _, scale := range scales {
if scale.scale == value {
scale.button.Importance = widget.HighImportance
} else {
scale.button.Importance = widget.MediumImportance
}
scale.button.Refresh()
}
}
func (s *MySettings) load() {
err := s.loadFromFile(s.fyneSettings.StoragePath())
if err != nil {
fyne.LogError("MySettings load error:", err)
}
}
func (s *MySettings) loadFromFile(path string) error {
file, err := os.Open(path) // #nosec
if err != nil {
if os.IsNotExist(err) {
err := os.MkdirAll(filepath.Dir(path), 0700)
if err != nil {
return err
}
return nil
}
return err
}
decode := json.NewDecoder(file)
return decode.Decode(&s.fyneSettings)
}
func (s *MySettings) save() error {
return s.saveToFile(s.fyneSettings.StoragePath())
}
func (s *MySettings) saveToFile(path string) error {
err := os.MkdirAll(filepath.Dir(path), 0700)
if err != nil { // this is not an exists error according to docs
return err
}
data, err := json.Marshal(&s.fyneSettings)
if err != nil {
return err
}
return ioutil.WriteFile(path, data, 0644)
}
type colorButton struct {
widget.BaseWidget
name string
color color.Color
s *MySettings
}
func newColorButton(n string, c color.Color, s *MySettings) *colorButton {
b := &colorButton{name: n, color: c, s: s}
b.ExtendBaseWidget(b)
return b
}
func (c *colorButton) CreateRenderer() fyne.WidgetRenderer {
r := canvas.NewRectangle(c.color)
r.StrokeWidth = 5
if c.name == c.s.fyneSettings.PrimaryColor {
r.StrokeColor = theme.PrimaryColor()
}
return &colorRenderer{c: c, rect: r, objs: []fyne.CanvasObject{r}}
}
func (c *colorButton) Tapped(_ *fyne.PointEvent) {
c.s.fyneSettings.PrimaryColor = c.name
for _, child := range c.s.colors {
child.Refresh()
}
c.s.preview.Image = c.s.createPreview()
canvas.Refresh(c.s.preview)
}
type colorRenderer struct {
c *colorButton
rect *canvas.Rectangle
objs []fyne.CanvasObject
}
func (c *colorRenderer) Layout(s fyne.Size) {
c.rect.Resize(s)
}
func (c *colorRenderer) MinSize() fyne.Size {
return fyne.NewSize(20, 20)
}
func (c *colorRenderer) Refresh() {
if c.c.name == c.c.s.fyneSettings.PrimaryColor {
c.rect.StrokeColor = theme.PrimaryColor()
} else {
c.rect.StrokeColor = color.Transparent
}
c.rect.FillColor = c.c.color
c.rect.Refresh()
}
func (c *colorRenderer) Objects() []fyne.CanvasObject {
return c.objs
}
func (c *colorRenderer) Destroy() {
}
type previewTheme struct {
t fyne.Theme
v fyne.ThemeVariant
}
func (p *previewTheme) Color(n fyne.ThemeColorName, v fyne.ThemeVariant) color.Color {
return p.t.Color(n, p.v)
}
func (p *previewTheme) Font(s fyne.TextStyle) fyne.Resource {
return p.t.Font(s)
}
func (p *previewTheme) Icon(n fyne.ThemeIconName) fyne.Resource {
return p.t.Icon(n)
}
func (p *previewTheme) Size(n fyne.ThemeSizeName) float32 {
return p.t.Size(n)
}
func showOverlay(c fyne.Canvas) {
username := widget.NewEntry()
password := widget.NewPasswordEntry()
form := widget.NewForm(widget.NewFormItem("Username", username),
widget.NewFormItem("Password", password))
form.OnCancel = func() {}
form.OnSubmit = func() {}
content := container.NewVBox(
widget.NewLabelWithStyle("Login demo", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}), form)
wrap := container.NewWithoutLayout(content)
wrap.Resize(content.MinSize().Add(fyne.NewSize(theme.Padding()*2, theme.Padding()*2)))
content.Resize(content.MinSize())
content.Move(fyne.NewPos(theme.Padding(), theme.Padding()))
over := container.NewMax(
canvas.NewRectangle(theme.ShadowColor()), container.NewCenter(wrap),
)
c.Overlays().Add(over)
c.Focus(username)
}
func (s *MySettings) makeScaleGroup(scale float32) *widget.Card {
scalePreviewBox := container.NewGridWithColumns(5, s.makeScalePreviews(scale)...)
scaleBox := container.NewGridWithColumns(5, s.makeScaleButtons()...)
return widget.NewCard("尺寸", "", container.NewVBox(scalePreviewBox, scaleBox, newRefreshMonitor(s)))
}
func (s *MySettings) makeScalePreviews(value float32) []fyne.CanvasObject {
var previews = make([]fyne.CanvasObject, len(scales))
for i, scale := range scales {
text := canvas.NewText("A", theme.ForegroundColor())
text.Alignment = fyne.TextAlignCenter
text.TextSize = theme.TextSize() * scale.scale / value
scale.preview = text
previews[i] = text
}
return previews
}
func (s *MySettings) refreshScalePreviews() {
for _, scale := range scales {
scale.preview.Color = theme.ForegroundColor()
}
}
func (s *MySettings) makeScaleButtons() []fyne.CanvasObject {
var buttons = make([]fyne.CanvasObject, len(scales))
for i, scale := range scales {
value := scale.scale
button := widget.NewButton(scale.name, func() {
s.chooseScale(value)
})
if s.fyneSettings.Scale == scale.scale {
button.Importance = widget.HighImportance
}
scale.button = button
buttons[i] = button
}
return buttons
}
func newRefreshMonitor(s *MySettings) *refreshMonitor {
r := &refreshMonitor{settings: s}
r.Hide()
return r
}
type scaleItems struct {
scale float32
name string
preview *canvas.Text
button *widget.Button
}
var scales = []*scaleItems{
{scale: 0.5, name: "很小"},
{scale: 0.8, name: "小"},
{scale: 1, name: "中等"},
{scale: 1.3, name: "大"},
{scale: 1.8, name: "很大"}}
// refreshMonitor is a simple widget that updates canvas components when the UI is asked to refresh.
// Captures theme and scale changes without the settings monitoring code.
type refreshMonitor struct {
widget.Label
settings *MySettings
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。