Implemented stacked button groups.

This commit is contained in:
2019-07-31 16:12:00 +02:00
parent 73342a0506
commit 614b4d8350
70 changed files with 1782 additions and 880 deletions
+2 -7
View File
@@ -3336,9 +3336,7 @@
}
_removeSelfFromScatterContainer() {
/**
Removes self from container when it's closed.
*/
// Removes self from container when it's closed.
if (this.container) {
this.container.remove(this);
}
@@ -3937,10 +3935,7 @@
* @memberof DOMScatterContainer
*/
remove(scatter) {
const element = scatter.element;
if (!this.scatter.has(element)) console.warn(`Try removing element that is not in the scatter.`, element);
this.scatter.delete(element);
this.scatter.delete(scatter.element);
}
/**
+104 -36
View File
@@ -2963,10 +2963,10 @@
* or a Theme object.
* @param {number} [opts.minWidth=44] - Button: The minimum width of one button.
* @param {number} [opts.minHeight=44] - Button: The minimum height of one button.
* @param {number} [opts.maxWidth] - The maximum width of the button group. Only used if stacked is true and the orientation is horizontal.
* @param {number} [opts.maxHeight] - The maximum height of the button group. Only used if stacked is true and the orientation is vertical.
* @param {boolean} [opts.stacked=false] - If set to true, the buttons of the button group gets stacked if they are broader or higher than the maximum permitted width or height, depending on orientation.
* @param {PIXI.Application} [opts.app] - The PixiJS Application. Must be set if you want to use the mousewheel to scroll your button group.
* @param {number} [opts.maxWidth] - The maximum width of the button group. If the buttons are wider than the maximum width, the buttons get stacked. Note: The buttons can only be stacked if margin is not zero.
* @param {number} [opts.maxHeight] - The maximum height of the button group. If the buttons are higher than the maximum height, the buttons get stacked. Note: The buttons can only be stacked if margin is not zero.
* @param {number} [opts.stackPadding=10] - The padding for stacked buttons.
* @param {PIXI.Application} [opts.app] - The PixiJS Application. Must be set if you want to use the mousewheel to scroll your button group. Only used when the buttons are stacked (with maxWidth or maxHeight).
* @param {number} [opts.padding=Theme.padding] - Button: The inner spacing (distance from icon and/or label) the the border.
* @param {number} [opts.margin=Theme.margin] - The outer spacing (distance from one button to the previous/next button).
* @param {string} [opts.iconPosition=left] - Button: The position of the icon in relation to the label. Can be left or right.
@@ -3017,7 +3017,7 @@
minHeight: 44,
maxWidth: null,
maxHeight: null,
stacked: false,
stackPadding: 10,
app: null,
padding: theme.padding,
margin: theme.margin,
@@ -3080,6 +3080,7 @@
// Buttons
//-----------------
let position = 0;
let index = 0;
for (let it of this.opts.buttons) {
delete it.x;
@@ -3158,6 +3159,9 @@
};
position += (this.opts.orientation === 'horizontal' ? button.width : button.height) + this.opts.margin;
button.__initIndex = index;
index++;
}
if (this.opts.orientation === 'vertical') {
@@ -3177,7 +3181,7 @@
// interaction
//--------------------
if (this.opts.stacked) {
if (this.opts.margin > 0 && (this.opts.maxWidth || this.opts.maxHeight)) {
this.interactive = true;
this.on('pointerdown', this.onStart.bind(this));
this.on('pointermove', this.onMove.bind(this));
@@ -3209,7 +3213,6 @@
this.addChildAt(background, 0);
this.__initWidth = this.container.width;
this.__deltaWidth = this.container.width - this.opts.maxWidth;
}
return this
@@ -3229,9 +3232,9 @@
//-----------------
this.draw();
// stacked
// stack
//-----------------
if (this.opts.stacked) {
if (this.opts.margin > 0 && (this.opts.maxWidth || this.opts.maxHeight)) {
this.stack();
}
@@ -3359,9 +3362,7 @@
this.container.position.y = event.data.global.y + this.__delta.y;
}
if (this.opts.stacked) {
this.stack();
}
this.stack();
}
}
@@ -3436,9 +3437,7 @@
}
}
if (this.opts.stacked) {
this.stack();
}
this.stack();
}
/**
@@ -3455,36 +3454,107 @@
*
*/
stack() {
if (this.opts.maxWidth) {
this._stackHorizontal();
} else if (this.opts.maxHeight) {
this._stackVertical();
}
}
/**
*
*/
_stackHorizontal() {
const sorted = [];
let reverseCounter = this.buttons.length - 1;
this.buttons.forEach((it, index) => {
if (it.__originalPosition.x + this.container.x < 0) {
const leftCorner = it.__originalPosition.x + this.container.x;
const rightCorner = it.__originalPosition.x + it.width;
const paddingLeft = index * this.opts.stackPadding;
const paddingRight = reverseCounter * this.opts.stackPadding;
if (leftCorner < paddingLeft) {
// left border
it.x = -this.container.x;
} else if (it.__originalPosition.x + it.width > Math.abs(this.container.x) + this.opts.maxWidth) {
it.x = -this.container.x + paddingLeft;
} else if (rightCorner > -this.container.x + this.opts.maxWidth - paddingRight) {
// right border
it.x = Math.abs(this.container.x) + this.opts.maxWidth - it.width;
it.x = -this.container.x + this.opts.maxWidth - it.width - paddingRight;
} else {
it.x = it.__originalPosition.x;
}
reverseCounter--;
sorted.push(it);
});
this.buttons.sort((a, b) => {
const delta = Math.abs(this.container.x) + this.opts.maxWidth / 2;
const distanceA = Math.abs(a.x - delta);
const distanceB = Math.abs(b.x - delta);
if (distanceA > distanceB) {
return -1
} else if (distanceB > distanceA) {
return 1
const min = Math.min(...sorted.map(it => it.x));
const max = Math.max(...sorted.map(it => it.x));
const center = (min + max) / 2;
// z-index
sorted
.sort((a, b) => {
const distanceA = Math.abs(a.x - center);
const distanceB = Math.abs(b.x - center);
if (distanceA < distanceB) {
return 1
} else if (distanceA > distanceB) {
return -1
} else {
return 0
}
})
.forEach(it => it.parent.addChild(it));
}
/**
*
*/
_stackVertical() {
const sorted = [];
let reverseCounter = this.buttons.length - 1;
this.buttons.forEach((it, index) => {
const topCorner = it.__originalPosition.y + this.container.y;
const bottomCorner = it.__originalPosition.y + it.height;
const paddingTop = index * this.opts.stackPadding;
const paddingBottom = reverseCounter * this.opts.stackPadding;
if (topCorner < paddingTop) {
// top border
it.y = -this.container.y + paddingTop;
} else if (bottomCorner > -this.container.y + this.opts.maxHeight - paddingBottom) {
// bottom border
it.y = -this.container.y + this.opts.maxHeight - it.height - paddingBottom;
} else {
return 0
it.y = it.__originalPosition.y;
}
reverseCounter--;
sorted.push(it);
});
this.buttons.forEach(it => {
const parent = it.parent;
parent.removeChild(it);
parent.addChild(it);
});
const min = Math.min(...sorted.map(it => it.y));
const max = Math.max(...sorted.map(it => it.y));
const center = (min + max) / 2;
// z-index
sorted
.sort((a, b) => {
const distanceA = Math.abs(a.y - center);
const distanceB = Math.abs(b.y - center);
if (distanceA < distanceB) {
return 1
} else if (distanceA > distanceB) {
return -1
} else {
return 0
}
})
.forEach(it => it.parent.addChild(it));
}
}
@@ -6782,9 +6852,7 @@
}
_removeSelfFromScatterContainer() {
/**
Removes self from container when it's closed.
*/
// Removes self from container when it's closed.
if (this.container) {
this.container.remove(this);
}