Skip to content

Commit

Permalink
Add ruler and grid renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeDoctorDE committed Dec 29, 2024
1 parent 3a49114 commit 417131d
Show file tree
Hide file tree
Showing 22 changed files with 308 additions and 114 deletions.
4 changes: 2 additions & 2 deletions api/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,8 @@ packages:
dependency: "direct main"
description:
path: "packages/lw_file_system_api"
ref: a0752f136913f64a975cb8b20ccb16fb6ce37737
resolved-ref: a0752f136913f64a975cb8b20ccb16fb6ce37737
ref: "5ab1b96bea6ef0e0c07629ff4e7152b4437cf8ee"
resolved-ref: "5ab1b96bea6ef0e0c07629ff4e7152b4437cf8ee"
url: "https://github.com/LinwoodDev/dart_pkgs"
source: git
version: "1.0.0"
Expand Down
2 changes: 1 addition & 1 deletion api/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ dependencies:
git:
url: https://github.com/LinwoodDev/dart_pkgs
path: packages/lw_file_system_api
ref: a0752f136913f64a975cb8b20ccb16fb6ce37737
ref: 5ab1b96bea6ef0e0c07629ff4e7152b4437cf8ee
dart_leap:
git:
url: https://github.com/LinwoodDev/dart_pkgs
Expand Down
4 changes: 3 additions & 1 deletion app/lib/bloc/document_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,9 @@ class DocumentBloc extends ReplayBloc<DocumentEvent, DocumentState> {
}).toList())));
final updatedCurrent = event.tools.entries.firstWhereOrNull((element) =>
oldTools[element.key] ==
current.currentIndexCubit.state.handler.data);
current.currentIndexCubit.state.handler.data ||
current.currentIndexCubit.state.toggleableHandlers
.containsKey(element.key));
if (updatedCurrent != null) {
current.currentIndexCubit.updateTool(this, updatedCurrent.value);
}
Expand Down
106 changes: 75 additions & 31 deletions app/lib/cubits/current_index.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ class CurrentIndex with _$CurrentIndex {
...rendererStates,
...?temporaryRendererStates,
};

List<Renderer> getAllForegrounds([bool networking = true]) => [
...(temporaryForegrounds ?? foregrounds),
...toggleableForegrounds.values.expand((e) => e),
if (networking) ...networkingForegrounds,
];
}

class CurrentIndexCubit extends Cubit<CurrentIndex> {
Expand Down Expand Up @@ -129,7 +135,7 @@ class CurrentIndexCubit extends Cubit<CurrentIndex> {
BuildContext? context,
Handler<Tool>? handler,
}) async {
resetInput(bloc);
await resetInput(bloc);
final blocState = bloc.state;
if (blocState is! DocumentLoadSuccess) return null;
final document = blocState.data;
Expand All @@ -139,7 +145,11 @@ class CurrentIndexCubit extends Cubit<CurrentIndex> {
return null;
}
handler ??= Handler.fromTool(info.tools[index]);
if (context == null || handler.onSelected(context)) {
var selectState = SelectState.normal;
if (context != null) {
selectState = handler.onSelected(context);
}
if (selectState != SelectState.none) {
state.handler.dispose(bloc);
state.temporaryHandler?.dispose(bloc);
_disposeForegrounds();
Expand All @@ -149,19 +159,36 @@ class CurrentIndexCubit extends Cubit<CurrentIndex> {
await Future.wait(foregrounds.map((e) async =>
await e.setup(document, blocState.assetService, blocState.page)));
}
emit(state.copyWith(
index: index,
handler: handler,
cursor: handler.cursor ?? MouseCursor.defer,
foregrounds: foregrounds,
toolbar: handler.getToolbar(bloc),
rendererStates: handler.rendererStates,
temporaryForegrounds: null,
temporaryHandler: null,
temporaryToolbar: null,
temporaryCursor: null,
temporaryRendererStates: null,
));
if (selectState == SelectState.normal) {
emit(state.copyWith(
index: index,
handler: handler,
cursor: handler.cursor ?? MouseCursor.defer,
foregrounds: foregrounds,
toolbar: handler.getToolbar(bloc),
rendererStates: handler.rendererStates,
temporaryForegrounds: null,
temporaryHandler: null,
temporaryToolbar: null,
temporaryCursor: null,
temporaryRendererStates: null,
));
} else {
if (isHandlerEnabled(index)) {
disableHandler(bloc, index);
} else {
emit(state.copyWith(
toggleableHandlers: {
...state.toggleableHandlers,
index: handler,
},
toggleableForegrounds: {
...state.toggleableForegrounds,
index: foregrounds
},
));
}
}
}
return handler;
}
Expand All @@ -186,7 +213,7 @@ class CurrentIndexCubit extends Cubit<CurrentIndex> {
cursor ??= state.lastPosition ?? Offset.zero;
state.networkingService.sendUser(NetworkingUser(
cursor: state.transformCubit.state.localToGlobal(cursor).toPoint(),
foreground: (foregrounds ?? getForegrounds(false))
foreground: (foregrounds ?? state.getAllForegrounds(false))
.map((e) => e.element)
.whereType<PadElement>()
.toList(),
Expand Down Expand Up @@ -427,9 +454,22 @@ class CurrentIndexCubit extends Cubit<CurrentIndex> {
return null;
}

void enableHandler(DocumentBloc bloc, int index, Handler<Tool> handler) {
void toggleHandler(DocumentBloc bloc, int index) {
if (state.toggleableHandlers.containsKey(index)) {
disableHandler(bloc, index);
} else {
enableHandler(bloc, index);
}
}

Handler? enableHandler(DocumentBloc bloc, int index) {
final blocState = bloc.state;
if (blocState is! DocumentLoaded) return;
if (blocState is! DocumentLoaded) return null;
if (index < 0 || index >= blocState.info.tools.length) {
return null;
}
final tool = blocState.info.tools[index];
final handler = Handler.fromTool(tool);
final document = blocState.data;
final page = blocState.page;
final info = blocState.info;
Expand All @@ -445,6 +485,7 @@ class CurrentIndexCubit extends Cubit<CurrentIndex> {
..[index] = handler,
toggleableForegrounds: Map.from(state.toggleableForegrounds)
..[index] = foregrounds));
return handler;
}

bool disableHandler(DocumentBloc bloc, int index) {
Expand All @@ -453,14 +494,16 @@ class CurrentIndexCubit extends Cubit<CurrentIndex> {
return false;
}
handler.dispose(bloc);
final foregrounds = state.toggleableForegrounds[index];
for (final r in foregrounds ?? []) {
final foregrounds =
Map<int, List<Renderer>>.from(state.toggleableForegrounds);
final current = foregrounds.remove(index);
for (final r in current ?? []) {
r.dispose();
}
emit(state.copyWith(
toggleableHandlers: Map.from(state.toggleableHandlers)..remove(index),
toggleableForegrounds: Map.from(state.toggleableForegrounds)
..remove(index)));
toggleableHandlers: Map.from(state.toggleableHandlers)..remove(index),
toggleableForegrounds: foregrounds,
));
return true;
}

Expand Down Expand Up @@ -518,12 +561,14 @@ class CurrentIndexCubit extends Cubit<CurrentIndex> {
tool,
bloc: bloc,
temporaryState: temporaryState,
index: index,
);
}

Future<Handler<T>?> changeTemporaryHandler<T extends Tool>(
BuildContext context, T tool,
{DocumentBloc? bloc,
int? index,
TemporaryState temporaryState = TemporaryState.allowClick}) async {
bloc ??= context.read<DocumentBloc>();
final handler = Handler.fromTool(tool);
Expand All @@ -533,7 +578,9 @@ class CurrentIndexCubit extends Cubit<CurrentIndex> {
final page = blocState.page;
final currentArea = blocState.currentArea;
state.temporaryHandler?.dispose(bloc);
if (handler.onSelected(context)) {
final selectState = handler.onSelected(context);

if (selectState == SelectState.normal) {
_disposeTemporaryForegrounds();
final temporaryForegrounds = handler.createForegrounds(
this, document, page, blocState.info, currentArea);
Expand All @@ -549,15 +596,12 @@ class CurrentIndexCubit extends Cubit<CurrentIndex> {
temporaryRendererStates: handler.rendererStates,
temporaryState: temporaryState,
));
} else if (selectState == SelectState.toggle && index != null) {
toggleHandler(bloc, index);
}
return handler;
}

List<Renderer> getForegrounds([bool networking = true]) => [
...(state.temporaryForegrounds ?? state.foregrounds),
if (networking) ...state.networkingForegrounds,
];

void resetReleaseHandler(DocumentBloc bloc) {
if (state.temporaryState == TemporaryState.removeAfterRelease) {
resetTemporaryHandler(bloc, true);
Expand Down Expand Up @@ -989,8 +1033,8 @@ class CurrentIndexCubit extends Cubit<CurrentIndex> {
emit(state.copyWith(buttons: null));
}

void resetInput(DocumentBloc bloc) {
state.handler.resetInput(bloc);
Future<void> resetInput(DocumentBloc bloc) async {
await state.handler.resetInput(bloc);
emit(state.copyWith(buttons: null, pointers: []));
}

Expand Down
1 change: 1 addition & 0 deletions app/lib/dialogs/import/add.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class _AddDialogState extends State<AddDialog> {
currentIndexCubit.changeTool(
bloc,
index: state.info.tools.length,
context: context,
handler: Handler.fromTool(defaultTool),
);
}
Expand Down
4 changes: 2 additions & 2 deletions app/lib/handlers/collection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class CollectionHandler extends Handler<CollectionTool> {
CollectionHandler(super.data);

@override
bool onSelected(BuildContext context, [bool wasAdded = true]) {
SelectState onSelected(BuildContext context, [bool wasAdded = true]) {
final bloc = context.read<DocumentBloc>();
showDialog(
context: context,
Expand All @@ -13,6 +13,6 @@ class CollectionHandler extends Handler<CollectionTool> {
child: const CollectionsDialog(),
),
);
return false;
return SelectState.normal;
}
}
4 changes: 2 additions & 2 deletions app/lib/handlers/export.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class ExportHandler extends Handler<ExportTool> {
ExportHandler(super.data);

@override
bool onSelected(BuildContext context, [bool wasAdded = true]) {
SelectState onSelected(BuildContext context, [bool wasAdded = true]) {
final bloc = context.read<DocumentBloc>();
showDialog(
context: context,
Expand All @@ -14,6 +14,6 @@ class ExportHandler extends Handler<ExportTool> {
options: data.options,
),
));
return false;
return SelectState.none;
}
}
2 changes: 1 addition & 1 deletion app/lib/handlers/eye_dropper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class EyeDropperHandler extends Handler<EyeDropperTool> {
EyeDropperHandler(super.data);

@override
bool onSelected(BuildContext context, [bool wasAdded = true]) {
SelectState onSelected(BuildContext context, [bool wasAdded = true]) {
if (!wasAdded) {
context.read<CurrentIndexCubit>().changeTemporaryHandler(context, data,
temporaryState: TemporaryState.removeAfterRelease);
Expand Down
4 changes: 2 additions & 2 deletions app/lib/handlers/full_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ class FullScreenHandler extends Handler<FullScreenTool> {
FullScreenHandler(super.data);

@override
bool onSelected(BuildContext context, [bool wasAdded = true]) {
SelectState onSelected(BuildContext context, [bool wasAdded = true]) {
context.read<WindowCubit>().toggleFullScreen();
return false;
return SelectState.none;
}

@override
Expand Down
56 changes: 56 additions & 0 deletions app/lib/handlers/grid.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
part of 'handler.dart';

class GridHandler extends Handler<GridTool> {
GridHandler(super.data);

@override
List<Renderer> createForegrounds(CurrentIndexCubit currentIndexCubit,
NoteData document, DocumentPage page, DocumentInfo info,
[Area? currentArea]) =>
[GridRenderer(data)];

@override
SelectState onSelected(BuildContext context, [bool wasAdded = true]) {
return SelectState.toggle;
}
}

class GridRenderer extends Renderer<GridTool> {
GridRenderer(super.element);

@override
void build(Canvas canvas, Size size, NoteData document, DocumentPage page,
DocumentInfo info, CameraTransform transform,
[ColorScheme? colorScheme, bool foreground = false]) {
if (element.xSize > 0) {
double x = 0;
while (x < size.width) {
final localX = x / transform.size;
canvas.drawLine(
Offset(localX + transform.position.dx, transform.position.dy),
Offset(localX + transform.position.dx,
size.height / transform.size + transform.position.dy),
Paint()
..strokeWidth = 1 / transform.size
..color = element.color.toColor(),
);
x += element.xSize;
}
}
if (element.ySize > 0) {
double y = 0;
while (y < size.height) {
final localY = y / transform.size;
canvas.drawLine(
Offset(transform.position.dx, transform.position.dy + localY),
Offset(transform.position.dx + size.width / transform.size,
transform.position.dy + localY),
Paint()
..strokeWidth = 1 / transform.size
..color = element.color.toColor(),
);
y += element.ySize;
}
}
}
}
12 changes: 9 additions & 3 deletions app/lib/handlers/handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ part 'pen.dart';
part 'eye_dropper.dart';
part 'presentation.dart';
part 'redo.dart';
part 'ruler.dart';
part 'grid.dart';
part 'select.dart';
part 'shape.dart';
part 'spacer.dart';
Expand Down Expand Up @@ -153,12 +155,15 @@ class EventContext {

enum ToolStatus { normal, disabled }

enum SelectState { normal, none, toggle }

abstract class Handler<T> {
final T data;

const Handler(this.data);

bool onSelected(BuildContext context, [bool wasAdded = true]) => true;
SelectState onSelected(BuildContext context, [bool wasAdded = true]) =>
SelectState.normal;

List<Renderer> createForegrounds(CurrentIndexCubit currentIndexCubit,
NoteData document, DocumentPage page, DocumentInfo info,
Expand Down Expand Up @@ -210,7 +215,7 @@ abstract class Handler<T> {

bool canChange(PointerDownEvent event, EventContext context) => true;

void resetInput(DocumentBloc bloc) {}
FutureOr<void> resetInput(DocumentBloc bloc) {}

ToolStatus getStatus(DocumentBloc bloc) => ToolStatus.normal;

Expand Down Expand Up @@ -244,7 +249,8 @@ abstract class Handler<T> {
AssetTool() => AssetHandler(tool),
EyeDropperTool() => EyeDropperHandler(tool),
ExportTool() => ExportHandler(tool),
_ => FallbackHandler<T>(tool),
GridTool() => GridHandler(tool),
RulerTool() => RulerHandler(tool),
} as Handler<T>;
}

Expand Down
Loading

0 comments on commit 417131d

Please sign in to comment.