Skip to content

Commit

Permalink
Merge pull request #49 from bluefireteam/feat/rotate-controls
Browse files Browse the repository at this point in the history
feat: adding rotate features
  • Loading branch information
erickzanardo authored Mar 13, 2024
2 parents 9b427e3 + 81a830d commit 297c1ae
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 1 deletion.
9 changes: 8 additions & 1 deletion packages/mini_sprite_editor/lib/l10n/arb/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,13 @@
"flipHorizontally": "Flip horizontally",
"@flipHorizontally": {
"description": "Label for flipping the sprite horizontally"
},
"rotateClockwise": "Rotate clockwise",
"@rotateClockwise": {
"description": "Label for rotating the sprite clockwise"
},
"rotateCounterClockwise": "Rotate counter clockwise",
"@rotateCounterClockwise": {
"description": "Label for rotating the sprite counter clockwise"
}

}
30 changes: 30 additions & 0 deletions packages/mini_sprite_editor/lib/sprite/cubit/sprite_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,36 @@ class SpriteCubit extends ReplayCubit<SpriteState> {
emit(state.copyWith(pixels: newPixels));
}

void rotateSpriteClockwise() {
final newPixels = List.generate(
state.pixels[0].length,
(i) => List.generate(state.pixels.length, (j) => -1),
);

for (var y = 0; y < state.pixels.length; y++) {
for (var x = 0; x < state.pixels[y].length; x++) {
newPixels[x][state.pixels.length - y - 1] = state.pixels[y][x];
}
}

emit(state.copyWith(pixels: newPixels));
}

void rotateSpriteCounterClockwise() {
final newPixels = List.generate(
state.pixels[0].length,
(i) => List.generate(state.pixels.length, (j) => -1),
);

for (var y = 0; y < state.pixels.length; y++) {
for (var x = 0; x < state.pixels[y].length; x++) {
newPixels[state.pixels[0].length - x - 1][y] = state.pixels[y][x];
}
}

emit(state.copyWith(pixels: newPixels));
}

Offset _projectOffset(Offset position, double pixelSize) {
final projected = position / pixelSize;
final x = projected.dx.floorToDouble();
Expand Down
18 changes: 18 additions & 0 deletions packages/mini_sprite_editor/lib/sprite/view/sprite_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,24 @@ class SpriteView extends StatelessWidget {
child: const Icon(Icons.transform),
),
),
IconButton(
key: const Key('rotate_clockwise_key'),
onPressed: () async {
context.read<SpriteCubit>().rotateSpriteClockwise();
},
tooltip: l10n.rotateClockwise,
icon: const Icon(Icons.rotate_right),
),
IconButton(
key: const Key('rotate_counter_clockwise_key'),
onPressed: () async {
context
.read<SpriteCubit>()
.rotateSpriteCounterClockwise();
},
tooltip: l10n.rotateCounterClockwise,
icon: const Icon(Icons.rotate_left),
),
IconButton(
key: const Key('copy_to_clipboard_key'),
onPressed: () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,46 @@ void main() {
expect(cubit.state, equals(expected));
});

test('rotate clockwise', () {
final cubit = SpriteCubit();
final state = SpriteState.initial().copyWith(
pixels: [
[1, 1],
[0, 0],
],
);
final expected = SpriteState.initial().copyWith(
pixels: [
[0, 1],
[0, 1],
],
);
cubit
..setSprite(state.pixels)
..rotateSpriteClockwise();
expect(cubit.state, equals(expected));
});

test('rotate counter clockwise', () {
final cubit = SpriteCubit();
final state = SpriteState.initial().copyWith(
pixels: [
[1, 1],
[0, 0],
],
);
final expected = SpriteState.initial().copyWith(
pixels: [
[1, 0],
[1, 0],
],
);
cubit
..setSprite(state.pixels)
..rotateSpriteCounterClockwise();
expect(cubit.state, equals(expected));
});

group('importFromClipboard', () {
late GetClipboardStub stub;
final sprite = MiniSprite(const [
Expand Down
42 changes: 42 additions & 0 deletions packages/mini_sprite_editor/test/sprite/view/sprite_view_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,48 @@ void main() async {
});
});

group('rotate', () {
testWidgets('rotates clockwise', (tester) async {
_mockState(
spriteState: SpriteState.initial(),
toolsState: ToolsState.initial(),
configState: ConfigState.initial(),
libraryState: LibraryState.initial(),
);
await tester.pumpTest(
spriteCubit: spriteCubit,
toolsCubit: toolsCubit,
configCubit: configCubit,
libraryCubit: libraryCubit,
);

await tester.tap(find.byKey(const Key('rotate_clockwise_key')));
await tester.pump();

verify(() => spriteCubit.rotateSpriteClockwise()).called(1);
});

testWidgets('rotates counter clockwise', (tester) async {
_mockState(
spriteState: SpriteState.initial(),
toolsState: ToolsState.initial(),
configState: ConfigState.initial(),
libraryState: LibraryState.initial(),
);
await tester.pumpTest(
spriteCubit: spriteCubit,
toolsCubit: toolsCubit,
configCubit: configCubit,
libraryCubit: libraryCubit,
);

await tester.tap(find.byKey(const Key('rotate_counter_clockwise_key')));
await tester.pump();

verify(() => spriteCubit.rotateSpriteCounterClockwise()).called(1);
});
});

group('tools', () {
group('brush', () {
testWidgets(
Expand Down

0 comments on commit 297c1ae

Please sign in to comment.