feat: add UI layer (theme, components, screens, main window)
- 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>
This commit is contained in:
@@ -1,2 +1,94 @@
|
||||
// package components provides reusable Fyne widgets (avatar, progress bar).
|
||||
// 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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user