mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-06-22 10:02:20 +00:00
fix(resize): tighten drag scope, simplify divider, clamp width, handle RTL
- build panel subtree outside the width-reactive Obx - replace redundant DraggableDivider with MouseRegion and 12px grab strip - clamp rendered width via LayoutBuilder so a wide panel can't overflow a narrow window - flip drag delta by Directionality so resizing isn't inverted in RTL Signed-off-by: StealUrKill <35749471+StealUrKill@users.noreply.github.com>
This commit is contained in:
parent
aad1082595
commit
fad445ca16
3 changed files with 95 additions and 74 deletions
|
|
@ -76,38 +76,43 @@ class _AddressBookState extends State<AddressBook> {
|
|||
});
|
||||
|
||||
Widget _buildAddressBookLandscape() {
|
||||
return Row(
|
||||
children: [
|
||||
Offstage(
|
||||
offstage: hideAbTagsPanel.value,
|
||||
child: Obx(() => Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.background)),
|
||||
width: _tagsPanel.width.value,
|
||||
height: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
_buildAbDropdown(),
|
||||
_buildTagHeader().marginOnly(
|
||||
left: 8.0,
|
||||
right: gFFI.abModel.legacyMode.value ? 8.0 : 0,
|
||||
top: gFFI.abModel.legacyMode.value ? 8.0 : 0),
|
||||
Expanded(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: _buildTags(),
|
||||
),
|
||||
),
|
||||
_buildAbPermission(),
|
||||
],
|
||||
),
|
||||
))),
|
||||
if (!hideAbTagsPanel.value) _tagsPanel.buildDivider(),
|
||||
_buildPeersViews()
|
||||
],
|
||||
final panel = Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border:
|
||||
Border.all(color: Theme.of(context).colorScheme.background)),
|
||||
height: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
_buildAbDropdown(),
|
||||
_buildTagHeader().marginOnly(
|
||||
left: 8.0,
|
||||
right: gFFI.abModel.legacyMode.value ? 8.0 : 0,
|
||||
top: gFFI.abModel.legacyMode.value ? 8.0 : 0),
|
||||
Expanded(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: _buildTags(),
|
||||
),
|
||||
),
|
||||
_buildAbPermission(),
|
||||
],
|
||||
),
|
||||
);
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) => Row(
|
||||
children: [
|
||||
Offstage(
|
||||
offstage: hideAbTagsPanel.value,
|
||||
child: Obx(() => SizedBox(
|
||||
width: _tagsPanel.effectiveWidth(constraints.maxWidth),
|
||||
child: panel,
|
||||
))),
|
||||
if (!hideAbTagsPanel.value) _tagsPanel.buildDivider(context),
|
||||
_buildPeersViews()
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,39 +63,42 @@ class _MyGroupState extends State<MyGroup> {
|
|||
}
|
||||
|
||||
Widget _buildLandscape() {
|
||||
return Row(
|
||||
children: [
|
||||
Obx(
|
||||
() => Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.background)),
|
||||
width: _devicesPanel.width.value,
|
||||
height: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
_buildLeftHeader(),
|
||||
Expanded(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: _buildLeftList(),
|
||||
),
|
||||
)
|
||||
],
|
||||
final panel = Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border:
|
||||
Border.all(color: Theme.of(context).colorScheme.background)),
|
||||
height: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
_buildLeftHeader(),
|
||||
Expanded(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: _buildLeftList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
_devicesPanel.buildDivider(),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: MyGroupPeerView(
|
||||
menuPadding: widget.menuPadding,
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) => Row(
|
||||
children: [
|
||||
Obx(() => SizedBox(
|
||||
width: _devicesPanel.effectiveWidth(constraints.maxWidth),
|
||||
child: panel,
|
||||
)),
|
||||
)
|
||||
],
|
||||
_devicesPanel.buildDivider(context),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: MyGroupPeerView(
|
||||
menuPadding: widget.menuPadding,
|
||||
)),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hbb/desktop/widgets/dragable_divider.dart';
|
||||
import 'dart:math';
|
||||
import 'package:flutter_hbb/models/platform_model.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
|
|
@ -14,6 +14,9 @@ class ResizablePanelController {
|
|||
final double maxWidth;
|
||||
late final RxDouble width;
|
||||
|
||||
static const double dividerHitWidth = 12.0;
|
||||
static const double minContentWidth = 120.0;
|
||||
|
||||
ResizablePanelController({
|
||||
required this.optionKey,
|
||||
required this.defaultWidth,
|
||||
|
|
@ -29,21 +32,31 @@ class ResizablePanelController {
|
|||
width.value = (width.value + dx).clamp(minWidth, maxWidth).toDouble();
|
||||
}
|
||||
|
||||
double effectiveWidth(double available) {
|
||||
if (!available.isFinite) return width.value;
|
||||
final maxAllowed = available - dividerHitWidth - minContentWidth;
|
||||
return width.value.clamp(minWidth, max(minWidth, maxAllowed)).toDouble();
|
||||
}
|
||||
|
||||
void _persist() {
|
||||
bind.mainSetLocalOption(
|
||||
key: optionKey, value: width.value.toStringAsFixed(0));
|
||||
}
|
||||
|
||||
Widget buildDivider() {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onHorizontalDragUpdate: (details) => _onDrag(details.delta.dx),
|
||||
onHorizontalDragEnd: (_) => _persist(),
|
||||
onHorizontalDragCancel: _persist,
|
||||
child: DraggableDivider(
|
||||
axis: Axis.vertical,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||
color: Colors.transparent,
|
||||
Widget buildDivider(BuildContext context) {
|
||||
final sign = Directionality.of(context) == TextDirection.rtl ? -1.0 : 1.0;
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.resizeLeftRight,
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onHorizontalDragUpdate: (details) => _onDrag(sign * details.delta.dx),
|
||||
onHorizontalDragEnd: (_) => _persist(),
|
||||
onHorizontalDragCancel: _persist,
|
||||
child: Container(
|
||||
width: dividerHitWidth,
|
||||
height: double.infinity,
|
||||
color: Colors.transparent,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue