feat(ui): Add lock icon to disabled modules for better visibility

Enhanced disabled module visual indicators:
- Added lock icon (🔒) in top-right corner of disabled tiles
- Lock icon shows/hides dynamically based on module availability
- Improved Refresh() to handle dynamic enable/disable state changes
- Updated renderer to include lock icon in layout and objects list

This makes it immediately clear which modules are available and which require missing dependencies, addressing the issue where adaptive text colors made disabled modules less distinguishable.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Stu Leak 2025-12-31 12:25:24 -05:00
parent 3b99cad32b
commit 89824f7859

View File

@ -168,10 +168,19 @@ func (m *ModuleTile) CreateRenderer() fyne.WidgetRenderer {
txt.Alignment = fyne.TextAlignCenter
txt.TextSize = 20
// Lock icon for disabled modules
lockIcon := canvas.NewText("🔒", color.NRGBA{R: 200, G: 200, B: 200, A: 255})
lockIcon.TextSize = 16
lockIcon.Alignment = fyne.TextAlignCenter
if m.enabled {
lockIcon.Hide()
}
return &moduleTileRenderer{
tile: m,
bg: bg,
label: txt,
tile: m,
bg: bg,
label: txt,
lockIcon: lockIcon,
}
}
@ -182,9 +191,10 @@ func (m *ModuleTile) Tapped(*fyne.PointEvent) {
}
type moduleTileRenderer struct {
tile *ModuleTile
bg *canvas.Rectangle
label *canvas.Text
tile *ModuleTile
bg *canvas.Rectangle
label *canvas.Text
lockIcon *canvas.Text
}
func (r *moduleTileRenderer) Layout(size fyne.Size) {
@ -195,6 +205,15 @@ func (r *moduleTileRenderer) Layout(size fyne.Size) {
x := (size.Width - labelSize.Width) / 2
y := (size.Height - labelSize.Height) / 2
r.label.Move(fyne.NewPos(x, y))
// Position lock icon in top-right corner
if r.lockIcon != nil {
lockSize := r.lockIcon.MinSize()
r.lockIcon.Resize(lockSize)
lockX := size.Width - lockSize.Width - 4
lockY := float32(4)
r.lockIcon.Move(fyne.NewPos(lockX, lockY))
}
}
func (r *moduleTileRenderer) MinSize() fyne.Size {
@ -202,7 +221,23 @@ func (r *moduleTileRenderer) MinSize() fyne.Size {
}
func (r *moduleTileRenderer) Refresh() {
r.bg.FillColor = r.tile.color
// Update tile color and text color based on enabled state
if r.tile.enabled {
r.bg.FillColor = r.tile.color
r.label.Color = getContrastColor(r.tile.color)
if r.lockIcon != nil {
r.lockIcon.Hide()
}
} else {
// Dim disabled tiles
if c, ok := r.tile.color.(color.NRGBA); ok {
r.bg.FillColor = color.NRGBA{R: c.R / 3, G: c.G / 3, B: c.B / 3, A: c.A}
}
r.label.Color = color.NRGBA{R: 100, G: 100, B: 100, A: 255}
if r.lockIcon != nil {
r.lockIcon.Show()
}
}
// Apply visual feedback based on state
if r.tile.flashing {
@ -222,12 +257,15 @@ func (r *moduleTileRenderer) Refresh() {
r.bg.Refresh()
r.label.Text = r.tile.label
r.label.Refresh()
if r.lockIcon != nil {
r.lockIcon.Refresh()
}
}
func (r *moduleTileRenderer) Destroy() {}
func (r *moduleTileRenderer) Objects() []fyne.CanvasObject {
return []fyne.CanvasObject{r.bg, r.label}
return []fyne.CanvasObject{r.bg, r.label, r.lockIcon}
}
// TintedBar creates a colored bar container