feature/ui - zatim ne uplne uhlazena ale celkem pouzitelna appka #1

Merged
luke-20 merged 17 commits from feature/ui into main 2025-09-28 21:05:52 +02:00
Showing only changes of commit 2d8e54b1c8 - Show all commits

65
ui.go
View File

@ -63,40 +63,21 @@ func (p *uiParts) showToast(msg string) {
}) })
} }
// theme toggle // custom fixed dark theme
// Simple theme variants using built-in with preference respecting variant type simpleTheme struct{}
// lightOverride & darkOverride implement fyne.Theme with adjusted primary/background colors.
// minimal two themes (light/dark) customizing a couple of colors
type simpleTheme struct{ dark bool }
func (s simpleTheme) Color(n fyne.ThemeColorName, v fyne.ThemeVariant) color.Color { func (simpleTheme) Color(n fyne.ThemeColorName, v fyne.ThemeVariant) color.Color {
base := theme.DefaultTheme().Color(n, v) base := theme.DefaultTheme().Color(n, v)
if !s.dark {
return base
}
// dark tweak: slightly desaturate backgrounds
if n == theme.ColorNameBackground || n == theme.ColorNameButton { if n == theme.ColorNameBackground || n == theme.ColorNameButton {
return color.NRGBA{R: 30, G: 34, B: 39, A: 255} return color.NRGBA{R: 30, G: 34, B: 39, A: 255}
} }
return base return base
} }
func (s simpleTheme) Font(st fyne.TextStyle) fyne.Resource { return theme.DefaultTheme().Font(st) } func (simpleTheme) Font(st fyne.TextStyle) fyne.Resource { return theme.DefaultTheme().Font(st) }
func (s simpleTheme) Icon(n fyne.ThemeIconName) fyne.Resource { return theme.DefaultTheme().Icon(n) } func (simpleTheme) Icon(n fyne.ThemeIconName) fyne.Resource { return theme.DefaultTheme().Icon(n) }
func (s simpleTheme) Size(n fyne.ThemeSizeName) float32 { return theme.DefaultTheme().Size(n) } func (simpleTheme) Size(n fyne.ThemeSizeName) float32 { return theme.DefaultTheme().Size(n) }
var currentDark bool var forceDark = true
func newThemeToggle(app fyne.App, parts *uiParts) *widget.Button {
return widget.NewButton("🌗 Motiv", func() {
currentDark = !currentDark
app.Settings().SetTheme(simpleTheme{dark: currentDark})
if currentDark {
parts.showToast("Dark")
} else {
parts.showToast("Light")
}
})
}
// Build key section // Build key section
func buildIdentityTab(parts *uiParts, svc ServiceFacade) fyne.CanvasObject { func buildIdentityTab(parts *uiParts, svc ServiceFacade) fyne.CanvasObject {
@ -158,15 +139,16 @@ func buildEncryptTab(parts *uiParts, svc ServiceFacade) fyne.CanvasObject {
}(m, p) }(m, p)
} }
msgBtns := buttonTile( msgBtns := buttonTile(
widget.NewButton("Clear+Paste", func() { parts.msg.SetText(""); parts.msg.SetText(fyne.CurrentApp().Clipboard().Content()) }),
widget.NewButton("Encrypt", encAction), widget.NewButton("Encrypt", encAction),
widget.NewButton("Copy", func() { copyClip(parts.cipherOut.Text, parts) }), widget.NewButton("Copy encrypted", func() { copyClip(parts.cipherOut.Text, parts) }),
) )
resultBtns := buttonTile(widget.NewButton("Copy", func() { copyClip(parts.cipherOut.Text, parts) }))
group := container.NewVBox( group := container.NewVBox(
widget.NewLabelWithStyle("Šifrování", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}), widget.NewLabelWithStyle("Šifrování", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
widget.NewLabel("Veřejný klíč příjemce"), peerBtns, parts.peer, widget.NewLabel("Veřejný klíč příjemce"), peerBtns, parts.peer,
widget.NewLabel("Zpráva"), msgBtns, parts.msg, widget.NewLabel("Zpráva"), msgBtns, parts.msg,
widget.NewLabel("Výsledek"), resultBtns, parts.cipherOut, widget.NewLabel("Výsledek"), parts.cipherOut,
) )
return container.NewVScroll(group) return container.NewVScroll(group)
} }
@ -196,7 +178,7 @@ func buildDecryptTab(parts *uiParts, svc ServiceFacade) fyne.CanvasObject {
decryptAction() decryptAction()
}), }),
// widget.NewButton("Decrypt", decryptAction), // widget.NewButton("Decrypt", decryptAction),
widget.NewButton("Clear", func() { parts.payload.SetText("") }), widget.NewButton("Clear", func() { parts.payload.SetText(""); parts.plainOut.SetText("") }),
) )
plainBtns := buttonTile(widget.NewButton("Copy", func() { copyClip(parts.plainOut.Text, parts) })) plainBtns := buttonTile(widget.NewButton("Copy", func() { copyClip(parts.plainOut.Text, parts) }))
group := container.NewVBox( group := container.NewVBox(
@ -214,35 +196,22 @@ func buildTabbedUI(parts *uiParts, svc ServiceFacade) fyne.CanvasObject {
tabs := container.NewAppTabs(idTab, encTab, decTab) tabs := container.NewAppTabs(idTab, encTab, decTab)
tabs.SetTabLocation(container.TabLocationTop) tabs.SetTabLocation(container.TabLocationTop)
// top bar with theme toggle // apply fixed dark theme once
themeBtn := newThemeToggle(fyne.CurrentApp(), parts) fyne.CurrentApp().Settings().SetTheme(simpleTheme{})
// load preferences
prefs := fyne.CurrentApp().Preferences() prefs := fyne.CurrentApp().Preferences()
if prefs != nil { if prefs != nil {
idx := prefs.IntWithFallback("lastTab", 0) idx := prefs.IntWithFallback("lastTab", 0)
if idx >= 0 && idx < len(tabs.Items) { if idx >= 0 && idx < len(tabs.Items) {
tabs.SelectIndex(idx) tabs.SelectIndex(idx)
} }
if prefs.Bool("darkTheme") { // only persist lastTab now
currentDark = true
fyne.CurrentApp().Settings().SetTheme(simpleTheme{dark: true})
}
} }
tabs.OnSelected = func(ti *container.TabItem) { tabs.OnSelected = func(ti *container.TabItem) {
if prefs != nil { if prefs != nil {
prefs.SetInt("lastTab", tabs.SelectedIndex()) prefs.SetInt("lastTab", tabs.SelectedIndex())
} }
} }
// wrap toggle to persist theme choice return container.NewBorder(nil, parts.toastLabel, nil, nil, tabs)
oldAction := themeBtn.OnTapped
themeBtn.OnTapped = func() {
oldAction()
if prefs != nil {
prefs.SetBool("darkTheme", currentDark)
}
}
topBar := container.NewBorder(nil, nil, nil, themeBtn, tabs)
return container.NewBorder(nil, parts.toastLabel, nil, nil, topBar)
} }
// buttonTile renders buttons above a related entry with a colored background spanning full width // buttonTile renders buttons above a related entry with a colored background spanning full width
@ -256,7 +225,7 @@ func buttonTile(btns ...fyne.CanvasObject) fyne.CanvasObject {
} // wrap into multiple rows if many } // wrap into multiple rows if many
grid := container.NewGridWithColumns(cols, btns...) grid := container.NewGridWithColumns(cols, btns...)
bgColor := color.NRGBA{R: 240, G: 240, B: 245, A: 255} bgColor := color.NRGBA{R: 240, G: 240, B: 245, A: 255}
if currentDark { if forceDark {
bgColor = color.NRGBA{R: 50, G: 54, B: 60, A: 255} bgColor = color.NRGBA{R: 50, G: 54, B: 60, A: 255}
} }
rect := canvas.NewRectangle(bgColor) rect := canvas.NewRectangle(bgColor)