mirror of
https://github.com/zen-browser/components.git
synced 2025-07-08 05:29:58 +02:00
Reimplement splitview resize for treelayout splitview.
This commit is contained in:
parent
a102dd4c37
commit
28baa2f9d4
1 changed files with 45 additions and 51 deletions
|
@ -6,6 +6,7 @@ class SplitNode {
|
||||||
this.splitters = [];
|
this.splitters = [];
|
||||||
this.widthInParent = widthInParent;
|
this.widthInParent = widthInParent;
|
||||||
this.heightInParent = heightInParent;
|
this.heightInParent = heightInParent;
|
||||||
|
this.positionToRoot = null; // position relative to root node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class SplitLeafNode {
|
class SplitLeafNode {
|
||||||
|
@ -33,6 +34,13 @@ var gZenViewSplitter = new class {
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyPreferenceGetter(
|
||||||
|
this,
|
||||||
|
'minResizeWidth',
|
||||||
|
'zen.splitView.min-resize-width',
|
||||||
|
7
|
||||||
|
);
|
||||||
|
|
||||||
ChromeUtils.defineLazyGetter(
|
ChromeUtils.defineLazyGetter(
|
||||||
this,
|
this,
|
||||||
'splitterBox',
|
'splitterBox',
|
||||||
|
@ -338,10 +346,6 @@ var gZenViewSplitter = new class {
|
||||||
return this._tabBrowserPanel;
|
return this._tabBrowserPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
get minResizeWidth() {
|
|
||||||
return Services.prefs.getIntPref('zen.splitView.min-resize-width');
|
|
||||||
}
|
|
||||||
|
|
||||||
get splitViewActive() {
|
get splitViewActive() {
|
||||||
return this.currentView >= 0;
|
return this.currentView >= 0;
|
||||||
}
|
}
|
||||||
|
@ -541,9 +545,12 @@ var gZenViewSplitter = new class {
|
||||||
* Apply grid layout to tabBrowserPanel
|
* Apply grid layout to tabBrowserPanel
|
||||||
*
|
*
|
||||||
* @param {SplitNode} splitNode SplitNode
|
* @param {SplitNode} splitNode SplitNode
|
||||||
* @param {{top, bottom, left, right}} nodeRootPosition position of node relative to root of split
|
|
||||||
*/
|
*/
|
||||||
applyGridLayout(splitNode, nodeRootPosition = {top: 0, bottom: 0, left: 0, right: 0}) {
|
applyGridLayout(splitNode) {
|
||||||
|
if (!splitNode.positionToRoot) {
|
||||||
|
splitNode.positionToRoot = {top: 0, bottom: 0, left: 0, right: 0};
|
||||||
|
}
|
||||||
|
const nodeRootPosition = splitNode.positionToRoot;
|
||||||
if (!splitNode.children) {
|
if (!splitNode.children) {
|
||||||
const browserContainer = document.getElementById(splitNode.id);
|
const browserContainer = document.getElementById(splitNode.id);
|
||||||
browserContainer.style.inset = `${nodeRootPosition.top}% ${nodeRootPosition.right}% ${nodeRootPosition.bottom}% ${nodeRootPosition.left}%`;
|
browserContainer.style.inset = `${nodeRootPosition.top}% ${nodeRootPosition.right}% ${nodeRootPosition.bottom}% ${nodeRootPosition.left}%`;
|
||||||
|
@ -559,7 +566,8 @@ var gZenViewSplitter = new class {
|
||||||
let topOffset = nodeRootPosition.top;
|
let topOffset = nodeRootPosition.top;
|
||||||
splitNode.children.forEach((childNode, i) => {
|
splitNode.children.forEach((childNode, i) => {
|
||||||
const childRootPosition = {top: topOffset, right: 100 - (leftOffset + childNode.widthInParent * rootToNodeWidthRatio), bottom: 100 - (topOffset + childNode.heightInParent * rootToNodeHeightRatio), left: leftOffset};
|
const childRootPosition = {top: topOffset, right: 100 - (leftOffset + childNode.widthInParent * rootToNodeWidthRatio), bottom: 100 - (topOffset + childNode.heightInParent * rootToNodeHeightRatio), left: leftOffset};
|
||||||
this.applyGridLayout(childNode, childRootPosition);
|
childNode.positionToRoot = childRootPosition;
|
||||||
|
this.applyGridLayout(childNode);
|
||||||
|
|
||||||
if (splitNode.direction === 'column') {
|
if (splitNode.direction === 'column') {
|
||||||
topOffset += childNode.heightInParent * rootToNodeHeightRatio;
|
topOffset += childNode.heightInParent * rootToNodeHeightRatio;
|
||||||
|
@ -572,7 +580,7 @@ var gZenViewSplitter = new class {
|
||||||
if (!isLastNode) {
|
if (!isLastNode) {
|
||||||
let splitter = currentSplitters?.[i];
|
let splitter = currentSplitters?.[i];
|
||||||
if (!splitter) {
|
if (!splitter) {
|
||||||
splitter = this.createSplitter(splitNode.direction === 'column' ? 'horizontal' : 'vertical', childNode, i);
|
splitter = this.createSplitter(splitNode.direction === 'column' ? 'horizontal' : 'vertical', splitNode, i);
|
||||||
}
|
}
|
||||||
if (splitNode.direction === 'column') {
|
if (splitNode.direction === 'column') {
|
||||||
splitter.style.inset = `${100 - childRootPosition.bottom}% ${childRootPosition.right}% 0% ${childRootPosition.left}%`;
|
splitter.style.inset = `${100 - childRootPosition.bottom}% ${childRootPosition.right}% 0% ${childRootPosition.left}%`;
|
||||||
|
@ -610,9 +618,10 @@ var gZenViewSplitter = new class {
|
||||||
}
|
}
|
||||||
|
|
||||||
removeSplitters() {
|
removeSplitters() {
|
||||||
[...gZenViewSplitter.tabBrowserPanel.children]
|
Array.from(this._splitNodeToSplitters.values()).forEach(s => {
|
||||||
.filter(e => e.classList.contains('zen-split-view-splitter'))
|
s.remove;
|
||||||
.forEach(s => s.remove());
|
});
|
||||||
|
this._splitNodeToSplitters.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -649,36 +658,38 @@ var gZenViewSplitter = new class {
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSplitterMouseDown = (event) => {
|
handleSplitterMouseDown = (event) => {
|
||||||
const splitData = this._data[this.currentView];
|
|
||||||
|
|
||||||
const isVertical = event.target.getAttribute('orient') === 'vertical';
|
const isVertical = event.target.getAttribute('orient') === 'vertical';
|
||||||
const dimension = isVertical ? 'widths' : 'heights';
|
const dimension = isVertical ? 'width' : 'height';
|
||||||
|
const dimensionInParent = dimension + 'InParent';
|
||||||
const clientAxis = isVertical ? 'screenX' : 'screenY';
|
const clientAxis = isVertical ? 'screenX' : 'screenY';
|
||||||
|
|
||||||
const gridIdx = event.target.getAttribute('gridIdx');
|
const gridIdx = parseInt(event.target.getAttribute('gridIdx'));
|
||||||
let prevPosition = event[clientAxis];
|
const startPosition = event[clientAxis];
|
||||||
|
const splitNode = event.target.parentSplitNode;
|
||||||
|
let rootToNodeSize;
|
||||||
|
if (isVertical) rootToNodeSize = 100 / (100 - splitNode.positionToRoot.right - splitNode.positionToRoot.left);
|
||||||
|
else rootToNodeSize = 100 / (100 - splitNode.positionToRoot.bottom - splitNode.positionToRoot.top);
|
||||||
|
const originalSizes = splitNode.children.map(c => c[dimensionInParent]);
|
||||||
|
|
||||||
const dragFunc = (dEvent) => {
|
const dragFunc = (dEvent) => {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
const movementX = dEvent[clientAxis] - prevPosition;
|
|
||||||
let percentageChange = (movementX / this.tabBrowserPanel.getBoundingClientRect()[isVertical ? 'width' : 'height']) * 100;
|
|
||||||
|
|
||||||
const currentSize = splitData[dimension][gridIdx - 1];
|
const movement = dEvent[clientAxis] - startPosition;
|
||||||
const neighborSize = splitData[dimension][gridIdx];
|
let movementPercent = (movement / this.tabBrowserPanel.getBoundingClientRect()[dimension] * rootToNodeSize) * 100;
|
||||||
if (currentSize < this.minResizeWidth && neighborSize < this.minResizeWidth) {
|
|
||||||
return;
|
let reducingMovement = Math.max(movementPercent, -movementPercent);
|
||||||
|
for (let i = gridIdx + (movementPercent < 0 ? 0 : 1); 0 <= i && i < originalSizes.length; i += movementPercent < 0 ? -1 : 1) {
|
||||||
|
const current = originalSizes[i];
|
||||||
|
const newSize = Math.max(this.minResizeWidth, current - reducingMovement);
|
||||||
|
splitNode.children[i][dimensionInParent] = newSize;
|
||||||
|
const amountReduced = current - newSize;
|
||||||
|
reducingMovement -= amountReduced;
|
||||||
|
if (reducingMovement <= 0) break;
|
||||||
}
|
}
|
||||||
let max = false;
|
const increasingMovement = Math.max(movementPercent, - movementPercent) - reducingMovement;
|
||||||
if (currentSize + percentageChange < this.minResizeWidth) {
|
const increaseIndex = gridIdx + (movementPercent < 0 ? 1 : 0);
|
||||||
percentageChange = this.minResizeWidth - currentSize;
|
splitNode.children[increaseIndex][dimensionInParent] = originalSizes[increaseIndex] + increasingMovement;
|
||||||
max = true;
|
this.applyGridLayout(splitNode);
|
||||||
} else if (neighborSize - percentageChange < this.minResizeWidth) {
|
|
||||||
percentageChange = neighborSize - this.minResizeWidth;
|
|
||||||
max = true;
|
|
||||||
}
|
|
||||||
splitData[dimension][gridIdx - 1] += percentageChange;
|
|
||||||
splitData[dimension][gridIdx] -= percentageChange;
|
|
||||||
this.applyGridSizes();
|
|
||||||
if (!max) prevPosition = dEvent[clientAxis];
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const stopListeners = () => {
|
const stopListeners = () => {
|
||||||
|
@ -691,23 +702,6 @@ var gZenViewSplitter = new class {
|
||||||
setCursor(isVertical ? 'ew-resize' : 'n-resize');
|
setCursor(isVertical ? 'ew-resize' : 'n-resize');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies the grid column and row sizes
|
|
||||||
*/
|
|
||||||
applyGridSizes() {
|
|
||||||
const splitData = this._data[this.currentView];
|
|
||||||
const columnGap = 'var(--zen-split-column-gap)';
|
|
||||||
const rowGap = 'var(--zen-split-row-gap)';
|
|
||||||
|
|
||||||
this.tabBrowserPanel.style.gridTemplateColumns = splitData.widths.slice(0, -1).map(
|
|
||||||
(w) => `calc(${w}% - ${columnGap} * ${splitData.widths.length - 1}/${splitData.widths.length}) ${columnGap}`
|
|
||||||
).join(' ');
|
|
||||||
|
|
||||||
this.tabBrowserPanel.style.gridTemplateRows = splitData.heights.slice(0, -1).map(
|
|
||||||
(h) => `calc(${h}% - ${rowGap} * ${splitData.heights.length - 1}/${splitData.heights.length}) ${rowGap}`
|
|
||||||
).join(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the docshell state for the tabs.
|
* Sets the docshell state for the tabs.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue