Skip to content

Commit 9b427e3

Browse files
authored
Merge pull request #48 from bluefireteam/feat/flip
2 parents c50986c + b5a53d7 commit 9b427e3

File tree

5 files changed

+124
-0
lines changed

5 files changed

+124
-0
lines changed

packages/mini_sprite_editor/lib/l10n/arb/app_en.arb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,5 +207,14 @@
207207
"addColor": "Add color",
208208
"@addColor": {
209209
"description": "Label for add color"
210+
},
211+
"flipVertically": "Flip vertically",
212+
"@flipVertically": {
213+
"description": "Label for flipping the sprite vertically"
214+
},
215+
"flipHorizontally": "Flip horizontally",
216+
"@flipHorizontally": {
217+
"description": "Label for flipping the sprite horizontally"
210218
}
219+
211220
}

packages/mini_sprite_editor/lib/sprite/cubit/sprite_cubit.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ class SpriteCubit extends ReplayCubit<SpriteState> {
7979
emit(state.copyWith(cursorPosition: const Offset(-1, -1)));
8080
}
8181

82+
void flipSpriteVertically() {
83+
final newPixels = [
84+
...state.pixels.reversed.map((e) => [...e]),
85+
];
86+
emit(state.copyWith(pixels: newPixels));
87+
}
88+
89+
void flipSpriteHorizontally() {
90+
final newPixels = [
91+
...state.pixels.map((e) => [...e.reversed]),
92+
];
93+
emit(state.copyWith(pixels: newPixels));
94+
}
95+
8296
Offset _projectOffset(Offset position, double pixelSize) {
8397
final projected = position / pixelSize;
8498
final x = projected.dx.floorToDouble();

packages/mini_sprite_editor/lib/sprite/view/sprite_page.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,25 @@ class SpriteView extends StatelessWidget {
172172
gridActive ? Icons.grid_on : Icons.grid_off,
173173
),
174174
),
175+
IconButton(
176+
key: const Key('flip_vertically_key'),
177+
onPressed: () async {
178+
context.read<SpriteCubit>().flipSpriteVertically();
179+
},
180+
tooltip: l10n.flipVertically,
181+
icon: const Icon(Icons.transform),
182+
),
183+
IconButton(
184+
key: const Key('flip_horizontally_key'),
185+
onPressed: () async {
186+
context.read<SpriteCubit>().flipSpriteHorizontally();
187+
},
188+
tooltip: l10n.flipHorizontally,
189+
icon: Transform.rotate(
190+
angle: 1.5708,
191+
child: const Icon(Icons.transform),
192+
),
193+
),
175194
IconButton(
176195
key: const Key('copy_to_clipboard_key'),
177196
onPressed: () {

packages/mini_sprite_editor/test/sprite/cubit/sprite_cubit_test.dart

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,46 @@ void main() {
5757
},
5858
);
5959

60+
test('flip vertically', () {
61+
final cubit = SpriteCubit();
62+
final state = SpriteState.initial().copyWith(
63+
pixels: [
64+
[1, 1],
65+
[0, 0],
66+
],
67+
);
68+
final expected = SpriteState.initial().copyWith(
69+
pixels: [
70+
[0, 0],
71+
[1, 1],
72+
],
73+
);
74+
cubit
75+
..setSprite(state.pixels)
76+
..flipSpriteVertically();
77+
expect(cubit.state, equals(expected));
78+
});
79+
80+
test('flip horizontally', () {
81+
final cubit = SpriteCubit();
82+
final state = SpriteState.initial().copyWith(
83+
pixels: [
84+
[1, 1],
85+
[0, 0],
86+
],
87+
);
88+
final expected = SpriteState.initial().copyWith(
89+
pixels: [
90+
[1, 1],
91+
[0, 0],
92+
],
93+
);
94+
cubit
95+
..setSprite(state.pixels)
96+
..flipSpriteHorizontally();
97+
expect(cubit.state, equals(expected));
98+
});
99+
60100
group('importFromClipboard', () {
61101
late GetClipboardStub stub;
62102
final sprite = MiniSprite(const [

packages/mini_sprite_editor/test/sprite/view/sprite_view_test.dart

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,48 @@ void main() async {
213213
verify(() => spriteCubit.cursorUp(any(), any())).called(1);
214214
});
215215

216+
group('flip', () {
217+
testWidgets('flips horizontally', (tester) async {
218+
_mockState(
219+
spriteState: SpriteState.initial(),
220+
toolsState: ToolsState.initial(),
221+
configState: ConfigState.initial(),
222+
libraryState: LibraryState.initial(),
223+
);
224+
await tester.pumpTest(
225+
spriteCubit: spriteCubit,
226+
toolsCubit: toolsCubit,
227+
configCubit: configCubit,
228+
libraryCubit: libraryCubit,
229+
);
230+
231+
await tester.tap(find.byKey(const Key('flip_horizontally_key')));
232+
await tester.pump();
233+
234+
verify(() => spriteCubit.flipSpriteHorizontally()).called(1);
235+
});
236+
237+
testWidgets('flips vertically', (tester) async {
238+
_mockState(
239+
spriteState: SpriteState.initial(),
240+
toolsState: ToolsState.initial(),
241+
configState: ConfigState.initial(),
242+
libraryState: LibraryState.initial(),
243+
);
244+
await tester.pumpTest(
245+
spriteCubit: spriteCubit,
246+
toolsCubit: toolsCubit,
247+
configCubit: configCubit,
248+
libraryCubit: libraryCubit,
249+
);
250+
251+
await tester.tap(find.byKey(const Key('flip_vertically_key')));
252+
await tester.pump();
253+
254+
verify(() => spriteCubit.flipSpriteVertically()).called(1);
255+
});
256+
});
257+
216258
group('tools', () {
217259
group('brush', () {
218260
testWidgets(

0 commit comments

Comments
 (0)