@@ -26,12 +26,14 @@ ContextMenuBuilder buildElementsContextMenu(
2626) {
2727 final cubit = bloc.editorController;
2828 final settingsCubit = state.settingsCubit;
29- final operations =
30- Map <
31- Renderer <PadElement >,
32- Map <RendererOperation , RendererOperationCallback >
33- >.fromIterable (renderers, value: (e) => e.getOperations ());
34- final operationKeys = operations.values.expand ((e) => e.keys).toList ();
29+ final operations = {
30+ for (final renderer in renderers) renderer: renderer.getOperations (),
31+ };
32+ final operationKeys = {
33+ ...operations.values.expand ((e) => e.keys),
34+ RendererOperation .flipHorizontal,
35+ RendererOperation .flipVertical,
36+ };
3537 return (context) {
3638 final rendererContextMenuItem = renderers.length == 1
3739 ? renderers.first.getContextMenuItem (bloc, context)
@@ -142,26 +144,30 @@ ContextMenuBuilder buildElementsContextMenu(
142144 .toList (),
143145 label: AppLocalizations .of (context).arrange,
144146 ),
145- if (operationKeys.isNotEmpty)
146- ContextMenuGroup (
147- label: AppLocalizations .of (context).operations,
148- icon: const PhosphorIcon (PhosphorIconsLight .wrench),
149- children: operationKeys
150- .map (
151- (e) => MenuItemButton (
152- leadingIcon: PhosphorIcon (e.icon (PhosphorIconsStyle .light)),
153- child: Text (e.getLocalizedName (context)),
154- onPressed: () {
147+ ContextMenuGroup (
148+ label: AppLocalizations .of (context).operations,
149+ icon: const PhosphorIcon (PhosphorIconsLight .wrench),
150+ children: operationKeys
151+ .map (
152+ (e) => MenuItemButton (
153+ leadingIcon: PhosphorIcon (e.icon (PhosphorIconsStyle .light)),
154+ child: Text (e.getLocalizedName (context)),
155+ onPressed: () {
156+ final flipAxis = e.flipAxis;
157+ if (flipAxis == null ) {
155158 operations.values
156159 .map ((v) => v[e])
157160 .nonNulls
158161 .forEach ((e) => e (bloc, context));
159- if (context.mounted) Navigator .of (context).pop (true );
160- },
161- ),
162- )
163- .toList (),
164- ),
162+ } else {
163+ _flipElements (bloc, renderers, rect, flipAxis);
164+ }
165+ if (context.mounted) Navigator .of (context).pop (true );
166+ },
167+ ),
168+ )
169+ .toList (),
170+ ),
165171 ? rendererContextMenuItem,
166172 if (renderers.length == 1 &&
167173 exportService.isExportable (renderers.first.element))
@@ -199,3 +205,24 @@ ContextMenuBuilder buildElementsContextMenu(
199205 ];
200206 };
201207}
208+
209+ void _flipElements (
210+ DocumentBloc bloc,
211+ List <Renderer <PadElement >> renderers,
212+ Rect selectionRect,
213+ Axis axis,
214+ ) {
215+ final changes = Map .fromEntries (
216+ renderers.map ((renderer) {
217+ final id = renderer.element.id;
218+ if (id == null ) return null ;
219+ final transformed = renderer.flip (
220+ axis: axis,
221+ selectionRect: selectionRect,
222+ );
223+ if (transformed == null ) return null ;
224+ return MapEntry (id, [transformed.element]);
225+ }).nonNulls,
226+ );
227+ if (changes.isNotEmpty) bloc.add (ElementsChanged (changes));
228+ }
0 commit comments