Menu

#87 Drop problems in multi-split container

open
None
5
2015-02-09
2010-10-15
No

Drop problems in multi-split container:
1/ Cannot drop content inside the content's node itself (e.g. top, left, bottom or righ side of the content leaf).
2/ Drop leaf does not always preserve its height or width after a drop.

Fix:
a/ MultiSplitDockableContainer.setConstraints(...)
// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
protected DockableLeaf _dockableLeaf;
protected DockableLeaf _aggregationLeaf;
public void setConstraints(Dockable dockable,
Component content,
Dockable aggregationOnDockable,
int aggregationIndexLocation,
AggregationPosition aggregationPosition) {
boolean old = this.storeLayout;

storeLayout = false;
// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
DockableLeaf oldDockableLeaf = _dockableLeaf;
DockableLeaf oldAggregationLeaf = _aggregationLeaf;
try {
// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
_dockableLeaf = dockable == null ? null : getLeaf(dockable);
_aggregationLeaf = aggregationOnDockable == null ? null : getLeaf(aggregationOnDockable);
if (_dockableLeaf != null && _dockableLeaf == _aggregationLeaf && _dockableLeaf.getDockables().size() == 1) {
return;
}
removeDockable(dockable);
addDockable(dockable, content, aggregationOnDockable, aggregationIndexLocation, aggregationPosition);
} finally {
storeLayout = old;
// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
_dockableLeaf = oldDockableLeaf;
_aggregationLeaf = oldAggregationLeaf;
}
}

b/ MultiSplitDockableContainer.validateModel(...)
protected void validateModel(Node root) {
if (root == null || !(root instanceof Split))
return;

List<Node> children = ((Split) root).getChildren();

double sum = 0.0;
for (Node node : children) {
if (!(node instanceof Divider)) {
sum += node.getWeight();
}

if (node instanceof Split) {
validateModel(node);
}

if (sum > 1.0d)
break;
}

if (sum != 1.0d) {
double w = 1.0 / ((children.size() / 2) + 1);

sum = 0;
for (int i = 0, size = children.size() - 1; i < size; i++) {
Node node = children.get(i);
// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
// node.resetBounds();
if (!(node instanceof Divider)) {
node.setWeight(w);
sum += w;
}
}

Node lastNode = children.get(children.size() - 1);
// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
// lastNode.resetBounds();
lastNode.setWeight(1.0d - sum);

multiSplitPane.getMultiSplitLayout().setFloatingDividers(true);
}
}

c/ MultiSplitDockableContainer.addDockable(...)
public void addDockable(Dockable dockable,
Component content,
Dockable aggregationOnDockable,
int aggregationIndexLocation,
AggregationPosition aggregationPosition) {
// Validate the model
if (!checkModel())
System.out.println("Check model fail. addDockable before");

if (entries.size() == 0) {
// Just one leaf
DockableLeaf leaf = new DockableLeaf(getNextLeanName(),
dockable.getId());
leaf.setWeight(1.0d);
multiSplitPaneModelRoot = leaf;

multiSplitPane.setModel(leaf);
multiSplitPane.add(getWrapperForComponent(dockable, content, Action.ADD_DOCK), "1");
setRootComponent(multiSplitPane);
SwingUtil.repaint(this);
} else {
boolean resetB = true;

byte[] oldModel = null;
if (dockable.equals(removedDockable)) {
oldModel = lastLayout;
removedDockable = null;
lastLayout = null;
}

boolean invalidAggregationPosition = false;
if (aggregationPosition == AggregationPosition.DEFAULT || aggregationPosition == null) {
invalidAggregationPosition = true;
aggregationPosition = defaultAggregationPosition;
}

if (multiSplitPaneModelRoot instanceof DockableLeaf) {
// The root is a leaf...
DockableLeaf rootLeaf = (DockableLeaf) multiSplitPaneModelRoot;

if (aggregationOnDockable != null && (aggregationPosition == null || invalidAggregationPosition)) {
// Aggregate to an already registered leaf
Component componentWrapper;

if (rootLeaf.getDockables().size() > 1) {
componentWrapper = multiSplitPane.getComponent(0);
} else {
Component rootLeafCmp = getComponentFromWrapper(multiSplitPane.getComponent(0));
multiSplitPane.removeAll();
componentWrapper = forceWrapperForComponent(entries.values().iterator().next().dockable, rootLeafCmp);
multiSplitPane.add(componentWrapper, rootLeaf.getName());
}

// The requeste is to add more than one dockable on the same leaf... no need to request a new leaf name
addToWrapper(componentWrapper, dockable, aggregationIndexLocation, content);

repaintMultiSplit(toolWindowManager.getClientProperty(MyDoggyKeySpace.PERSISTENCE_DELEGATE_PARSING) != null,
multiSplitPaneModelRoot);

rootLeaf.addDockable(dockable.getId());
} else {
// Create a new leaf...

DockableLeaf firstLeaf = rootLeaf;
DockableLeaf secondLeaf;

// Init two leafs
firstLeaf.setWeight(0.5);

secondLeaf = new DockableLeaf(getNextLeanName());
secondLeaf.setWeight(0.5);
// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
secondLeaf.setBounds(firstLeaf.getBounds());
secondLeaf.addDockable(dockable.getId());

List<Node> children = null;
switch (aggregationPosition) {
case LEFT:
case TOP:
children = Arrays.asList(secondLeaf,
new Divider(),
firstLeaf);
break;
case RIGHT:
case BOTTOM:
children = Arrays.asList(firstLeaf,
new Divider(),
secondLeaf);
break;
}

boolean rowLayout = (aggregationPosition == AggregationPosition.LEFT || aggregationPosition == AggregationPosition.RIGHT);

Split split = new Split();
split.setRowLayout(rowLayout);
split.setBounds(split.getBounds());
split.setChildren(children);

// update the model
multiSplitPaneModelRoot = split;

if (!multiSplitPane.getMultiSplitLayout().getFloatingDividers())
multiSplitPane.getMultiSplitLayout().setFloatingDividers(true);

validateModel(multiSplitPaneModelRoot);
multiSplitPane.setModel(multiSplitPaneModelRoot);

// update the components in the container
Component wrapper;
if (rootLeaf.getDockables().size() > 1) {
wrapper = multiSplitPane.getComponent(0);
} else {
Dockable delegator = entries.values().iterator().next().dockable;
wrapper = getWrapperForComponent(delegator, getComponentFromWrapper(multiSplitPane.getComponent(0)), Action.ADD_DOCK);
}
multiSplitPane.removeAll();

multiSplitPane.add(wrapper, firstLeaf.getName());
multiSplitPane.add(getWrapperForComponent(dockable, content, Action.ADD_DOCK), secondLeaf.getName());
}
} else {
// Take the root, it's a split
Split splitRoot = (Split) multiSplitPaneModelRoot;

// Build content to add
boolean addCmp = true;
String leafName = null;

// Modify model
if (aggregationOnDockable != null) {

// Search for aggregationOnDockable leaf
Stack<Split> stack = new Stack<Split>();
stack.push(splitRoot);

while (!stack.isEmpty()) {
Split split = stack.pop();

for (Node child : split.getChildren()) {
if (child instanceof DockableLeaf) {
DockableLeaf leaf = (DockableLeaf) child;

// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
// if (leaf.getDockables().contains(aggregationOnDockable.getId())) {
if (leaf == _aggregationLeaf || leaf.getDockables().contains(aggregationOnDockable.getId())) {
if (invalidAggregationPosition) {
// The requeste is to add more than one dockable on the same leaf...
addToWrapper(multiSplitPane.getMultiSplitLayout().getChildMap().get(leaf.getName()),
dockable,
aggregationIndexLocation,
content);

leaf.addDockable(dockable.getId());

addCmp = false;
resetB = false;
} else {
leafName = getNextLeanName();
boolean step1Failed = false;

// Check for concordance to leaf.getParent().isRowLayout and aggregationPosition
Split parent = leaf.getParent();
boolean rowLayout = parent.isRowLayout();

List<Node> parentChildren = parent.getChildren();
int startIndex = parentChildren.indexOf(leaf);
if (rowLayout) {
boolean finalize = false;
switch (aggregationPosition) {
case LEFT:
// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
DockableLeaf newLeafLeft = new DockableLeaf(leafName, dockable.getId());
newLeafLeft.setBounds(leaf.getBounds());
newLeafLeft.setWeight(leaf.getWeight());
parentChildren.add(startIndex, newLeafLeft);
parentChildren.add(startIndex + 1, new Divider());
finalize = true;
break;
case RIGHT:
// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
DockableLeaf newLeafRight = new DockableLeaf(leafName, dockable.getId());
newLeafRight.setBounds(leaf.getBounds());
newLeafRight.setWeight(leaf.getWeight());
parentChildren.add(startIndex + 1, new Divider());
parentChildren.add(startIndex + 2, newLeafRight);
finalize = true;
break;
default:
step1Failed = true;
}

if (finalize) {
// Set new children
forceWeight(parentChildren);
parent.setChildren(parentChildren);
}
} else {
boolean finalize = false;
switch (aggregationPosition) {
case TOP:
// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
DockableLeaf newLeafTop = new DockableLeaf(leafName, dockable.getId());
newLeafTop.setBounds(leaf.getBounds());
newLeafTop.setWeight(leaf.getWeight());
parentChildren.add(startIndex, newLeafTop);
parentChildren.add(startIndex + 1, new Divider());
finalize = true;
break;
case BOTTOM:
// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
DockableLeaf newLeafBottom = new DockableLeaf(leafName, dockable.getId());
newLeafBottom.setBounds(leaf.getBounds());
newLeafBottom.setWeight(leaf.getWeight());
parentChildren.add(startIndex + 1, new Divider());
parentChildren.add(startIndex + 2, newLeafBottom);
finalize = true;
break;
default:
step1Failed = true;
}

if (finalize) {
// Set new children
forceWeight(parentChildren);
parent.setChildren(parentChildren);
}
}

if (step1Failed) {
// Create two leafs

Leaf newleaf = new DockableLeaf(leafName, dockable.getId());
newleaf.setWeight(0.5);
// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
newleaf.setBounds(leaf.getBounds());
newleaf.setWeight(leaf.getWeight());

// Creat the split
Split newSplit = new Split();
newSplit.setBounds(leaf.getBounds());
newSplit.setRowLayout((aggregationPosition == AggregationPosition.LEFT || aggregationPosition == AggregationPosition.RIGHT));
newSplit.setWeight(leaf.getWeight());
leaf.getParent().removeNode(leaf);
switch (aggregationPosition) {
case LEFT:
case TOP:
newSplit.setChildren(Arrays.asList(newleaf,
new Divider(),
leaf));
break;
default:
newSplit.setChildren(Arrays.asList(leaf,
new Divider(),
newleaf));
break;
}

leaf.setWeight(0.5);

// Switch the leaf with the new split
parentChildren.set(startIndex, newSplit);
parent.setChildren(parentChildren);
}
}

stack.clear();
break;
}
} else if (child instanceof Split) {
stack.push((Split) child);
}
}
}

if (!multiSplitPane.getMultiSplitLayout().getFloatingDividers())
multiSplitPane.getMultiSplitLayout().setFloatingDividers(true);
} else {
leafName = getNextLeanName();
boolean rowLayout = (aggregationPosition == AggregationPosition.LEFT || aggregationPosition == AggregationPosition.RIGHT);

if (splitRoot.isRowLayout() == rowLayout) {
List<Node> children = splitRoot.getChildren();

switch (aggregationPosition) {
case LEFT:
case TOP:
children.add(0, new DockableLeaf(leafName, dockable.getId()));
children.add(1, new Divider());
break;
case RIGHT:
case BOTTOM:
children.add(new Divider());
children.add(new DockableLeaf(leafName, dockable.getId()));
break;
}

forceWeight(children);

splitRoot.setChildren(children);
} else {
Split newRoot = new Split();
newRoot.setRowLayout(rowLayout);
newRoot.setBounds(multiSplitPaneModelRoot.getBounds());

Leaf leaf = new DockableLeaf(leafName, dockable.getId());
leaf.setWeight(0.5);
multiSplitPaneModelRoot.setWeight(0.5);

List<Node> children = null;
switch (aggregationPosition) {
case LEFT:
case TOP:
children = Arrays.asList(leaf,
new Divider(),
multiSplitPaneModelRoot);
break;
case RIGHT:
case BOTTOM:
children = Arrays.asList(multiSplitPaneModelRoot,
new Divider(),
leaf);
break;
}
forceWeight(children);
newRoot.setChildren(children);

multiSplitPaneModelRoot = newRoot;
}

if (!multiSplitPane.getMultiSplitLayout().getFloatingDividers())
multiSplitPane.getMultiSplitLayout().setFloatingDividers(true);
}
// }

validateModel(multiSplitPaneModelRoot);
multiSplitPane.setModel(multiSplitPaneModelRoot);

if (addCmp)
multiSplitPane.add(getWrapperForComponent(dockable, content, Action.ADD_DOCK), leafName);
}

if (!checkModel())
System.out.println("Check model fail. addDockable end");

if (storeLayout && oldModel != null) {
// Decode stored model
final Node decodedModel = decode(oldModel);
// jumpResetBounds = true;
multiSplitPane.getMultiSplitLayout().setFloatingDividers(false);

SwingUtilities.invokeLater(new Runnable() {
public void run() {
setMultiSplitLayout(decodedModel);
}
});
} else {
if (resetB) {
// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
// Node split = getLeaf(dockable).getParent();
Node split = null;
DockableLeaf leaf = getLeaf(dockable);
if (leaf != null) {
split = leaf.getParent();
}
if (split == null)
split = multiSplitPaneModelRoot;

repaintMultiSplit(toolWindowManager.getClientProperty(MyDoggyKeySpace.PERSISTENCE_DELEGATE_PARSING) == null,
split);
} else {
repaintMultiSplit(false,
null);
}
}
}

entries.put(dockable, new DockableEntry(dockable, content));
}

d/ MultiSplitTabbedContentContainer.MultiSplitTabbedDockableDropPanel.drop(...), ca. line 319:
if (onIndex == -1) {
// PAMFOLIO-2482 mydoggy: fix drop problems in multi-split container (drop inside same leaf, preserve leaf height or width)
// rejectDrop = true;
} else {
Component onDockableContainer = getOnDockableContainer();

Thank you,
Pierre

Discussion

  • Angelo De Caro

    Angelo De Caro - 2010-10-30
    • assigned_to: nobody --> adecaro
     
  • Angelo De Caro

    Angelo De Caro - 2010-10-30

    Ciao Pierre,
    can you send me directly the file?

    Best,
    ./angelo

     
Auth0 Logo