All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.intellij.uiDesigner.actions.AbstractMoveSelectionAction Maven / Gradle / Ivy

Go to download

A packaging of the IntelliJ Community Edition ui-designer library. This is release number 1 of trunk branch 142.

The newest version!
/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.uiDesigner.actions;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.util.Ref;
import com.intellij.uiDesigner.FormEditingUtil;
import com.intellij.uiDesigner.designSurface.GuiEditor;
import com.intellij.uiDesigner.radComponents.RadAtomicComponent;
import com.intellij.uiDesigner.radComponents.RadComponent;
import com.intellij.uiDesigner.radComponents.RadContainer;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;

/**
 * @author Anton Katilin
 * @author Vladimir Kondratyev
 */
abstract class AbstractMoveSelectionAction extends AnAction implements DumbAware {
  private static final Logger LOG=Logger.getInstance("#com.intellij.uiDesigner.actions.MoveSelectionToRightAction");

  private final GuiEditor myEditor;
  private final boolean myExtend;
  private final boolean myMoveToLast;

  public AbstractMoveSelectionAction(@NotNull final GuiEditor editor, boolean extend, final boolean moveToLast) {
    myEditor = editor;
    myExtend = extend;
    myMoveToLast = moveToLast;
  }

  public final void actionPerformed(final AnActionEvent e) {
    final ArrayList selectedComponents = FormEditingUtil.getSelectedComponents(myEditor);
    final JComponent rootContainerDelegee = myEditor.getRootContainer().getDelegee();
    if(selectedComponents.size() == 0){
      moveToFirstComponent(rootContainerDelegee);
      return;
    }
    RadComponent selectedComponent = myEditor.getSelectionLead();
    if (selectedComponent == null || !selectedComponents.contains(selectedComponent)) {
      selectedComponent = selectedComponents.get(0);
    }

    if (moveSelectionByGrid(selectedComponent) || myMoveToLast) {
      return;
    }

    // 1. We need to get coordinates of all editor's component in the same
    // coordinate system. For example, in the RadRootContainer rootContainerDelegee's coordinate system.

    final ArrayList components = new ArrayList();
    final ArrayList points = new ArrayList();
    final RadComponent selectedComponent1 = selectedComponent;
    FormEditingUtil.iterate(
      myEditor.getRootContainer(),
      new FormEditingUtil.ComponentVisitor() {
        public boolean visit(final RadComponent component) {
          if (component instanceof RadAtomicComponent) {
            if(selectedComponent1.equals(component)){
              return true;
            }
            if (!FormEditingUtil.isComponentSwitchedInView(component)) {
              return true;
            }
            components.add(component);
            final JComponent _delegee = component.getDelegee();
            final Point p = SwingUtilities.convertPoint(
              _delegee,
              new Point(0, 0),
              rootContainerDelegee
            );
            p.x += _delegee.getWidth() / 2;
            p.y += _delegee.getHeight() / 2;
            points.add(p);
          }
          return true;
        }
      }
    );
    if(components.size() == 0){
      return;
    }

    // 2.
    final Point source = SwingUtilities.convertPoint(
      selectedComponent.getDelegee(),
      new Point(0, 0),
      rootContainerDelegee
    );
    source.x += selectedComponent.getDelegee().getWidth() / 2;
    source.y += selectedComponent.getDelegee().getHeight() / 2;
    int min = Integer.MAX_VALUE;
    int nextSelectedIndex = -1;
    for(int i = points.size() - 1; i >= 0; i--){
      final int distance = calcDistance(source, points.get(i));
      if(distance < min){
        min = distance;
        nextSelectedIndex = i;
      }
    }
    if(min == Integer.MAX_VALUE){
      return;
    }

    LOG.assertTrue(nextSelectedIndex != -1);
    final RadComponent component = components.get(nextSelectedIndex);
    selectOrExtend(component);
  }

  private void selectOrExtend(final RadComponent component) {
    if (myExtend) {
      FormEditingUtil.selectComponent(myEditor, component);
    }
    else {
      FormEditingUtil.selectSingleComponent(myEditor, component);
    }
  }

  private void moveToFirstComponent(final JComponent rootContainerDelegee) {
    final int[] minX = new int[]{Integer.MAX_VALUE};
    final int[] minY = new int[]{Integer.MAX_VALUE};
    final Ref componentToBeSelected = new Ref();
    FormEditingUtil.iterate(
      myEditor.getRootContainer(),
      new FormEditingUtil.ComponentVisitor() {
        public boolean visit(final RadComponent component) {
          if (component instanceof RadAtomicComponent) {
            final JComponent _delegee = component.getDelegee();
            final Point p = SwingUtilities.convertPoint(
              _delegee,
              new Point(0, 0),
              rootContainerDelegee
            );
            if(minX[0] > p.x || minY[0] > p.y){
              minX[0] = p.x;
              minY[0] = p.y;
              componentToBeSelected.set(component);
            }
          }
          return true;
        }
      }
    );
    if(!componentToBeSelected.isNull()){
      FormEditingUtil.selectComponent(myEditor, componentToBeSelected.get());
    }
  }

  @Override
  public void update(AnActionEvent e) {
    e.getPresentation().setEnabled(!myEditor.getMainProcessor().isProcessorActive());
  }

  private boolean moveSelectionByGrid(final RadComponent selectedComponent) {
    final RadContainer parent = selectedComponent.getParent();
    if (parent == null || !parent.getLayoutManager().isGrid()) {
      return false;
    }

    int row = selectedComponent.getConstraints().getRow();
    int column = selectedComponent.getConstraints().getColumn();

    RadComponent lastComponent = null;
    do {
      row += getRowMoveDelta();
      column += getColumnMoveDelta();
      if (row < 0 || row >= parent.getGridRowCount() || column < 0 || column >= parent.getGridColumnCount()) {
        if (myMoveToLast) {
          break;
        }
        return false;
      }

      final RadComponent component = parent.getComponentAtGrid(row, column);
      if (component != null && component != selectedComponent) {
        if (myMoveToLast) {
          if (myExtend) {
            FormEditingUtil.selectComponent(myEditor, component);
          }
          lastComponent = component;
        }
        else {
          selectOrExtend(component);
          return true;
        }
      }
    } while(true);

    if (lastComponent != null) {
      selectOrExtend(lastComponent);
      return true;
    }
    return false;
  }

  protected abstract int calcDistance(Point source, Point point);

  protected int getColumnMoveDelta() {
    return 0;
  }

  protected int getRowMoveDelta() {
    return 0;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy