119 lines
3.2 KiB
Dart
119 lines
3.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:window_manager/window_manager.dart';
|
|
|
|
/// Resize edge zones for frameless windows.
|
|
class WindowResizeZones extends StatelessWidget {
|
|
final Widget child;
|
|
|
|
const WindowResizeZones({super.key, required this.child});
|
|
|
|
static const _edgeSize = 4.0;
|
|
static const _cornerSize = 10.0;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Stack(
|
|
children: [
|
|
child,
|
|
|
|
// Top edge
|
|
_ResizeEdge(
|
|
edge: ResizeEdge.top,
|
|
top: 0, left: _cornerSize, right: _cornerSize, height: _edgeSize,
|
|
),
|
|
// Bottom edge
|
|
_ResizeEdge(
|
|
edge: ResizeEdge.bottom,
|
|
bottom: 0, left: _cornerSize, right: _cornerSize, height: _edgeSize,
|
|
),
|
|
// Left edge
|
|
_ResizeEdge(
|
|
edge: ResizeEdge.left,
|
|
left: 0, top: _cornerSize, bottom: _cornerSize, width: _edgeSize,
|
|
),
|
|
// Right edge
|
|
_ResizeEdge(
|
|
edge: ResizeEdge.right,
|
|
right: 0, top: _cornerSize, bottom: _cornerSize, width: _edgeSize,
|
|
),
|
|
|
|
// Corners
|
|
_ResizeCorner(edge: ResizeEdge.topLeft, top: 0, left: 0),
|
|
_ResizeCorner(edge: ResizeEdge.topRight, top: 0, right: 0),
|
|
_ResizeCorner(edge: ResizeEdge.bottomLeft, bottom: 0, left: 0),
|
|
_ResizeCorner(edge: ResizeEdge.bottomRight, bottom: 0, right: 0),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
class _ResizeEdge extends StatelessWidget {
|
|
final ResizeEdge edge;
|
|
final double? top, bottom, left, right, width, height;
|
|
|
|
const _ResizeEdge({
|
|
required this.edge,
|
|
this.top, this.bottom, this.left, this.right,
|
|
this.width, this.height,
|
|
});
|
|
|
|
MouseCursor _cursor(ResizeEdge e) {
|
|
return switch (e) {
|
|
ResizeEdge.top || ResizeEdge.bottom => SystemMouseCursors.resizeRow,
|
|
ResizeEdge.left || ResizeEdge.right => SystemMouseCursors.resizeColumn,
|
|
_ => SystemMouseCursors.basic,
|
|
};
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Positioned(
|
|
top: top, bottom: bottom, left: left, right: right,
|
|
width: width, height: height,
|
|
child: MouseRegion(
|
|
cursor: _cursor(edge),
|
|
child: GestureDetector(
|
|
behavior: HitTestBehavior.opaque,
|
|
onPanStart: (_) => windowManager.startResizing(edge),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _ResizeCorner extends StatelessWidget {
|
|
final ResizeEdge edge;
|
|
final double? top, bottom, left, right;
|
|
|
|
const _ResizeCorner({
|
|
required this.edge,
|
|
this.top, this.bottom, this.left, this.right,
|
|
});
|
|
|
|
MouseCursor _cursor(ResizeEdge e) {
|
|
return switch (e) {
|
|
ResizeEdge.topLeft || ResizeEdge.bottomRight =>
|
|
SystemMouseCursors.resizeDownLeft,
|
|
ResizeEdge.topRight || ResizeEdge.bottomLeft =>
|
|
SystemMouseCursors.resizeDownRight,
|
|
_ => SystemMouseCursors.basic,
|
|
};
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Positioned(
|
|
top: top, bottom: bottom, left: left, right: right,
|
|
width: WindowResizeZones._cornerSize,
|
|
height: WindowResizeZones._cornerSize,
|
|
child: MouseRegion(
|
|
cursor: _cursor(edge),
|
|
child: GestureDetector(
|
|
behavior: HitTestBehavior.opaque,
|
|
onPanStart: (_) => windowManager.startResizing(edge),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|