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

com.intellij.uiDesigner.radComponents.RadSplitPane 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.radComponents;

import com.intellij.uiDesigner.ModuleProvider;
import com.intellij.uiDesigner.UIDesignerBundle;
import com.intellij.uiDesigner.UIFormXmlConstants;
import com.intellij.uiDesigner.XmlWriter;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.designSurface.*;
import com.intellij.uiDesigner.lw.LwSplitPane;
import com.intellij.uiDesigner.palette.Palette;
import com.intellij.uiDesigner.snapShooter.SnapshotContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;

/**
 * @author Anton Katilin
 * @author Vladimir Kondratyev
 */
public final class RadSplitPane extends RadContainer {
  public static class Factory extends RadComponentFactory {
    public RadComponent newInstance(ModuleProvider module, Class aClass, String id) {
      return new RadSplitPane(module, aClass, id);
    }

    public RadComponent newInstance(final Class componentClass, final String id, final Palette palette) {
      return new RadSplitPane(componentClass, id, palette);
    }
  }

  public RadSplitPane(final ModuleProvider module, final Class componentClass, final String id) {
    super(module, componentClass, id);
  }

  public RadSplitPane(Class componentClass, @NotNull final String id, final Palette palette) {
    super(componentClass, id, palette);
  }

  @Override protected RadLayoutManager createInitialLayoutManager() {
    return new RadSplitPaneLayoutManager();
  }

  private static boolean isEmptySplitComponent(final Component component) {
    return component == null || ((JComponent)component).getClientProperty(CLIENT_PROP_RAD_COMPONENT) == null;
  }

  private boolean isLeft(Point pnt) {
    if (getSplitPane().getOrientation() == JSplitPane.VERTICAL_SPLIT) {
      return pnt.y < getDividerPos();
    }
    else {
      return pnt.x < getDividerPos();
    }
  }

  private int getDividerPos() {
    final JSplitPane splitPane = getSplitPane();
    int size = splitPane.getOrientation() == JSplitPane.VERTICAL_SPLIT ? splitPane.getHeight() : splitPane.getWidth();
    if (splitPane.getDividerLocation() > splitPane.getDividerSize() &&
        splitPane.getDividerLocation() < size - splitPane.getDividerSize()) {
      return splitPane.getDividerLocation() + splitPane.getDividerSize() / 2;
    }
    else {
      return size / 2;
    }
  }

  private JSplitPane getSplitPane() {
    return (JSplitPane)getDelegee();
  }

  @Override @Nullable
  public EventProcessor getEventProcessor(final MouseEvent event) {
    final JSplitPane splitPane = getSplitPane();
    Point pnt = SwingUtilities.convertPoint(event.getComponent(), event.getPoint(), splitPane);
    int pos = (splitPane.getOrientation() == JSplitPane.VERTICAL_SPLIT) ? pnt.y : pnt.x;
    if (event.getID() == MouseEvent.MOUSE_PRESSED &&
        pos >= splitPane.getDividerLocation() &&
        pos < splitPane.getDividerLocation() + splitPane.getDividerSize()) {
      return new DividerDragProcessor();
    }
    return null;
  }

  public void write(final XmlWriter writer) {
    writer.startElement(UIFormXmlConstants.ELEMENT_SPLITPANE);
    try {
      writeId(writer);
      writeClassIfDifferent(writer, JSplitPane.class.getName());
      writeBinding(writer);

      // Constraints and properties
      writeConstraints(writer);
      writeProperties(writer);

      // Margin and border
      writeBorder(writer);
      writeChildren(writer);
    }
    finally {
      writer.endElement(); // scrollpane
    }
  }


  @Override
  protected void importSnapshotComponent(final SnapshotContext context, final JComponent component) {
    JSplitPane splitPane = (JSplitPane) component;
    importSideComponent(splitPane.getLeftComponent(), context, LwSplitPane.POSITION_LEFT);
    importSideComponent(splitPane.getRightComponent(), context, LwSplitPane.POSITION_RIGHT);
  }

  private void importSideComponent(final Component sideComponent,
                                   final SnapshotContext context,
                                   final String position) {
    if (sideComponent instanceof JComponent) {
      RadComponent radSideComponent = createSnapshotComponent(context, (JComponent) sideComponent);
      if (radSideComponent != null) {
        radSideComponent.setCustomLayoutConstraints(position);
        addComponent(radSideComponent);
      }
    }
  }

  private class RadSplitPaneLayoutManager extends RadLayoutManager {

    @Nullable public String getName() {
      return null;
    }

    public void writeChildConstraints(final XmlWriter writer, final RadComponent child) {
      writer.startElement("splitpane");
      try {
        final String position = (String)child.getCustomLayoutConstraints();
        if (!LwSplitPane.POSITION_LEFT.equals(position) && !LwSplitPane.POSITION_RIGHT.equals(position)) {
          throw new IllegalStateException("invalid position: " + position);
        }
        writer.addAttribute("position", position);
      }
      finally {
        writer.endElement();
      }
    }

    public void addComponentToContainer(final RadContainer container, final RadComponent component, final int index) {
      final JSplitPane splitPane = (JSplitPane) container.getDelegee();
      final JComponent delegee = component.getDelegee();
      if (LwSplitPane.POSITION_LEFT.equals(component.getCustomLayoutConstraints())) {
        splitPane.setLeftComponent(delegee);
      }
      else if (LwSplitPane.POSITION_RIGHT.equals(component.getCustomLayoutConstraints())) {
        splitPane.setRightComponent(delegee);
      }
      else {
        throw new IllegalStateException("invalid layout constraints on component added to RadSplitPane");
      }
    }

    @Override @NotNull
    public ComponentDropLocation getDropLocation(RadContainer container, @Nullable final Point location) {
      if (location == null) {
        return new MyDropLocation(isEmptySplitComponent(getSplitPane().getLeftComponent()));
      }
      return new MyDropLocation(isLeft(location));
    }
  }

  private class MyDropLocation implements ComponentDropLocation {
    private final boolean myLeft;

    public MyDropLocation(final boolean left) {
      myLeft = left;
    }

    public RadContainer getContainer() {
      return RadSplitPane.this;
    }

    public boolean canDrop(ComponentDragObject dragObject) {
      /*
      TODO[yole]: support multi-drop (is it necessary?)
      if (componentCount == 2) {
        return isEmptySplitComponent(getSplitPane().getLeftComponent()) &&
               isEmptySplitComponent(getSplitPane().getRightComponent());
      }
      */
      return dragObject.getComponentCount() == 1 &&
             isEmptySplitComponent(myLeft ? getSplitPane().getLeftComponent() : getSplitPane().getRightComponent());
    }

    public void placeFeedback(FeedbackLayer feedbackLayer, ComponentDragObject dragObject) {
      final JSplitPane splitPane = getSplitPane();
      int dividerPos = getDividerPos();
      int dividerStartPos = dividerPos - splitPane.getDividerSize()/2;
      int dividerEndPos = dividerPos + splitPane.getDividerSize() - splitPane.getDividerSize()/2;
      Rectangle rc;
      if (splitPane.getOrientation() == JSplitPane.VERTICAL_SPLIT) {
        rc = myLeft
             ? new Rectangle(0, 0, getWidth(), dividerStartPos)
             : new Rectangle(0, dividerEndPos, getWidth(), getHeight() - dividerEndPos);
      }
      else {
        rc = myLeft
             ? new Rectangle(0, 0, dividerStartPos, getHeight())
             : new Rectangle(dividerEndPos, 0, getWidth() - dividerEndPos, getHeight());
      }
      feedbackLayer.putFeedback(getDelegee(), rc, getInsertFeedbackTooltip());
    }

    private String getInsertFeedbackTooltip() {
      String pos;
      if (getSplitPane().getOrientation() == JSplitPane.VERTICAL_SPLIT) {
        pos = myLeft ? UIDesignerBundle.message("insert.feedback.top") : UIDesignerBundle.message("insert.feedback.bottom");
      }
      else {
        pos = myLeft ? UIDesignerBundle.message("insert.feedback.left") : UIDesignerBundle.message("insert.feedback.right");
      }
      return getDisplayName() + " (" + pos + ")";
    }

    public void processDrop(GuiEditor editor,
                            RadComponent[] components,
                            GridConstraints[] constraintsToAdjust,
                            ComponentDragObject dragObject) {
      components[0].setCustomLayoutConstraints(myLeft ? LwSplitPane.POSITION_LEFT : LwSplitPane.POSITION_RIGHT);
      addComponent(components[0]);
    }

    @Nullable
    public ComponentDropLocation getAdjacentLocation(Direction direction) {
      return null;
    }
  }

  private class DividerDragProcessor extends EventProcessor {
    protected void processKeyEvent(KeyEvent e) {
    }

    protected void processMouseEvent(MouseEvent event) {
      JSplitPane splitPane = getSplitPane();
      Point pnt = SwingUtilities.convertPoint(event.getComponent(), event.getPoint(), splitPane);
      splitPane.dispatchEvent(new MouseEvent(splitPane, event.getID(), event.getWhen(), event.getModifiers(), pnt.x, pnt.y,
                                             event.getClickCount(), event.isPopupTrigger(), event.getButton()));
    }

    @Override public boolean needMousePressed() {
      return true;
    }

    protected boolean cancelOperation() {
      return false;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy