private void alignSelectedCenter(boolean yAlign) {
    if (selectedEntities.size == 0) return;

    UndoableActionGroup undoableGroup = new UndoableActionGroup("Change Alignment");

    float targetPos = 0;

    for (EntityProxy proxy : selectedEntities) {
      if (yAlign) targetPos += proxy.getX();
      else targetPos += proxy.getY();
    }

    targetPos /= selectedEntities.size;

    for (EntityProxy proxy : selectedEntities) {
      MoveEntityAction action = new MoveEntityAction(proxy);

      if (yAlign == true) proxy.setX(targetPos);
      else proxy.setY(targetPos);

      action.saveNewData(proxy);
      undoableGroup.add(action);
    }

    undoableGroup.finalizeGroup();
    undoModule.add(undoableGroup);
  }
  private void alignSelected(int align) {
    if (selectedEntities.size == 0) return;

    UndoableActionGroup undoableGroup = new UndoableActionGroup("Change Alignment");

    if (align == Align.left || align == Align.right) {
      float targetX = selectedEntities.get(0).getX();

      for (EntityProxy proxy : selectedEntities) {
        if (align == Align.left) {
          if (proxy.getX() < targetX) targetX = proxy.getX();
        } else {
          if (proxy.getX() > targetX) targetX = proxy.getX();
        }
      }

      for (EntityProxy proxy : selectedEntities) {
        MoveEntityAction action = new MoveEntityAction(proxy);
        proxy.setX(targetX);
        action.saveNewData(proxy);
        undoableGroup.add(action);
      }
    }

    if (align == Align.top || align == Align.bottom) {
      float targetY = selectedEntities.get(0).getY();

      for (EntityProxy proxy : selectedEntities) {
        if (align == Align.top) {
          if (proxy.getY() < targetY) targetY = proxy.getY();
        } else {
          if (proxy.getY() > targetY) targetY = proxy.getY();
        }
      }

      for (EntityProxy proxy : selectedEntities) {
        MoveEntityAction action = new MoveEntityAction(proxy);
        proxy.setY(targetY);
        action.saveNewData(proxy);
        undoableGroup.add(action);
      }
    }

    undoableGroup.finalizeGroup();
    undoModule.add(undoableGroup);
  }
  public LayersDialog(
      SceneTab sceneTab, EntityEngineConfiguration engineConfig, ModuleInjector sceneMC) {
    super(true);
    this.sceneTab = sceneTab;
    this.scene = sceneTab.getScene();
    sceneMC.injectModules(this);
    layerManipulatorManager = engineConfig.getManager(LayerManipulatorManager.class);

    setBackground(VisUI.getSkin().getDrawable("window-bg"));
    setTouchable(Touchable.enabled);

    VisImageButton layerAddButton = new VisImageButton(Icons.LAYER_ADD.drawable(), "Add new layer");
    layerUpButton = new VisImageButton(Icons.LAYER_UP.drawable(), "Move layer up");
    layerDownButton = new VisImageButton(Icons.LAYER_DOWN.drawable(), "Move layer down");
    layerSettingsButton = new VisImageButton(Icons.SETTINGS.drawable(), "Show layer settings");
    layerRemoveButton = new VisImageButton(Icons.LAYER_REMOVE.drawable(), "Delete layer");

    layerUpButton.setGenerateDisabledImage(true);
    layerDownButton.setGenerateDisabledImage(true);
    layerRemoveButton.setGenerateDisabledImage(true);

    layerAddButton.addListener(
        new VisChangeListener(
            (event, actor) ->
                DialogUtils.showInputDialog(
                    getStage(),
                    "New Layer",
                    "Name:",
                    true,
                    input -> scene.getLayerByName(input) == null,
                    (DefaultInputDialogListener)
                        input -> undoModule.execute(new LayerAddedAction(input)))));

    layerUpButton.addListener(
        new VisChangeListener((event, actor) -> undoModule.execute(new LayerMovedAction(true))));
    layerDownButton.addListener(
        new VisChangeListener((event, actor) -> undoModule.execute(new LayerMovedAction(false))));

    layerSettingsButton.addListener(
        new VisChangeListener(
            (event1, actor1) ->
                getStage().addActor(new LayerSettingsDialog(sceneMC, scene).fadeIn())));

    layerRemoveButton.addListener(
        new VisChangeListener(
            (event, actor) ->
                DialogUtils.showOptionDialog(
                    getStage(),
                    "Delete Layer",
                    "Are you sure you want to delete layer '" + scene.getActiveLayer().name + "'?",
                    OptionDialogType.YES_NO,
                    new OptionDialogAdapter() {
                      @Override
                      public void yes() {
                        UndoableActionGroup layerRemovedGroup =
                            new UndoableActionGroup("Delete Layer");
                        layerRemovedGroup.add(
                            new EntitiesRemovedAction(
                                sceneMC,
                                sceneTab.getEntityEngine(),
                                VisBagUtils.toSet(
                                    layerManipulatorManager.getEntitiesWithLayer(
                                        scene.getActiveLayerId()))));
                        layerRemovedGroup.add(new LayerRemovedAction(scene.getActiveLayer()));
                        layerRemovedGroup.finalizeGroup();

                        undoModule.execute(layerRemovedGroup);
                      }
                    })));

    layersTable = new VisTable();

    VisScrollPane layersScrollPane = new VisScrollPane(layersTable);
    layersScrollPane.setScrollingDisabled(true, false);
    layersScrollPane.setFadeScrollBars(false);

    top();
    left();
    defaults().left();
    defaults().padLeft(5).padRight(5);
    add(new VisLabel("Layers")).center().row();
    add(layersScrollPane).expandX().fillX().row();
    addSeparator();
    add(TableBuilder.build(
            layerAddButton, layerUpButton, layerDownButton, layerSettingsButton, layerRemoveButton))
        .padBottom(8);

    addListener(new EventStopper());

    rebuildLayersTable();

    sceneObservable =
        nid -> {
          if (nid == EditorScene.LAYER_ADDED
              || nid == EditorScene.LAYER_INSERTED
              || nid == EditorScene.LAYER_REMOVED
              || nid == EditorScene.LAYERS_SORTED
              || nid == EditorScene.ACTIVE_LAYER_CHANGED
              || nid == EditorScene.LAYER_DATA_CHANGED) {
            rebuildLayersTable();
            sceneTab.dirty();
          }
        };

    scene.addObservable(sceneObservable);
  }