- theme: MinecraftTheme — dark palette with green accents - components: ServerCard, ProgressBar, PlayButton, SettingsButton, LogoutButton, AvatarImage - screens: MainScreen (BorderLayout: sidebar + center + bottom bar), LoginScreen (modal form), SettingsScreen (RAM slider + JVM args) - ui.Launch: wires theme, session, settings into Fyne app - main.go: delegates to ui.Launch, loads config - fix: nil-session guard in MainScreen username display Co-Authored-By: OWL <noreply@anthropic.com>
95 lines
2.2 KiB
Go
95 lines
2.2 KiB
Go
// package components provides reusable Fyne widgets for the launcher UI.
|
||
package components
|
||
|
||
import (
|
||
"image/color"
|
||
|
||
"fyne.io/fyne/v2"
|
||
"fyne.io/fyne/v2/canvas"
|
||
"fyne.io/fyne/v2/container"
|
||
"fyne.io/fyne/v2/widget"
|
||
)
|
||
|
||
// ServerCard displays a single modpack entry in the sidebar.
|
||
func ServerCard(name string, selected bool, onTap func()) fyne.CanvasObject {
|
||
bg := canvas.NewRectangle(color.Transparent)
|
||
bg.SetMinSize(fyne.NewSize(180, 48))
|
||
|
||
label := widget.NewLabel(name)
|
||
label.TextStyle.Bold = selected
|
||
|
||
content := container.NewBorder(nil, nil,
|
||
nil, nil,
|
||
label,
|
||
)
|
||
|
||
card := container.NewStack(bg, content)
|
||
|
||
btn := widget.NewButton("", onTap)
|
||
btn.Importance = widget.LowImportance
|
||
|
||
return container.NewStack(card, btn)
|
||
}
|
||
|
||
// ProgressBar wraps widget.ProgressBar with show/hide helpers.
|
||
type ProgressBar struct {
|
||
*widget.ProgressBar
|
||
hidden bool
|
||
}
|
||
|
||
// NewProgressBar creates a new progress bar initialized to 0 and hidden.
|
||
func NewProgressBar() *ProgressBar {
|
||
pb := widget.NewProgressBar()
|
||
pb.Hide()
|
||
return &ProgressBar{
|
||
ProgressBar: pb,
|
||
hidden: true,
|
||
}
|
||
}
|
||
|
||
// SetProgress sets the value [0…1] and shows the bar.
|
||
func (pb *ProgressBar) SetProgress(v float64) {
|
||
pb.SetValue(v)
|
||
if pb.hidden {
|
||
pb.Show()
|
||
pb.hidden = false
|
||
}
|
||
}
|
||
|
||
// Done hides the progress bar and resets it.
|
||
func (pb *ProgressBar) Done() {
|
||
pb.SetValue(0)
|
||
pb.Hide()
|
||
pb.hidden = true
|
||
}
|
||
|
||
// PlayButton creates the accent "PLAY" button.
|
||
func PlayButton(onTap func()) *widget.Button {
|
||
btn := widget.NewButton("▶ PLAY", onTap)
|
||
btn.Importance = widget.HighImportance
|
||
return btn
|
||
}
|
||
|
||
// SettingsButton creates the small settings (gear) button.
|
||
func SettingsButton(onTap func()) *widget.Button {
|
||
btn := widget.NewButton("⚙", onTap)
|
||
btn.Importance = widget.LowImportance
|
||
return btn
|
||
}
|
||
|
||
// LogoutButton creates the logout button.
|
||
func LogoutButton(onTap func()) *widget.Button {
|
||
btn := widget.NewButton("Выйти", onTap)
|
||
btn.Importance = widget.LowImportance
|
||
return btn
|
||
}
|
||
|
||
// AvatarImage returns a placeholder avatar (64×64 colored square).
|
||
// TODO: render 8×64 face from skin PNG.
|
||
func AvatarImage() *canvas.Image {
|
||
img := canvas.NewImageFromResource(nil)
|
||
img.SetMinSize(fyne.NewSize(64, 64))
|
||
img.FillMode = canvas.ImageFillContain
|
||
return img
|
||
}
|