diff --git a/internal/page/audioDevices.go b/internal/page/audioDevices.go index b4fd897..7b4afde 100644 --- a/internal/page/audioDevices.go +++ b/internal/page/audioDevices.go @@ -8,23 +8,22 @@ import ( "rhemawavetech.com/rhemawave/internal/colors" "rhemawavetech.com/rhemawave/internal/db" "rhemawavetech.com/rhemawave/internal/fontManager" - "rhemawavetech.com/rhemawave/internal/mixer" + "rhemawavetech.com/rhemawave/internal/logger" "rhemawavetech.com/rhemawave/internal/shaderManager" ) type AudioDevices struct { Base - font *fontManager.FontEntry - textShader *shaderManager.Shader - solidShader *shaderManager.Shader - title StringItem - prompt StringItem - devices []StringItem - highlightIndex int - selectedIndex int - verticalMargin int32 - CfgPtr *db.AppConfig - // DbPtr *gorm.DB + font *fontManager.FontEntry + textShader *shaderManager.Shader + solidShader *shaderManager.Shader + title StringItem + prompt StringItem + AudioStatusToggle StringItem + highlightIndex int + selectedIndex int + verticalMargin int32 + CfgPtr *db.AppConfig } func (p *AudioDevices) Init(ctx *PageCtx) error { @@ -76,32 +75,6 @@ func (p *AudioDevices) Init(ctx *PageCtx) error { } p.prompt.Scale(itemScale) - // Get list of audio output devices - devices := mixer.ListDevices() - if len(devices) == 0 { - // Create a default entry so the page doesn't break - devices = []string{"System Default"} - } - - // Get currently selected device from database - currentDevice := p.Context.CfgPtr.SelectedAudioDevice - - // Create UI items for each device - for i, name := range devices { // Iterate over the devices - item, err := NewStringItem(name, p.font, colors.White) // Create a new string string texture - if err != nil { - return fmt.Errorf("failed to create device item name: %w", err) - } - item.Scale(itemScale) // Scale the new string item - p.devices = append(p.devices, item) // Add the new scaled string item to the list of items - - // Mark currently selected device - if name == currentDevice { - p.selectedIndex = i - p.highlightIndex = i // Start with cursor on current device - } - } - on := p.Context.CfgPtr.AudioEnabled audioStatus := "Turn Audio On" @@ -117,12 +90,26 @@ func (p *AudioDevices) Init(ctx *PageCtx) error { // Scale the new option audioStatusStringItem.Scale(itemScale) - p.devices = append(p.devices, audioStatusStringItem) - p.layout() return nil } +func (p *AudioDevices) CreateAudioStatusItem() error { + on := p.Context.CfgPtr.AudioEnabled + statusString := "Turn Audio Off" // The audio is ON + color := colors.Green + if !on { + statusString = "Turn Audio on" + color = colors.Red + } + audioStatusStringItem, err := NewStringItem(statusString, p.font, color) + if err != nil { + return fmt.Errorf("failed to create '%s' string item: %v", statusString, err) + } + p.AudioStatusToggle = audioStatusStringItem + return nil +} + func (p *AudioDevices) layout() { // Position title at bottom p.title.X = p.ScreenCenterX - p.title.W/2 @@ -131,16 +118,6 @@ func (p *AudioDevices) layout() { // Position prompt above title p.prompt.X = p.ScreenCenterX - p.prompt.W/2 p.prompt.Y = p.title.Y - p.verticalMargin*2 - p.prompt.H - - // Position device items stacked upward from prompt - for i := range p.devices { - p.devices[i].X = p.ScreenCenterX - p.devices[i].W/2 - if i == 0 { - p.devices[i].Y = p.prompt.Y - p.verticalMargin*2 - p.devices[i].H - } else { - p.devices[i].Y = p.devices[i-1].Y - p.devices[i].H - 10 - } - } } func (p *AudioDevices) HandleEvent(event *sdl.Event) error { @@ -150,45 +127,16 @@ func (p *AudioDevices) HandleEvent(event *sdl.Event) error { } switch e.Keysym.Sym { - case sdl.K_UP: - if p.highlightIndex > 0 { - p.highlightIndex-- - } - - case sdl.K_DOWN: - if p.highlightIndex < len(p.devices)-1 { - p.highlightIndex++ - } case sdl.K_RETURN: - selection := p.devices[p.highlightIndex].content - - // Handle audio disable - if selection == "Turn Audio Off" || selection == "Turn Audio On" { - newStatus := !p.Context.CfgPtr.AudioEnabled - updatedConfig := p.Context.CfgPtr - updatedConfig.AudioEnabled = newStatus - p.Context.DbPtr.Save(&updatedConfig) - p.Context.RefreshConfig() - return nil - } - - // Map "System Default" to empty string for SDL - deviceName := selection - if selection == "System Default" { - deviceName = "" - } - - // Validate by attempting the switch - if err := mixer.SwitchDevice(deviceName); err != nil { - return fmt.Errorf("failed to switch to device %q: %w", selection, err) - } - - // Save settings - p.Context.CfgPtr.SelectedAudioDevice = deviceName - p.Context.CfgPtr.AudioEnabled = true + // Toggle AudioEnabled + p.Context.CfgPtr.AudioEnabled = !p.Context.CfgPtr.AudioEnabled + // Save the config to the database p.Context.DbPtr.Save(p.Context.CfgPtr) + // Refresh the config throughout the application p.Context.RefreshConfig() + // Update AudioEnabled UI element + case sdl.K_BACKSPACE: p.Context.NavigateTo(SETTINGS) } @@ -198,43 +146,23 @@ func (p *AudioDevices) HandleEvent(event *sdl.Event) error { func (p *AudioDevices) Render() error { // Always render title and prompt - p.RenderTexture(p.textShader, p.title.ID, p.title.Position(), p.title.RawDimensions(), p.title.Color) - p.RenderTexture(p.textShader, p.prompt.ID, p.prompt.Position(), p.prompt.RawDimensions(), p.prompt.Color) - - // Render highlight box behind highlighted item - //p.RenderSolidColorQuad( - // p.solidShader, - // p.devices[p.highlightIndex].Position(), - // p.devices[p.highlightIndex].RawDimensions(), - // colors.White, - //) - - // Render device items with appropriate colors - //for i, item := range p.devices { - // if i == p.highlightIndex && i == p.selectedIndex { - // // Currently highlighted AND selected device - dark green - // item.Color = colors.DarkGreen - // } else if i == p.highlightIndex { - // // Just highlighted - black (shows on white background) - // item.Color = colors.Black - // } else if i == p.selectedIndex { - // // Just selected - green - // item.Color = colors.Green - // } else { - // // Normal item - white - // item.Color = colors.White - // } - // p.RenderTexture(p.textShader, item.ID, item.Position(), item.RawDimensions(), item.Color) - //} - + if err := p.RenderTexture(p.textShader, p.title.ID, p.title.Position(), p.title.RawDimensions(), p.title.Color); err != nil { + logger.Error("unable to render title texture: %v", err) + return fmt.Errorf("unable to render title texture: %w", err) + } + if err := p.RenderTexture(p.textShader, p.prompt.ID, p.prompt.Position(), p.prompt.RawDimensions(), p.prompt.Color); err != nil { + logger.Error("unable to render prompt texture: %v", err) + return fmt.Errorf("unable to render prompt texture: %w", err) + } + if err := p.RenderTexture(p.textShader, p.AudioStatusToggle.ID, p.AudioStatusToggle.Position(), p.AudioStatusToggle.RawDimensions(), p.AudioStatusToggle.Color); err != nil { + logger.Error("unable to render audioStatusToggle texture: %v", err) + return fmt.Errorf("unable to render audioStatusToggle texture: %w", err) + } return nil } func (p *AudioDevices) Destroy() error { gl.DeleteTextures(1, &p.title.ID) gl.DeleteTextures(1, &p.prompt.ID) - for _, item := range p.devices { - gl.DeleteTextures(1, &item.ID) - } return nil }