Files

75 lines
2.4 KiB
Go

// Copyright (c) 2026 Storm Dragon
// SPDX-License-Identifier: GPL-3.0-or-later
package reader
import (
"git.stormux.org/storm/fenrir/internal/i18n"
"git.stormux.org/storm/fenrir/internal/presentation"
"git.stormux.org/storm/fenrir/internal/screen"
"strings"
"time"
)
func (r *Reader) Configure_attributes(mode, format string) {
// Configuration is the saved/quick-menu choice. Reapplying unchanged
// settings must not overwrite the shortcut's temporary session state.
if mode != r.attributeConfigured {
r.attributeConfigured, r.attributeMode = mode, mode
if mode != "" && mode != "none" {
r.attributeResumeMode = mode
}
}
r.attributeFormat = format
r.review.Configure_attributes(format)
}
func (r *Reader) toggle_attributes() string {
if r.attributeMode == "" || r.attributeMode == "none" {
r.attributeMode = r.attributeResumeMode
if r.attributeMode == "" {
r.attributeMode = "beeps"
}
return i18n.T("announcement of attributes enabled")
}
r.attributeResumeMode, r.attributeMode = r.attributeMode, "none"
return i18n.T("announcement of attributes disabled")
}
func (r *Reader) attribute_feedback(announce bool) *presentation.Message {
attribute, valid := r.review.Attribute()
if !valid {
r.attributeKnown = false
return nil
}
changed := r.attributeKnown && attribute != r.lastAttribute
r.lastAttribute, r.attributeKnown = attribute, true
if !announce || !changed || r.attributeMode == "" || r.attributeMode == "none" {
return nil
}
// Presence tones describe emphasis; returning to defaults is described by
// speech modes, but must not play a misleading has-attribute cue.
if attribute.Default() && r.attributeMode == "beeps" {
return nil
}
message := presentation.Attribute_message(attribute, r.attributeMode, r.attributeFormat)
if attribute.Default() {
message.Cue = ""
}
if message.Cue == "" && strings.TrimSpace(message.Text) == "" {
return nil
}
return &message
}
func (r *Reader) automatic_attributes(previous, next screen.Snapshot, switched bool) *presentation.Message {
if switched {
r.attributeKnown = false
}
announce := !switched && next.Active && r.automatic && r.cursorEcho && r.trackingMode == "cursor" && !r.review.Active() && r.region_state().allows(next.X, next.Y, next.Cols, true, true)
if announce && (previous.X != next.X || previous.Y != next.Y) {
announce = !r.applicationInputAt.IsZero() && time.Since(r.applicationInputAt) < 300*time.Millisecond
}
return r.attribute_feedback(announce)
}