mirror of
https://github.com/zen-browser/components.git
synced 2025-07-08 17:49:58 +02:00
Refactor: remove redundant height AND widthInParent from splitNode, fix weird splitTabs behaviour
This commit is contained in:
parent
cde3c6a48b
commit
694cbc9d89
1 changed files with 41 additions and 44 deletions
|
@ -1,13 +1,10 @@
|
||||||
class SplitNode {
|
class SplitLeafNode {
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
* @type
|
|
||||||
*/
|
|
||||||
widthInParent ;
|
|
||||||
/**
|
/**
|
||||||
|
* The percentage of the size of the parent the node takes up, dependent on parent direction this is either
|
||||||
|
* width or height.
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
heightInParent ;
|
sizeInParent;
|
||||||
/**
|
/**
|
||||||
* @type {Object}
|
* @type {Object}
|
||||||
*/
|
*/
|
||||||
|
@ -16,16 +13,31 @@ class SplitNode {
|
||||||
* @type {SplitNode}
|
* @type {SplitNode}
|
||||||
*/
|
*/
|
||||||
parent;
|
parent;
|
||||||
|
constructor(tab, sizeInParent) {
|
||||||
|
this.tab = tab;
|
||||||
|
this.sizeInParent = sizeInParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
get heightInParent() {
|
||||||
|
return this.parent.direction === 'column' ? this.sizeInParent : 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
get widthInParent() {
|
||||||
|
return this.parent.direction === 'row' ? this.sizeInParent : 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SplitNode extends SplitLeafNode {
|
||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
direction;
|
direction;
|
||||||
|
_children = [];
|
||||||
|
|
||||||
constructor(direction, widthInParent = 100, heightInParent = 100) {
|
constructor(direction, sizeInParent) {
|
||||||
this.widthInParent = widthInParent;
|
super(null, sizeInParent);
|
||||||
this.heightInParent = heightInParent;
|
this.sizeInParent = sizeInParent;
|
||||||
this.direction = direction; // row or column
|
this.direction = direction; // row or column
|
||||||
this._children = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set children(children) {
|
set children(children) {
|
||||||
|
@ -42,13 +54,6 @@ class SplitNode {
|
||||||
this._children.push(child);
|
this._children.push(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class SplitLeafNode {
|
|
||||||
constructor(tab, widthInParent = 100, heightInParent = 100) {
|
|
||||||
this.tab = tab;
|
|
||||||
this.widthInParent = widthInParent;
|
|
||||||
this.heightInParent = heightInParent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ZenViewSplitter extends ZenDOMOperatedFeature {
|
class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||||
currentView = -1;
|
currentView = -1;
|
||||||
|
@ -143,16 +148,14 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||||
parent.children.splice(childIndex, 1);
|
parent.children.splice(childIndex, 1);
|
||||||
if (parent.children.length !== 1) {
|
if (parent.children.length !== 1) {
|
||||||
const nodeToResize = parent.children[Math.max(0, childIndex - 1)];
|
const nodeToResize = parent.children[Math.max(0, childIndex - 1)];
|
||||||
if (parent.direction === 'column') nodeToResize.heightInParent += toRemove.heightInParent;
|
nodeToResize.sizeInParent += toRemove.sizeInParent;
|
||||||
else nodeToResize.widthInParent += toRemove.widthInParent;
|
|
||||||
this.applyGridLayout(parent);
|
this.applyGridLayout(parent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// node that is not a leaf cannot have less than 2 children, this makes for better resizing
|
// node that is not a leaf cannot have less than 2 children, this makes for better resizing
|
||||||
// node takes place of parent
|
// node takes place of parent
|
||||||
const leftOverChild = parent.children[0];
|
const leftOverChild = parent.children[0];
|
||||||
leftOverChild.widthInParent = parent.widthInParent;
|
leftOverChild.sizeInParent = parent.sizeInParent;
|
||||||
leftOverChild.heightInParent = parent.heightInParent;
|
|
||||||
if (parent.parent) {
|
if (parent.parent) {
|
||||||
leftOverChild.parent = parent.parent;
|
leftOverChild.parent = parent.parent;
|
||||||
parent.parent.children[parent.parent.children.indexOf(parent)] = leftOverChild;
|
parent.parent.children[parent.parent.children.indexOf(parent)] = leftOverChild;
|
||||||
|
@ -510,7 +513,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||||
* @param {Tab[]} tabs - The tabs to split.
|
* @param {Tab[]} tabs - The tabs to split.
|
||||||
* @param {string} gridType - The type of grid layout.
|
* @param {string} gridType - The type of grid layout.
|
||||||
*/
|
*/
|
||||||
splitTabs(tabs, gridType = 'grid') {
|
splitTabs(tabs, gridType) {
|
||||||
if (tabs.length < 2) {
|
if (tabs.length < 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -519,7 +522,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||||
if (existingSplitTab) {
|
if (existingSplitTab) {
|
||||||
const groupIndex = this._data.findIndex((group) => group.tabs.includes(existingSplitTab));
|
const groupIndex = this._data.findIndex((group) => group.tabs.includes(existingSplitTab));
|
||||||
const group = this._data[groupIndex];
|
const group = this._data[groupIndex];
|
||||||
if (group.gridType !== gridType || tabs.length !== tabs.length) {
|
if (gridType && (group.gridType !== gridType)) {
|
||||||
// reset layout
|
// reset layout
|
||||||
group.gridType = gridType;
|
group.gridType = gridType;
|
||||||
group.layoutTree = this.calculateLayoutTree([...new Set(group.tabs.concat(tabs))], gridType);
|
group.layoutTree = this.calculateLayoutTree([...new Set(group.tabs.concat(tabs))], gridType);
|
||||||
|
@ -535,6 +538,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||||
this.activateSplitView(group, true);
|
this.activateSplitView(group, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
gridType ??= 'grid';
|
||||||
|
|
||||||
const splitData = {
|
const splitData = {
|
||||||
tabs,
|
tabs,
|
||||||
|
@ -547,15 +551,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||||
}
|
}
|
||||||
|
|
||||||
addTabToSplit(tab, splitNode) {
|
addTabToSplit(tab, splitNode) {
|
||||||
if (splitNode.direction === 'row') {
|
const reduce = splitNode.children.length / (splitNode.children.length + 1);
|
||||||
const reduce = splitNode.children.length / (splitNode.children.length + 1);
|
splitNode.children.forEach(c => c.sizeInParent *= reduce);
|
||||||
splitNode.children.forEach(c => c.widthInParent *= reduce);
|
splitNode.addChild(new SplitLeafNode(tab, (1 - reduce) * 100));
|
||||||
splitNode.addChild(new SplitLeafNode(tab, (1 - reduce) * 100, 100));
|
|
||||||
} else if (splitNode.direction === 'column') {
|
|
||||||
const reduce = splitNode.children.length / (splitNode.children.length + 1);
|
|
||||||
splitNode.children.forEach(c => c.heightInParent *= reduce);
|
|
||||||
splitNode.addChild(new SplitLeafNode(tab, (1 - reduce) * 100, 100));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -620,20 +618,20 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||||
let rootNode;
|
let rootNode;
|
||||||
if (gridType === 'vsep' || (tabs.length === 2 && gridType === 'grid')) {
|
if (gridType === 'vsep' || (tabs.length === 2 && gridType === 'grid')) {
|
||||||
rootNode = new SplitNode('row');
|
rootNode = new SplitNode('row');
|
||||||
rootNode.children = tabs.map(tab => new SplitLeafNode(tab, 100 / tabs.length, 100));
|
rootNode.children = tabs.map(tab => new SplitLeafNode(tab, 100 / tabs.length));
|
||||||
} else if (gridType === 'hsep') {
|
} else if (gridType === 'hsep') {
|
||||||
rootNode = new SplitNode('column');
|
rootNode = new SplitNode('column');
|
||||||
rootNode.children = tabs.map(tab => new SplitLeafNode(tab, 100, 100 / tabs.length));
|
rootNode.children = tabs.map(tab => new SplitLeafNode(tab, 100 / tabs.length));
|
||||||
} else if (gridType === 'grid') {
|
} else if (gridType === 'grid') {
|
||||||
rootNode = new SplitNode('row');
|
rootNode = new SplitNode('row');
|
||||||
const rowWidth = 100 / Math.ceil(tabs.length / 2);
|
const rowWidth = 100 / Math.ceil(tabs.length / 2);
|
||||||
for (let i = 0; i < tabs.length - 1; i += 2) {
|
for (let i = 0; i < tabs.length - 1; i += 2) {
|
||||||
const columnNode = new SplitNode('column', rowWidth, 100);
|
const columnNode = new SplitNode('column', rowWidth, 100);
|
||||||
columnNode.children = [new SplitLeafNode(tabs[i], 100, 50), new SplitLeafNode(tabs[i + 1], 100, 50)];
|
columnNode.children = [new SplitLeafNode(tabs[i], 50), new SplitLeafNode(tabs[i + 1], 50)];
|
||||||
rootNode.addChild(columnNode);
|
rootNode.addChild(columnNode);
|
||||||
}
|
}
|
||||||
if (tabs.length % 2 !== 0) {
|
if (tabs.length % 2 !== 0) {
|
||||||
rootNode.addChild(new SplitLeafNode(tabs[tabs.length - 1], rowWidth, 100));
|
rootNode.addChild(new SplitLeafNode(tabs[tabs.length - 1], rowWidth));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -685,9 +683,9 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||||
this.applyGridLayout(childNode);
|
this.applyGridLayout(childNode);
|
||||||
|
|
||||||
if (splitNode.direction === 'column') {
|
if (splitNode.direction === 'column') {
|
||||||
topOffset += childNode.heightInParent * rootToNodeHeightRatio;
|
topOffset += childNode.sizeInParent * rootToNodeHeightRatio;
|
||||||
} else {
|
} else {
|
||||||
leftOffset += childNode.widthInParent * rootToNodeWidthRatio;
|
leftOffset += childNode.sizeInParent * rootToNodeWidthRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < splittersNeeded) {
|
if (i < splittersNeeded) {
|
||||||
|
@ -783,7 +781,6 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||||
this.tabBrowserPanel.setAttribute('zen-split-resizing', true);
|
this.tabBrowserPanel.setAttribute('zen-split-resizing', true);
|
||||||
const isVertical = event.target.getAttribute('orient') === 'vertical';
|
const isVertical = event.target.getAttribute('orient') === 'vertical';
|
||||||
const dimension = isVertical ? 'width' : 'height';
|
const dimension = isVertical ? 'width' : 'height';
|
||||||
const dimensionInParent = dimension + 'InParent';
|
|
||||||
const clientAxis = isVertical ? 'screenX' : 'screenY';
|
const clientAxis = isVertical ? 'screenX' : 'screenY';
|
||||||
|
|
||||||
const gridIdx = parseInt(event.target.getAttribute('gridIdx'));
|
const gridIdx = parseInt(event.target.getAttribute('gridIdx'));
|
||||||
|
@ -792,11 +789,11 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||||
let rootToNodeSize;
|
let rootToNodeSize;
|
||||||
if (isVertical) rootToNodeSize = 100 / (100 - splitNode.positionToRoot.right - splitNode.positionToRoot.left);
|
if (isVertical) rootToNodeSize = 100 / (100 - splitNode.positionToRoot.right - splitNode.positionToRoot.left);
|
||||||
else rootToNodeSize = 100 / (100 - splitNode.positionToRoot.bottom - splitNode.positionToRoot.top);
|
else rootToNodeSize = 100 / (100 - splitNode.positionToRoot.bottom - splitNode.positionToRoot.top);
|
||||||
const originalSizes = splitNode.children.map(c => c[dimensionInParent]);
|
const originalSizes = splitNode.children.map(c => c.sizeInParent);
|
||||||
|
|
||||||
const dragFunc = (dEvent) => {
|
const dragFunc = (dEvent) => {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
originalSizes.forEach((s, i) => splitNode.children[i][dimensionInParent] = s); // reset changes
|
originalSizes.forEach((s, i) => splitNode.children[i].sizeInParent = s); // reset changes
|
||||||
|
|
||||||
const movement = dEvent[clientAxis] - startPosition;
|
const movement = dEvent[clientAxis] - startPosition;
|
||||||
let movementPercent = (movement / this.tabBrowserPanel.getBoundingClientRect()[dimension] * rootToNodeSize) * 100;
|
let movementPercent = (movement / this.tabBrowserPanel.getBoundingClientRect()[dimension] * rootToNodeSize) * 100;
|
||||||
|
@ -805,14 +802,14 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
||||||
for (let i = gridIdx + (movementPercent < 0 ? 0 : 1); 0 <= i && i < originalSizes.length; i += movementPercent < 0 ? -1 : 1) {
|
for (let i = gridIdx + (movementPercent < 0 ? 0 : 1); 0 <= i && i < originalSizes.length; i += movementPercent < 0 ? -1 : 1) {
|
||||||
const current = originalSizes[i];
|
const current = originalSizes[i];
|
||||||
const newSize = Math.max(this.minResizeWidth, current - reducingMovement);
|
const newSize = Math.max(this.minResizeWidth, current - reducingMovement);
|
||||||
splitNode.children[i][dimensionInParent] = newSize;
|
splitNode.children[i].sizeInParent = newSize;
|
||||||
const amountReduced = current - newSize;
|
const amountReduced = current - newSize;
|
||||||
reducingMovement -= amountReduced;
|
reducingMovement -= amountReduced;
|
||||||
if (reducingMovement <= 0) break;
|
if (reducingMovement <= 0) break;
|
||||||
}
|
}
|
||||||
const increasingMovement = Math.max(movementPercent, - movementPercent) - reducingMovement;
|
const increasingMovement = Math.max(movementPercent, - movementPercent) - reducingMovement;
|
||||||
const increaseIndex = gridIdx + (movementPercent < 0 ? 1 : 0);
|
const increaseIndex = gridIdx + (movementPercent < 0 ? 1 : 0);
|
||||||
splitNode.children[increaseIndex][dimensionInParent] = originalSizes[increaseIndex] + increasingMovement;
|
splitNode.children[increaseIndex].sizeInParent = originalSizes[increaseIndex] + increasingMovement;
|
||||||
this.applyGridLayout(splitNode);
|
this.applyGridLayout(splitNode);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue