212f8e16d2
- Added WindowDragController to manage custom dragging of sub-windows. - Integrated dragging logic into EqWindow and PlWindow, allowing for smooth window movement. - Introduced docking logic to snap windows together and maintain their positions relative to each other. - Implemented persistence of window positions using SharedPreferences. - Enhanced AppDelegate to support screen bounds and mouse location retrieval for accurate window positioning. - Updated pubspec.yaml to include screen_retriever dependency. - Added comprehensive tests for dock controller and dock logic to ensure correct behavior during window interactions. Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
113 lines
4.7 KiB
Dart
113 lines
4.7 KiB
Dart
import "dart:ui";
|
|
|
|
import "package:dartamp/src/docking/dock_controller.dart";
|
|
import "package:dartamp/src/docking/dock_logic.dart";
|
|
import "package:flutter_test/flutter_test.dart";
|
|
|
|
const screen = Rect.fromLTWH(0, 0, 1440, 900);
|
|
|
|
void main() {
|
|
late List<(DockWindow, Rect)> moved;
|
|
late Map<DockWindow, Rect>? persisted;
|
|
late DockController dock;
|
|
|
|
setUp(() {
|
|
moved = [];
|
|
persisted = null;
|
|
dock = DockController(
|
|
moveWindow: (window, rect) => moved.add((window, rect)),
|
|
persistRects: (rects) => persisted = rects,
|
|
)..screenRect = screen;
|
|
});
|
|
|
|
test("setRect and removeWindow maintain the rect map", () {
|
|
dock.setRect(DockWindow.eq, const Rect.fromLTWH(275, 0, 275, 116));
|
|
expect(dock.rectOf(DockWindow.eq)!.topLeft, const Offset(275, 0));
|
|
expect(dock.rects.length, 1);
|
|
dock.removeWindow(DockWindow.eq);
|
|
expect(dock.rectOf(DockWindow.eq), isNull);
|
|
});
|
|
|
|
test("a main-window drag moves the attached group by the same delta", () {
|
|
dock.setRect(DockWindow.main, const Rect.fromLTWH(500, 300, 275, 116));
|
|
dock.setRect(DockWindow.eq, const Rect.fromLTWH(775, 300, 275, 116));
|
|
dock.beginMainDrag(const Offset(600, 340));
|
|
dock.mainDragTo(const Offset(700, 420));
|
|
dock.endMainDrag();
|
|
final mainRect = dock.rectOf(DockWindow.main)!;
|
|
final eqRect = dock.rectOf(DockWindow.eq)!;
|
|
expect(mainRect.topLeft, const Offset(600, 380));
|
|
expect(eqRect.topLeft, const Offset(875, 380));
|
|
expect(moved, contains((DockWindow.main, mainRect)));
|
|
expect(moved, contains((DockWindow.eq, eqRect)));
|
|
expect(persisted, isNotNull);
|
|
});
|
|
|
|
test("movement tracks the cumulative pointer delta", () {
|
|
dock.setRect(DockWindow.main, const Rect.fromLTWH(500, 300, 275, 116));
|
|
dock.setRect(DockWindow.eq, const Rect.fromLTWH(775, 300, 275, 116));
|
|
dock.beginMainDrag(const Offset(600, 340));
|
|
dock.mainDragTo(const Offset(700, 420));
|
|
dock.mainDragTo(const Offset(800, 500));
|
|
expect(dock.rectOf(DockWindow.main)!.topLeft, const Offset(700, 460));
|
|
expect(dock.rectOf(DockWindow.eq)!.topLeft, const Offset(975, 460));
|
|
});
|
|
|
|
test("dragging to a screen corner snaps the whole group", () {
|
|
dock.setRect(DockWindow.main, const Rect.fromLTWH(10, 10, 275, 116));
|
|
dock.setRect(DockWindow.eq, const Rect.fromLTWH(285, 10, 275, 116));
|
|
dock.beginMainDrag(const Offset(100, 100));
|
|
dock.mainDragTo(const Offset(95, 95));
|
|
expect(dock.rectOf(DockWindow.main)!.topLeft, Offset.zero);
|
|
expect(dock.rectOf(DockWindow.eq)!.topLeft, const Offset(275, 0));
|
|
});
|
|
|
|
test("an unattached window stays put while the group moves", () {
|
|
dock.setRect(DockWindow.main, const Rect.fromLTWH(500, 300, 275, 116));
|
|
dock.setRect(DockWindow.eq, const Rect.fromLTWH(800, 500, 275, 116));
|
|
dock.beginMainDrag(const Offset(600, 340));
|
|
dock.mainDragTo(const Offset(650, 400));
|
|
expect(dock.rectOf(DockWindow.main)!.topLeft, const Offset(550, 360));
|
|
expect(dock.rectOf(DockWindow.eq)!.topLeft, const Offset(800, 500));
|
|
});
|
|
|
|
test("a sub-window resizing re-pins windows docked to its new edge", () {
|
|
dock.setRect(DockWindow.main, const Rect.fromLTWH(0, 0, 275, 116));
|
|
dock.setRect(DockWindow.eq, const Rect.fromLTWH(275, 0, 275, 116));
|
|
dock.setRect(DockWindow.pl, const Rect.fromLTWH(0, 116, 280, 290));
|
|
dock.repinResized(DockWindow.main, const Rect.fromLTWH(0, 0, 330, 139.2));
|
|
expect(dock.rectOf(DockWindow.eq)!.topLeft, const Offset(330, 0));
|
|
expect(dock.rectOf(DockWindow.pl)!.topLeft, const Offset(0, 139.2));
|
|
});
|
|
|
|
test("subBounds re-pins the chain docked below the resized window", () {
|
|
dock.setRect(DockWindow.main, const Rect.fromLTWH(0, 0, 275, 116));
|
|
dock.setRect(DockWindow.pl, const Rect.fromLTWH(0, 116, 280, 290));
|
|
dock.setRect(DockWindow.eq, const Rect.fromLTWH(0, 406, 275, 116));
|
|
dock.subBounds(DockWindow.pl, const Rect.fromLTWH(0, 116, 280, 14));
|
|
expect(dock.rectOf(DockWindow.eq)!.topLeft, const Offset(0, 130));
|
|
});
|
|
|
|
test("repinResized keeps everything pinned when the edge does not move", () {
|
|
dock.setRect(DockWindow.main, const Rect.fromLTWH(0, 0, 275, 116));
|
|
dock.setRect(DockWindow.eq, const Rect.fromLTWH(275, 0, 275, 116));
|
|
dock.repinResized(DockWindow.main, const Rect.fromLTWH(0, 0, 275, 14));
|
|
expect(dock.rectOf(DockWindow.eq)!.topLeft, const Offset(275, 0));
|
|
});
|
|
|
|
test("scaledSize accounts for shade state and UI scale", () {
|
|
expect(
|
|
DockController.scaledSize(DockWindow.main, false, 1.0),
|
|
const Size(275, 116),
|
|
);
|
|
expect(
|
|
DockController.scaledSize(DockWindow.eq, true, 1.0),
|
|
const Size(275, 14),
|
|
);
|
|
expect(
|
|
DockController.scaledSize(DockWindow.pl, false, 1.2),
|
|
const Size(336, 348),
|
|
);
|
|
});
|
|
}
|