Files
Button/qml/settings/BannerPage.qml
T
GrigoandClaude Opus 5.5 f07e153f09 Boot splash and periodic announcement banner
Splash: resources/splash/splash.gif built into the binary, played once by
SplashOverlay over a black cover present from the first frame (no UI
flash), then fades into the UI; hides icons loading. GIF, so no
QtMultimedia/gstreamer. Toggle: splash.enabled.

Banner (InfoBanner): metro-style band that fades/slides in with a hold
pictogram; text that does not fit runs as a seamless ticker for two
rounds. Never takes touches; hidden during splash and settings. Config
section banner (enabled, text, intervalSec, showSec, position,
accentColor), editable in the web UI and on-device settings; shown once
after saving.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 10:58:16 +00:00

156 lines
5.2 KiB
QML

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import "../components"
// Announcement banner + boot splash (config sections "banner", "splash").
Item {
id: page
signal previewRequested()
function sync() {
accentPicker.hex = settingsContainer.bannerAccentColor
if (!textField.activeFocus)
textField.text = settingsContainer.bannerText
}
Component.onCompleted: sync()
Connections {
target: settingsContainer
function onChanged() { page.sync() }
}
Rectangle {
anchors.fill: parent
color: "#161628"
}
ScrollView {
anchors.fill: parent
clip: true
contentWidth: availableWidth
contentHeight: col.implicitHeight + 16
ScrollBar.vertical.policy: ScrollBar.AsNeeded
ColumnLayout {
id: col
width: page.width - 16
x: 8
y: 8
spacing: 12
BackHeader { title: "Объявление и заставка"; onBack: page.StackView.view.pop() }
CheckBox {
text: "Заставка при запуске"
checked: settingsContainer.splashEnabled
onToggled: btnController.setSplashEnabled(checked)
contentItem: Text {
text: parent.text
font: parent.font
color: "#ffffff"
leftPadding: parent.indicator.width + parent.spacing
verticalAlignment: Text.AlignVCenter
}
}
CheckBox {
text: "Периодически показывать объявление"
checked: settingsContainer.bannerEnabled
onToggled: btnController.setBannerValue("enabled", checked)
contentItem: Text {
text: parent.text
font: parent.font
color: "#ffffff"
leftPadding: parent.indicator.width + parent.spacing
verticalAlignment: Text.AlignVCenter
}
}
Text {
Layout.fillWidth: true
text: "Текст объявления"
color: "#ffffff"
}
RowLayout {
Layout.fillWidth: true
TextField {
id: textField
Layout.fillWidth: true
Layout.preferredHeight: 40
maximumLength: 200
placeholderText: "Для вызова клининга удерживайте кнопку"
onAccepted: applyText.clicked()
}
Button {
id: applyText
text: "Сохранить"
enabled: textField.text.trim() !== settingsContainer.bannerText
onClicked: {
btnController.setBannerValue("text", textField.text.trim())
textField.focus = false
}
}
}
LabeledSlider {
label: "Раз в, сек"
from: 30; to: 1800; stepSize: 30
value: settingsContainer.bannerIntervalSec
onMoved: btnController.setBannerValue("intervalSec", value)
}
LabeledSlider {
label: "Показ, сек"
from: 3; to: 30; stepSize: 1
value: settingsContainer.bannerShowSec
onMoved: btnController.setBannerValue("showSec", value)
}
RowLayout {
Layout.fillWidth: true
Text {
text: "Положение:"
color: "#ffffff"
}
Item { Layout.fillWidth: true }
Button {
text: "Сверху"
highlighted: settingsContainer.bannerPosition === "top"
onClicked: btnController.setBannerValue("position", "top")
}
Button {
text: "Снизу"
highlighted: settingsContainer.bannerPosition === "bottom"
onClicked: btnController.setBannerValue("position", "bottom")
}
}
ColorPickerField {
id: accentPicker
label: "Цвет полосы:"
onColorChanged: btnController.setBannerValue("accentColor", hex)
}
SettingsButton {
Layout.fillWidth: true
text: "Показать сейчас"
enabled: settingsContainer.bannerText.length > 0
onClicked: page.previewRequested()
}
Text {
Layout.fillWidth: true
text: "Объявление не перехватывает нажатия. Если текст не помещается, он прокручивается как бегущая строка."
color: "#aaaaaa"
font.pixelSize: 12
wrapMode: Text.Wrap
}
Item { Layout.preferredHeight: 8 }
}
}
}