summaryrefslogtreecommitdiff
path: root/internal/ui/helpers.go
diff options
context:
space:
mode:
authorspiperac <[email protected]>2026-06-15 06:42:13 +0200
committerspiperac <[email protected]>2026-06-15 06:42:13 +0200
commit0a477fd288d064d265395c88dbd0f261b723804e (patch)
tree9b129f8f41c907285b89ed8385679934bb59c14f /internal/ui/helpers.go
Initial release
Diffstat (limited to 'internal/ui/helpers.go')
-rw-r--r--internal/ui/helpers.go91
1 files changed, 91 insertions, 0 deletions
diff --git a/internal/ui/helpers.go b/internal/ui/helpers.go
new file mode 100644
index 0000000..6b706d4
--- /dev/null
+++ b/internal/ui/helpers.go
@@ -0,0 +1,91 @@
+package ui
+
+import (
+ "fmt"
+ "strings"
+
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/dialog"
+ "fyne.io/fyne/v2/widget"
+ "github.com/shiv/internal/logger"
+)
+
+func closeOnEscape(win fyne.Window, closeFn func()) {
+ previous := win.Canvas().OnTypedKey()
+ win.Canvas().SetOnTypedKey(func(keyEvent *fyne.KeyEvent) {
+ if keyEvent.Name == fyne.KeyEscape {
+ closeFn()
+ win.Canvas().SetOnTypedKey(previous)
+ }
+ })
+}
+
+// newBoldLabel returns a label with bold text style.
+func newBoldLabel(text string) *widget.Label {
+ label := widget.NewLabel(text)
+ label.TextStyle = fyne.TextStyle{Bold: true}
+ return label
+}
+
+// recoverPanic logs a panic without crashing the process.
+// Use as: defer recoverPanic("context description")
+func recoverPanic(context string) {
+ if r := recover(); r != nil {
+ logger.Error("panic in %s: %v", context, r)
+ }
+}
+
+func hasSuffix(s string, suffixes ...string) bool {
+ for _, suffix := range suffixes {
+ if strings.HasSuffix(s, suffix) {
+ return true
+ }
+ }
+ return false
+}
+
+// saveToFile opens a file-save dialog and writes content to the chosen path.
+func saveToFile(content []byte, defaultName string, win fyne.Window) {
+ d := dialog.NewFileSave(func(wc fyne.URIWriteCloser, err error) {
+ if err != nil || wc == nil {
+ return
+ }
+ defer wc.Close()
+ if _, err := wc.Write(content); err != nil {
+ dialog.ShowError(err, win)
+ }
+ }, win)
+ d.SetFileName(defaultName)
+ d.Show()
+}
+
+// copyButton returns a button labelled "Copy" that copies text to clipboard.
+func copyButton(label string, text func() string) *widget.Button {
+ return widget.NewButton(label, func() {
+ fyne.CurrentApp().Clipboard().SetContent(text())
+ })
+}
+
+// paneHeader returns a border container with a bold label on the left and
+// optional extra widgets on the right, used consistently across all detail panes.
+func paneHeader(title string, right ...fyne.CanvasObject) fyne.CanvasObject {
+ var rightObj fyne.CanvasObject
+ if len(right) == 1 {
+ rightObj = right[0]
+ } else if len(right) > 1 {
+ rightObj = container.NewHBox(right...)
+ }
+ return container.NewBorder(nil, nil, newBoldLabel(title), rightObj)
+}
+
+func formatSize(bytes int) string {
+ switch {
+ case bytes >= 1<<20:
+ return fmt.Sprintf("%.1fMB", float64(bytes)/float64(1<<20))
+ case bytes >= 1<<10:
+ return fmt.Sprintf("%.1fKB", float64(bytes)/float64(1<<10))
+ default:
+ return fmt.Sprintf("%dB", bytes)
+ }
+}