diff --git a/lib/common/widgets/custom_height_widget.dart b/lib/common/widgets/custom_height_widget.dart
index f94655209..6d14c357b 100644
--- a/lib/common/widgets/custom_height_widget.dart
+++ b/lib/common/widgets/custom_height_widget.dart
@@ -57,7 +57,7 @@ class RenderCustomHeightWidget extends RenderProxyBox {
@override
void performLayout() {
- child!.layout(constraints, parentUsesSize: true);
+ child!.layout(constraints);
size = constraints.constrainDimensions(constraints.maxWidth, height);
}
diff --git a/lib/common/widgets/image/custom_grid_view.dart b/lib/common/widgets/image/custom_grid_view.dart
index 3099bd194..d4c74c4bd 100644
--- a/lib/common/widgets/image/custom_grid_view.dart
+++ b/lib/common/widgets/image/custom_grid_view.dart
@@ -415,7 +415,7 @@ class RenderImageGrid extends RenderBox
while (child != null) {
final childParentData = child.parentData as MultiChildLayoutParentData;
final index = childParentData.id as int;
- child.layout(itemConstraints, parentUsesSize: true);
+ child.layout(itemConstraints);
childParentData.offset = Offset(
(space + width) * (index % column),
(space + height) * (index ~/ column),
diff --git a/lib/common/widgets/player_bar.dart b/lib/common/widgets/player_bar.dart
new file mode 100644
index 000000000..29403e61c
--- /dev/null
+++ b/lib/common/widgets/player_bar.dart
@@ -0,0 +1,133 @@
+/*
+ * This file is part of PiliPlus
+ *
+ * PiliPlus is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PiliPlus is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with PiliPlus. If not, see .
+ */
+
+import 'dart:math' as math;
+
+import 'package:flutter/material.dart';
+import 'package:flutter/rendering.dart'
+ show
+ ContainerRenderObjectMixin,
+ MultiChildLayoutParentData,
+ RenderBoxContainerDefaultsMixin,
+ BoxHitTestResult;
+
+class PlayerBar extends MultiChildRenderObjectWidget {
+ const PlayerBar({
+ super.key,
+ super.children,
+ });
+
+ @override
+ RenderObject createRenderObject(BuildContext context) {
+ return RenderBottomBar();
+ }
+}
+
+class RenderBottomBar extends RenderBox
+ with
+ ContainerRenderObjectMixin,
+ RenderBoxContainerDefaultsMixin {
+ @override
+ void setupParentData(RenderBox child) {
+ if (child.parentData is! MultiChildLayoutParentData) {
+ child.parentData = MultiChildLayoutParentData();
+ }
+ }
+
+ Matrix4? _transform;
+
+ @override
+ void performLayout() {
+ _transform = null;
+
+ final c = constraints.copyWith(maxWidth: .infinity);
+ final RenderBox first = firstChild!..layout(c, parentUsesSize: true);
+ final RenderBox last = lastChild!..layout(c, parentUsesSize: true);
+
+ final firstSize = first.size;
+ final lastSize = last.size;
+
+ final firstParentData = first.parentData as MultiChildLayoutParentData;
+ final lastParentData = last.parentData as MultiChildLayoutParentData;
+
+ final firstWidth = firstSize.width;
+ final lastWidth = lastSize.width;
+ final totalWidth = firstWidth + lastWidth;
+ final maxWidth = constraints.maxWidth;
+ final height = math.max(firstSize.height, lastSize.height);
+ size = constraints.constrainDimensions(maxWidth, height);
+
+ firstParentData.offset = Offset(0.0, (height - firstSize.height) / 2);
+ if (totalWidth <= maxWidth) {
+ lastParentData.offset = Offset(
+ maxWidth - lastWidth,
+ (height - lastSize.height) / 2,
+ );
+ } else {
+ final scale = maxWidth / totalWidth;
+ _transform = Matrix4.identity()
+ ..translateByDouble(0.0, height * (1 - scale) / 2, 0.0, 1.0)
+ ..scaleByDouble(scale, scale, scale, 1.0);
+ lastParentData.offset = Offset(
+ (maxWidth - lastWidth * scale) / scale,
+ (height - lastSize.height) / 2,
+ );
+ }
+ }
+
+ void _paintChild(PaintingContext context, Offset offset) {
+ RenderBox? child = firstChild;
+ while (child != null) {
+ final childParentData = child.parentData as MultiChildLayoutParentData;
+ context.paintChild(child, childParentData.offset + offset);
+ child = childParentData.nextSibling;
+ }
+ }
+
+ @override
+ void paint(PaintingContext context, Offset offset) {
+ if (_transform != null) {
+ context.pushTransform(needsCompositing, offset, _transform!, _paintChild);
+ } else {
+ _paintChild(context, offset);
+ }
+ }
+
+ @override
+ bool hitTestChildren(BoxHitTestResult result, {required Offset position}) {
+ return result.addWithPaintTransform(
+ transform: _transform,
+ position: position,
+ hitTest: (BoxHitTestResult result, Offset position) {
+ return defaultHitTestChildren(result, position: position);
+ },
+ );
+ }
+
+ @override
+ void applyPaintTransform(RenderBox child, Matrix4 transform) {
+ final childParentData = child.parentData! as MultiChildLayoutParentData;
+ final Offset offset = childParentData.offset;
+ if (_transform != null) {
+ transform
+ ..translateByDouble(offset.dx * _transform!.storage[0], offset.dy, 0, 1)
+ ..multiply(_transform!);
+ } else {
+ transform.translateByDouble(offset.dx, offset.dy, 0, 1);
+ }
+ }
+}
diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart
index fe60bbbe4..a23a3f51d 100644
--- a/lib/plugin/pl_player/view.dart
+++ b/lib/plugin/pl_player/view.dart
@@ -11,6 +11,7 @@ import 'package:PiliPlus/common/widgets/gesture/immediate_tap_gesture_recognizer
import 'package:PiliPlus/common/widgets/gesture/mouse_interactive_viewer.dart';
import 'package:PiliPlus/common/widgets/loading_widget.dart';
import 'package:PiliPlus/common/widgets/pair.dart';
+import 'package:PiliPlus/common/widgets/player_bar.dart';
import 'package:PiliPlus/common/widgets/progress_bar/audio_video_progress_bar.dart';
import 'package:PiliPlus/common/widgets/progress_bar/segment_progress_bar.dart';
import 'package:PiliPlus/common/widgets/view_safe_area.dart';
@@ -874,22 +875,15 @@ class _PLVideoPlayerState extends State
if (isNotFileSource && flag) BottomControlType.qa,
if (!plPlayerController.isDesktopPip) BottomControlType.fullscreen,
];
-
- return Row(
+ return PlayerBar(
children: [
- ...userSpecifyItemLeft.map(progressWidget),
- Expanded(
- child: LayoutBuilder(
- builder: (context, constraints) => FittedBox(
- child: ConstrainedBox(
- constraints: BoxConstraints(minWidth: constraints.maxWidth),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.end,
- children: userSpecifyItemRight.map(progressWidget).toList(),
- ),
- ),
- ),
- ),
+ Row(
+ mainAxisSize: .min,
+ children: userSpecifyItemLeft.map(progressWidget).toList(),
+ ),
+ Row(
+ mainAxisSize: .min,
+ children: userSpecifyItemRight.map(progressWidget).toList(),
),
],
);
@@ -2868,7 +2862,7 @@ class _RenderVideoTime extends RenderBox {
)
..addText(time);
return builder.build()
- ..layout(ui.ParagraphConstraints(width: constraints.maxWidth));
+ ..layout(const ui.ParagraphConstraints(width: .infinity));
}
@override