refactor: another ui test
This commit is contained in:
parent
a8ed9c9ed1
commit
789ee25e1f
4 changed files with 182 additions and 86 deletions
62
cmd/main.go
62
cmd/main.go
|
|
@ -16,8 +16,7 @@ import (
|
|||
|
||||
func main() {
|
||||
myApp := app.NewWithID("com.example.kettlebell-tracker")
|
||||
// myApp.Settings().SetTheme(theme.DarkTheme())
|
||||
mainWIndow := myApp.NewWindow("Kettlebell Programm Tracker")
|
||||
mainWindow := myApp.NewWindow("Kettlebell Programm Tracker")
|
||||
|
||||
dbDir := myApp.Storage().RootURI().Path()
|
||||
dbPath := filepath.Join(dbDir, "kb_training.db")
|
||||
|
|
@ -32,23 +31,50 @@ func main() {
|
|||
apiService := services.NewApiService(myApp.UniqueID())
|
||||
|
||||
trainingService := services.NewTrainingService(dbService, settingsService, apiService)
|
||||
// Dark Mode nach Systemeinstellung
|
||||
if fyne.CurrentDevice().IsMobile() {
|
||||
myApp.Settings().SetTheme(theme.DarkTheme())
|
||||
}
|
||||
|
||||
homeScreen := ui.MakeHomeScreen()
|
||||
settingsScreen := ui.MakeSettingsScreen(settingsService, mainWIndow)
|
||||
historyScreen := ui.MakeHistoryScreen(dbService, mainWIndow)
|
||||
trainingScreen := ui.MakeTrainingScreen(trainingService, settingsService, mainWIndow)
|
||||
// mainWindow := myApp.NewWindow("Kettlebell Tracker")
|
||||
mainWindow.SetMaster()
|
||||
|
||||
tabs := container.NewAppTabs(
|
||||
container.NewTabItemWithIcon("Home", theme.HomeIcon(), homeScreen),
|
||||
container.NewTabItemWithIcon("Training", theme.MediaPlayIcon(), trainingScreen),
|
||||
container.NewTabItemWithIcon("Historie", theme.HistoryIcon(), historyScreen),
|
||||
container.NewTabItemWithIcon("Einstellungen", theme.SettingsIcon(), settingsScreen),
|
||||
)
|
||||
// Responsive Layout
|
||||
content := container.NewMax()
|
||||
nav := buildNavigation(content, mainWindow, dbService, settingsService, apiService, trainingService) // Eigene Nav-Komponente
|
||||
|
||||
tabs.SetTabLocation(container.TabLocationBottom)
|
||||
|
||||
mainWIndow.Resize(fyne.NewSize(400, 600))
|
||||
mainWIndow.SetContent(tabs)
|
||||
mainWIndow.SetMaster()
|
||||
mainWIndow.ShowAndRun()
|
||||
mainWindow.SetContent(container.NewBorder(nav, nil, nil, nil, content))
|
||||
mainWindow.Resize(fyne.NewSize(400, 600))
|
||||
mainWindow.ShowAndRun()
|
||||
}
|
||||
|
||||
func buildNavigation(content *fyne.Container, mainWindow fyne.Window, dbService *data.DatabaseService, settingsService *services.SettingsService, apiService *services.ApiService, trainingService *services.TrainingService) fyne.CanvasObject {
|
||||
navItems := []struct {
|
||||
icon fyne.Resource
|
||||
title string
|
||||
view func() fyne.CanvasObject
|
||||
}{
|
||||
{theme.HomeIcon(), "Home", ui.MakeHomeScreen},
|
||||
{theme.MediaPlayIcon(), "Training", func() fyne.CanvasObject {
|
||||
return ui.MakeTrainingScreen(trainingService, settingsService, mainWindow)
|
||||
}},
|
||||
{theme.HistoryIcon(), "Historie", func() fyne.CanvasObject {
|
||||
return ui.MakeHistoryScreen(dbService, mainWindow)
|
||||
}},
|
||||
{theme.SettingsIcon(), "Einstellungen", func() fyne.CanvasObject {
|
||||
return ui.MakeSettingsScreen(settingsService, mainWindow)
|
||||
}},
|
||||
}
|
||||
|
||||
nav := container.NewAppTabs()
|
||||
for _, item := range navItems {
|
||||
nav.Append(container.NewTabItemWithIcon(item.title, item.icon, item.view()))
|
||||
}
|
||||
nav.SetTabLocation(container.TabLocationBottom)
|
||||
nav.OnSelected = func(t *container.TabItem) {
|
||||
content.Objects = []fyne.CanvasObject{t.Content}
|
||||
content.Refresh()
|
||||
}
|
||||
|
||||
return nav
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,9 +84,36 @@ func MakeHistoryScreen(db *data.DatabaseService, parent fyne.Window) fyne.Canvas
|
|||
refreshData()
|
||||
|
||||
// Toolbar mit Refresh-Button
|
||||
toolbar := widget.NewToolbar(
|
||||
widget.NewToolbarAction(theme.ViewRefreshIcon(), refreshData),
|
||||
// toolbar := widget.NewToolbar(
|
||||
// widget.NewToolbarAction(theme.ViewRefreshIcon(), refreshData),
|
||||
// )
|
||||
table := widget.NewTable(
|
||||
func() (int, int) { return len(history), 4 },
|
||||
func() fyne.CanvasObject { return widget.NewLabel("Template") },
|
||||
func(id widget.TableCellID, cell fyne.CanvasObject) {
|
||||
session := history[id.Row]
|
||||
label := cell.(*widget.Label)
|
||||
switch id.Col {
|
||||
case 0:
|
||||
label.SetText(session.Date.Format("02.01"))
|
||||
case 1:
|
||||
label.SetText(fmt.Sprintf("%d Sätze", session.Sets))
|
||||
case 2:
|
||||
label.SetText(fmt.Sprintf("%.1fkg", session.WeightLeft))
|
||||
case 3:
|
||||
label.SetText(formatDuration(session.Duration))
|
||||
}
|
||||
},
|
||||
)
|
||||
table.SetColumnWidth(0, 80)
|
||||
table.SetColumnWidth(1, 100)
|
||||
table.SetColumnWidth(2, 80)
|
||||
table.SetColumnWidth(3, 80)
|
||||
|
||||
return container.NewBorder(toolbar, nil, nil, nil, container.NewStack(list, placeholder))
|
||||
// return container.NewBorder(toolbar, nil, nil, nil, container.NewStack(list, placeholder))
|
||||
return container.NewBorder(
|
||||
widget.NewToolbar(widget.NewToolbarAction(theme.ViewRefreshIcon(), refreshData)),
|
||||
nil, nil, nil,
|
||||
table,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,29 +8,69 @@ import (
|
|||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
// MakeHomeScreen erstellt den statischen Willkommensbildschirm.
|
||||
// // MakeHomeScreen erstellt den statischen Willkommensbildschirm.
|
||||
// func MakeHomeScreen() fyne.CanvasObject {
|
||||
// primaryColor := theme.PrimaryColor()
|
||||
//
|
||||
// title := canvas.NewText("Willkommen beim Giant Programm Tracker!", primaryColor)
|
||||
// title.TextStyle.Bold = true
|
||||
// title.Alignment = fyne.TextAlignCenter
|
||||
// title.TextSize = 24
|
||||
//
|
||||
// subtitle := widget.NewLabel("Verwalte deine Kettlebell-Trainings effizient.")
|
||||
// subtitle.Alignment = fyne.TextAlignCenter
|
||||
//
|
||||
// icon := widget.NewIcon(theme.MediaPlayIcon())
|
||||
// icon.Resize(fyne.NewSize(150, 150))
|
||||
//
|
||||
// // Layout erstellen, das dem Flutter-Layout entspricht
|
||||
// content := container.NewVBox(
|
||||
// title,
|
||||
// widget.NewSeparator(),
|
||||
// subtitle,
|
||||
// container.NewPadded(icon), // Icon mit etwas Abstand
|
||||
// )
|
||||
//
|
||||
// // Zentriert den Inhalt
|
||||
// return container.NewCenter(content)
|
||||
// }
|
||||
|
||||
func MakeHomeScreen() fyne.CanvasObject {
|
||||
primaryColor := theme.PrimaryColor()
|
||||
primary := theme.PrimaryColor()
|
||||
secondary := theme.WarningColor()
|
||||
|
||||
title := canvas.NewText("Willkommen beim Giant Programm Tracker!", primaryColor)
|
||||
title.TextStyle.Bold = true
|
||||
title.Alignment = fyne.TextAlignCenter
|
||||
title.TextSize = 24
|
||||
// Header mit personalisierter Begrüßung
|
||||
greeting := canvas.NewText("Dein Kettlebell Fortschritt", primary)
|
||||
greeting.TextSize = 20
|
||||
greeting.Alignment = fyne.TextAlignCenter
|
||||
|
||||
subtitle := widget.NewLabel("Verwalte deine Kettlebell-Trainings effizient.")
|
||||
subtitle.Alignment = fyne.TextAlignCenter
|
||||
// Fortschrittsvisualisierung (Beispiel)
|
||||
progressRing := canvas.NewCircle(secondary)
|
||||
progressRing.StrokeWidth = 8
|
||||
progressRing.StrokeColor = primary
|
||||
ringContainer := container.NewCenter(progressRing)
|
||||
|
||||
icon := widget.NewIcon(theme.MediaPlayIcon())
|
||||
icon.Resize(fyne.NewSize(150, 150))
|
||||
// Programmstatus
|
||||
programInfo := widget.NewLabel("Aktuell: Giant - Woche 2/4")
|
||||
programInfo.Alignment = fyne.TextAlignCenter
|
||||
|
||||
// Layout erstellen, das dem Flutter-Layout entspricht
|
||||
content := container.NewVBox(
|
||||
title,
|
||||
// Primäre Aktion
|
||||
startBtn := widget.NewButtonWithIcon("Training starten", theme.MediaPlayIcon(), func() {})
|
||||
startBtn.Importance = widget.HighImportance
|
||||
|
||||
return container.NewVBox(
|
||||
container.NewPadded(greeting),
|
||||
ringContainer,
|
||||
programInfo,
|
||||
container.NewCenter(startBtn),
|
||||
widget.NewSeparator(),
|
||||
subtitle,
|
||||
container.NewPadded(icon), // Icon mit etwas Abstand
|
||||
buildQuickStats(), // Eigene Komponente für Statistiken
|
||||
)
|
||||
}
|
||||
|
||||
func buildQuickStats() fyne.CanvasObject {
|
||||
return container.NewGridWithColumns(2,
|
||||
widget.NewCard("Letztes Training", "12 Sätze", nil),
|
||||
widget.NewCard("Aktuelle Serie", "5 Tage", nil),
|
||||
)
|
||||
|
||||
// Zentriert den Inhalt
|
||||
return container.NewCenter(content)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"git.patanix.de/git/kettlebell-app/internal/services"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/canvas"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/dialog"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
|
|
@ -75,35 +76,35 @@ func MakeTrainingScreen(ts *services.TrainingService, ss *services.SettingsServi
|
|||
}
|
||||
}
|
||||
|
||||
startAction := func() {
|
||||
settings := ss.LoadSettings()
|
||||
ts.StartTraining(settings.TrainingTimeMinutes, settings.GoalSets)
|
||||
updateUI()
|
||||
|
||||
mainTimer = time.NewTicker(time.Second)
|
||||
go func() {
|
||||
for range mainTimer.C {
|
||||
if ts.State.RemainingSeconds <= 0 {
|
||||
stopTimers()
|
||||
fyne.CurrentApp().SendNotification(&fyne.Notification{
|
||||
Title: "Zeit abgelaufen!",
|
||||
Content: "Training wird automatisch gespeichert.",
|
||||
})
|
||||
finishButton.OnTapped()
|
||||
return
|
||||
}
|
||||
ts.Tick()
|
||||
updateUI()
|
||||
}
|
||||
}()
|
||||
|
||||
lastSetTimer = time.NewTicker(time.Second)
|
||||
go func() {
|
||||
for range lastSetTimer.C {
|
||||
ts.TickLastSetTimer()
|
||||
}
|
||||
}()
|
||||
}
|
||||
// startAction := func() {
|
||||
// settings := ss.LoadSettings()
|
||||
// ts.StartTraining(settings.TrainingTimeMinutes, settings.GoalSets)
|
||||
// updateUI()
|
||||
//
|
||||
// mainTimer = time.NewTicker(time.Second)
|
||||
// go func() {
|
||||
// for range mainTimer.C {
|
||||
// if ts.State.RemainingSeconds <= 0 {
|
||||
// stopTimers()
|
||||
// fyne.CurrentApp().SendNotification(&fyne.Notification{
|
||||
// Title: "Zeit abgelaufen!",
|
||||
// Content: "Training wird automatisch gespeichert.",
|
||||
// })
|
||||
// finishButton.OnTapped()
|
||||
// return
|
||||
// }
|
||||
// ts.Tick()
|
||||
// updateUI()
|
||||
// }
|
||||
// }()
|
||||
//
|
||||
// lastSetTimer = time.NewTicker(time.Second)
|
||||
// go func() {
|
||||
// for range lastSetTimer.C {
|
||||
// ts.TickLastSetTimer()
|
||||
// }
|
||||
// }()
|
||||
// }
|
||||
|
||||
setAction := func() {
|
||||
ts.CompleteSet()
|
||||
|
|
@ -135,27 +136,29 @@ func MakeTrainingScreen(ts *services.TrainingService, ss *services.SettingsServi
|
|||
updateUI()
|
||||
}
|
||||
|
||||
startButton = widget.NewButtonWithIcon("Start", theme.MediaPlayIcon(), startAction)
|
||||
setButton = widget.NewButtonWithIcon("Satz", theme.ConfirmIcon(), setAction)
|
||||
finishButton = widget.NewButtonWithIcon("Beenden", theme.MediaStopIcon(), finishAction)
|
||||
timerDisplay := canvas.NewText("00:00", theme.PrimaryColor())
|
||||
timerDisplay.TextSize = 48
|
||||
timerDisplay.Alignment = fyne.TextAlignCenter
|
||||
|
||||
updateUI()
|
||||
exerciseInfo := widget.NewLabel("Aktuelle Übung: Double Clean & Press")
|
||||
exerciseInfo.Alignment = fyne.TextAlignCenter
|
||||
|
||||
headerCard := widget.NewCard("", "", container.NewVBox(programLabel, blockDayLabel, repsLabel))
|
||||
timerCard := widget.NewCard("", "", container.NewVBox(
|
||||
widget.NewLabelWithStyle("Verbleibende Zeit", fyne.TextAlignCenter, fyne.TextStyle{}),
|
||||
timerLabel,
|
||||
progressBar,
|
||||
progressLabel,
|
||||
))
|
||||
progressRing := canvas.NewCircle(theme.BackgroundColor())
|
||||
progressRing.StrokeWidth = 5
|
||||
progressRing.StrokeColor = theme.PrimaryColor()
|
||||
|
||||
actionButtons := container.NewGridWithColumns(3, startButton, setButton, finishButton)
|
||||
historyCard := widget.NewCard("Satz-Historie", "", setHistoryList)
|
||||
// Vereinfachte Steuerung
|
||||
setBtn := widget.NewButtonWithIcon("Satz", theme.ConfirmIcon(), setAction)
|
||||
finishBtn := widget.NewButtonWithIcon("Beenden", theme.CancelIcon(), finishAction)
|
||||
actionBar := container.NewGridWithColumns(2, setBtn, finishBtn)
|
||||
|
||||
return container.NewVBox(
|
||||
headerCard,
|
||||
timerCard,
|
||||
actionButtons,
|
||||
historyCard,
|
||||
// Tastatur-Shortcut
|
||||
canvasObj := container.NewVBox(
|
||||
container.NewCenter(timerDisplay),
|
||||
container.NewCenter(exerciseInfo),
|
||||
container.NewCenter(progressRing),
|
||||
actionBar,
|
||||
)
|
||||
|
||||
return container.NewPadded(canvasObj)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue