Панель времени/заряда: оверлей-слой поверх контента, у низа экрана — стабильно при любом масштабе

This commit is contained in:
2026-08-25 02:28:00 +03:00
parent 8958370507
commit d113ffd744
2 changed files with 58 additions and 61 deletions
@@ -473,39 +473,38 @@ fun ConnectionScreen() {
val containerW = (screenWidthPx * scale).toInt() val containerW = (screenWidthPx * scale).toInt()
val containerH = (screenHeightPx * scale).toInt() val containerH = (screenHeightPx * scale).toInt()
Box( // Оверлей-обёртка половины: контейнер (смещается scale/vertical) + панель статуса
modifier = Modifier // поверх него. Панель — у низа экрана при любом масштабе/вертикали.
.width(containerW.px) Box(Modifier.fillMaxSize()) {
.height(containerH.px) Box(
.offset( modifier = Modifier
x = scaleOffsetX(side, screenWidthPx, scale).px, .width(containerW.px)
y = verticalOffsetY(screenHeightPx, scale, vertical).px, .height(containerH.px)
) .offset(
.background(Color.Black), x = scaleOffsetX(side, screenWidthPx, scale).px,
) { y = verticalOffsetY(screenHeightPx, scale, vertical).px,
Column( )
modifier = Modifier.fillMaxSize().padding(start = 24.dp, end = 24.dp, top = 56.dp), .background(Color.Black),
verticalArrangement = Arrangement.spacedBy(8.dp),
) { ) {
Text("ViewMate Glasses", style = MaterialTheme.typography.headlineMedium) Column(
Text(if (connected) "подключено к телефону" else "нет соединения") modifier = Modifier.fillMaxSize().padding(start = 24.dp, end = 24.dp, top = 56.dp),
Text(status, style = MaterialTheme.typography.bodyMedium) verticalArrangement = Arrangement.spacedBy(8.dp),
Text("Последние сообщения:", style = MaterialTheme.typography.titleMedium) ) {
LazyColumn(modifier = Modifier.fillMaxWidth()) { Text("ViewMate Glasses", style = MaterialTheme.typography.headlineMedium)
items(messages) { msg -> Text(if (connected) "подключено к телефону" else "нет соединения")
Text(msg, style = MaterialTheme.typography.bodySmall) Text(status, style = MaterialTheme.typography.bodyMedium)
Text("Последние сообщения:", style = MaterialTheme.typography.titleMedium)
LazyColumn(modifier = Modifier.fillMaxWidth()) {
items(messages) { msg ->
Text(msg, style = MaterialTheme.typography.bodySmall)
}
} }
} }
// Оверлей распознавания/ответа — в AssistantOverlay (корень, поверх любого экрана).
} }
// Оверлей распознавания/ответа — в AssistantOverlay (корень, поверх любого экрана).
}
// Панель статуса (время/заряд) — вне контейнера, всегда у верха половины:
// при vertical=0 контейнер у низа, и панель иначе повисала бы посередине.
Box(Modifier.fillMaxSize()) {
StatusPanelCompose( StatusPanelCompose(
modifier = Modifier.align(Alignment.TopCenter).padding(top = 12.dp), modifier = Modifier.align(Alignment.BottomCenter).padding(bottom = 10.dp),
scale = scale, scale = scale,
) )
} }
@@ -104,45 +104,43 @@ fun GlassesMovieScreen(
maxHeight = containerH - 25, maxHeight = containerH - 25,
) )
Box( // Оверлей-обёртка половины: контейнер (смещается scale/vertical) + панель статуса
modifier = Modifier // поверх него. Панель — у низа экрана при любом масштабе/вертикали.
.width(containerW.px) Box(Modifier.fillMaxSize()) {
.height(containerH.px) Box(
.offset( modifier = Modifier
x = scaleOffsetX(side, screenWidthPx, scale).px, .width(containerW.px)
y = verticalOffsetY(screenHeightPx, scale, vertical).px, .height(containerH.px)
), .offset(
) { x = scaleOffsetX(side, screenWidthPx, scale).px,
Row( y = verticalOffsetY(screenHeightPx, scale, vertical).px,
modifier = Modifier.fillMaxWidth().background(Color.Black), ),
// Видео в контейнере прижимается к верху (vertical=1) или низу (vertical=0):
// Row-центрирование съедало вертикаль — картинка оставалась «по центру».
verticalAlignment = Alignment.Top,
horizontalArrangement = if (side == Side.LEFT) Arrangement.End else Arrangement.Start,
) { ) {
if (SCALE_DEBUG_SQUARE) { Row(
// Тестовый режим: большой красный квадрат вместо видео — быстрая modifier = Modifier.fillMaxWidth().background(Color.Black),
// проверка масштаба/позиций скрином без запуска видео. // Видео в контейнере прижимается к верху (vertical=1) или низу (vertical=0):
Box(Modifier.fillMaxSize().background(Color.Red)) // Row-центрирование съедало вертикаль — картинка оставалась «по центру».
} else { verticalAlignment = Alignment.Top,
BinocularVideoPlayer( horizontalArrangement = if (side == Side.LEFT) Arrangement.End else Arrangement.Start,
player = player, ) {
renderer = renderer, if (SCALE_DEBUG_SQUARE) {
modifier = Modifier // Тестовый режим: большой красный квадрат вместо видео — быстрая
.size(playerWidth.px, playerHeight.px) // проверка масштаба/позиций скрином без запуска видео.
.offset(y = videoOffsetY(containerH, playerHeight, vertical).px), Box(Modifier.fillMaxSize().background(Color.Red))
) } else {
BinocularVideoPlayer(
player = player,
renderer = renderer,
modifier = Modifier
.size(playerWidth.px, playerHeight.px)
.offset(y = videoOffsetY(containerH, playerHeight, vertical).px),
)
}
} }
} }
// Панель статуса (время/заряд) — вне контейнера, всегда у верха половины:
// при vertical=0 контейнер у низа, и панель иначе повисала бы посередине
// чёрного поля между верхом экрана и видео.
}
Box(Modifier.fillMaxSize()) {
StatusPanelCompose( StatusPanelCompose(
modifier = Modifier.align(Alignment.TopCenter).padding(top = 12.dp), modifier = Modifier.align(Alignment.BottomCenter).padding(bottom = 10.dp),
scale = scale, scale = scale,
) )
} }