# HG changeset patch # Parent 7ab8e84f33651a16b5fe6c78001d50fd387bbfff diff --git a/core.windows/src/org/netbeans/core/windows/Central.java b/core.windows/src/org/netbeans/core/windows/Central.java --- a/core.windows/src/org/netbeans/core/windows/Central.java +++ b/core.windows/src/org/netbeans/core/windows/Central.java @@ -552,6 +552,25 @@ WindowManager.PROP_MODES, null, null); } + /** change weights of splitter children */ + public boolean adjustSizes(ModeImpl mode, WindowManager.WeightCalculator wc) { + SplitConstraint[] oldC = getModeConstraints(mode); + if(!model.adjustSizes(mode, wc)) { + return false; + } + SplitConstraint[] newC = getModeConstraints(mode); + + if(isVisible()) { + // XXX is following more appropriate? + // mode.getKind() == Constants.MODE_KIND_EDITOR + // ? View.CHANGE_EDITOR_AREA_CONSTRAINTS_CHANGED + // : View.CHANGE_MODE_CONSTRAINTS_CHANGED, + viewRequestor.scheduleRequest( + new ViewRequest(null, View.CHANGE_MODE_CONSTRAINTS_CHANGED, oldC, newC)); + } + return true; + } + /** Removes mode from model and requests view (if needed). */ public void removeMode(ModeImpl mode) { if(!getModes().contains(mode)) { diff --git a/core.windows/src/org/netbeans/core/windows/WindowManagerImpl.java b/core.windows/src/org/netbeans/core/windows/WindowManagerImpl.java --- a/core.windows/src/org/netbeans/core/windows/WindowManagerImpl.java +++ b/core.windows/src/org/netbeans/core/windows/WindowManagerImpl.java @@ -766,6 +766,33 @@ central.addMode(mode, modeConstraints); } } + + public void addModeOnSide(Mode mode, String side, TopComponent tc) { + if(tc == null || !tc.isOpened()) + throw new NullPointerException("null TopComponent or not open"); + + central.userDroppedTopComponents((ModeImpl)mode, new TopComponent[] {tc}, side); + } + + public void addModeAround(Mode mode, String side, TopComponent tc) { + if(tc == null || !tc.isOpened()) + throw new NullPointerException("null TopComponent or not open"); + + TopComponent[] tcs = new TopComponent[] {tc}; + if(((ModeImpl)mode).getKind() == Constants.MODE_KIND_EDITOR) { + central.userDroppedTopComponentsAroundEditor( + tcs, side, Constants.MODE_KIND_EDITOR); + } else { + central.userDroppedTopComponentsAround(tcs, side); + } + } + + /** change weights of splitter children */ + @Override + public boolean adjustSizes(Mode mode, WeightCalculator wc) + { + return central.adjustSizes((ModeImpl)mode, wc); + } /** Removes mode. */ public void removeMode(ModeImpl mode) { diff --git a/core.windows/src/org/netbeans/core/windows/model/DefaultModel.java b/core.windows/src/org/netbeans/core/windows/model/DefaultModel.java --- a/core.windows/src/org/netbeans/core/windows/model/DefaultModel.java +++ b/core.windows/src/org/netbeans/core/windows/model/DefaultModel.java @@ -70,6 +70,7 @@ import org.netbeans.core.windows.WindowSystemSnapshot; import org.openide.windows.RetainLocation; import org.openide.windows.TopComponent; +import org.openide.windows.WindowManager; /** @@ -283,6 +284,12 @@ } } + /** change weights of splitter children */ + public boolean adjustSizes(ModeImpl mode, WindowManager.WeightCalculator wc) { + synchronized(LOCK_MODES) { + return modesSubModel.adjustSizes(mode, wc); + } + } /** Removes mode. */ public void removeMode(ModeImpl mode) { diff --git a/core.windows/src/org/netbeans/core/windows/model/Model.java b/core.windows/src/org/netbeans/core/windows/model/Model.java --- a/core.windows/src/org/netbeans/core/windows/model/Model.java +++ b/core.windows/src/org/netbeans/core/windows/model/Model.java @@ -56,6 +56,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.openide.windows.WindowManager; /** @@ -106,6 +107,8 @@ // XXX /** Adds mode around editor area (attaches from side). */ public void addModeAroundEditor(ModeImpl mode, String side); + /** change weights of splitter children */ + public boolean adjustSizes(ModeImpl mode, WindowManager.WeightCalculator wc); /** Removes mode. */ public void removeMode(ModeImpl mode); /** Sets mode constraints. */ diff --git a/core.windows/src/org/netbeans/core/windows/model/ModesSubModel.java b/core.windows/src/org/netbeans/core/windows/model/ModesSubModel.java --- a/core.windows/src/org/netbeans/core/windows/model/ModesSubModel.java +++ b/core.windows/src/org/netbeans/core/windows/model/ModesSubModel.java @@ -58,6 +58,7 @@ import java.util.Set; import org.netbeans.core.windows.WindowManagerImpl; import org.openide.windows.TopComponent; +import org.openide.windows.WindowManager; /** @@ -282,6 +283,15 @@ slideInSizes.put( side+tcId, new Integer(size) ); } } + + /** change weights of splitter children */ + public boolean adjustSizes(ModeImpl mode, WindowManager.WeightCalculator wc) { + if(mode.getKind() == Constants.MODE_KIND_EDITOR) { + return editorSplitSubModel.getEditorArea().adjustSizes(mode, wc); + } else { + return editorSplitSubModel.adjustSizes(mode, wc); + } + } public boolean removeMode(ModeImpl mode) { int kind = mode.getKind(); diff --git a/core.windows/src/org/netbeans/core/windows/model/SplitSubModel.java b/core.windows/src/org/netbeans/core/windows/model/SplitSubModel.java --- a/core.windows/src/org/netbeans/core/windows/model/SplitSubModel.java +++ b/core.windows/src/org/netbeans/core/windows/model/SplitSubModel.java @@ -50,6 +50,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.netbeans.core.windows.*; +import org.openide.windows.WindowManager; /** @@ -1162,6 +1163,75 @@ } } // End of nested ModeNode class. + /** change weights of splitter children */ + public boolean adjustSizes(ModeImpl mode, WindowManager.WeightCalculator wc) { + if(mode == null) { + throw new NullPointerException("Cannot adjust sizes of null mode!"); + } + if(mode.getOpenedTopComponents().isEmpty()) + return false; + ModeNode node = getModeNode(mode); + if(!isInTree(node)) { + return false; + } + SplitNode parent = node.getParent(); + if(parent == null) + return false; + List children = parent.getVisibleChildren(); + List w = new ArrayList(children.size()); + + int iTarget = -1; + for(int i = 0; i < children.size(); i++) { + Node n = children.get(i); + if(node.equals(n)) { + iTarget = i; + } + w.add(parent.getChildSplitWeight(n)); + } + + SiblingState state = new SiblingState(w, iTarget, + parent.getOrientation() == Constants.HORIZONTAL + ? WindowManager.SiblingState.Orientation.HORIZONTAL + : WindowManager.SiblingState.Orientation.VERTICAL); + w = wc.getWeights(state); + + // the weight for the node of interest must be different + if(w.size() != state.weights.size() + || w.get(iTarget).equals(state.weights.get(iTarget))) { + return false; + } + Iterator it = w.iterator(); + for(Node n : children) { + parent.setChildSplitWeight(n, it.next()); + } + return true; + } + + private static class SiblingState implements WindowManager.SiblingState { + private List weights; + private int targetIndex; + private WindowManager.SiblingState.Orientation orientation; + + public SiblingState(List weights, int targetIndex, + Orientation orientation) + { + this.weights = weights; + this.targetIndex = targetIndex; + this.orientation = orientation; + } + + @Override public WindowManager.SiblingState.Orientation getOrientation() { + return orientation; + } + + @Override public int getTargetIndex() { + return targetIndex; + } + + @Override public List getWeights() { + return new ArrayList(weights); + } + } } diff --git a/openide.windows/src/org/openide/windows/DummyWindowManager.java b/openide.windows/src/org/openide/windows/DummyWindowManager.java --- a/openide.windows/src/org/openide/windows/DummyWindowManager.java +++ b/openide.windows/src/org/openide/windows/DummyWindowManager.java @@ -455,6 +455,24 @@ return "editor".equals(mode.getName()); } + @Override + public void addModeAround(Mode mode, String side, TopComponent tc) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void addModeOnSide(Mode mode, String side, TopComponent tc) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean adjustSizes(Mode mode, WeightCalculator wc) + { + throw new UnsupportedOperationException("Not supported yet."); + } + private final class W implements Workspace { private static final long serialVersionUID = 1L; private final String name; diff --git a/openide.windows/src/org/openide/windows/WindowManager.java b/openide.windows/src/org/openide/windows/WindowManager.java --- a/openide.windows/src/org/openide/windows/WindowManager.java +++ b/openide.windows/src/org/openide/windows/WindowManager.java @@ -710,4 +710,109 @@ */ public Set whereOpened(); } + ////////////////////////////////////////////////////////////////////// + // + // REVIEWERS: + // - For side, could have enum WindowManager.Side + // (then have Orientation in WindowManager instead of SiblingState + // + // - The WeightCalculator is removed from these addMode* API + // to simplify implementation. + // It can be put back and handled here, + // then performance optimized at a later date. + // + // - The original proposal returned the new mode, but that isn't + // a pattern I see around. Should it return a mode? + // + ////////////////////////////////////////////////////////////////////// + + /** + * Add a new Mode, with a TopComponent in it, on a side of the specified + * mode. Constants from JSplitPane are used to specify the side: + * TOP, BOTTOM, LEFT, RIGHT. + * + * @param mode the new mode is next to this mode + * @param side which side to attach the new mode. + * @param tc TopComponent to put into the new mode. + */ + abstract public void addModeOnSide(Mode mode, String side, TopComponent tc); + + /** + * Add a new Mode, with a TopComponent in it, that touches the side + * of the specified mode. The new mode is either wider or higher + * than the mode. + * Constants from JSplitPane are used to specify the side: + * TOP, BOTTOM, LEFT, RIGHT. + * When mode's container's orientation is the same as + * the specified side, this method does the same thing as addModeOnSide. + * + * @param mode + * @param side + * @param tc + */ + abstract public void addModeAround(Mode mode, String side, TopComponent tc); + + ////////////////////////////////////////////////////////////////////// + // + // REVIEWERS: + // The restriction that the specified mode's weight must + // be changed can be relaxed so that a modification to any + // weight will trigger a change. + // + // To do that is trivial if in + // ViewRequest(null, View.CHANGE_MODE_CONSTRAINTS_CHANGED, + // oldConstraints, newConstraints) + // it doesn't matter if oldContstraints == newConstraints. Or + // if oldConstraints can simply be set to null. + // If the type of ViewRequest requires accurate old/new then + // the restriction can still be relaxed by keeping track + // of the constraints for each of the modes. + // + ////////////////////////////////////////////////////////////////////// + + /** + * Change the sizing weights of a mode, and optionally its siblings, + * within a splitter. If the weight for the specified mode is not + * changed then no action takes place even if sibling weights are + * changed. + * @param mode + * @param wc provides new size informaiton + * @return true if the sizes changed + */ + abstract public boolean adjustSizes(Mode mode, WeightCalculator wc); + + /** + * Used with the adjustSizes method to provide new weights. + */ + public interface WeightCalculator { + /** + * Invoked by the window system to get the new weights. + * @param currentState splitter and sibling information + * @return new weights + */ + List getWeights(SiblingState currentState); + } + + /** + * Information about a splitter's children. + */ + public interface SiblingState { + enum Orientation { HORIZONTAL, VERTICAL; } + /** + * Splitter orientation. + * @return the splitter orientation + */ + Orientation getOrientation(); + /** + * @return the index of the mode to change + */ + int getTargetIndex(); + /** + * The current weights of the splitter's children, either top to bottom + * or left to right depending on orientation. The returned list + * can be modified. + * @return current weights + */ + List getWeights(); + } }