Slider hover fix, added vector spinbox for future

This commit is contained in:
Lucas Dower 2022-03-04 21:56:12 +00:00
parent b66a489af2
commit 3f988c0654
7 changed files with 352 additions and 30 deletions

View File

@ -98,6 +98,8 @@ export class AppContext {
this._ui = new UI(this);
this._ui.build();
this._ui.registerEvents();
// this._ui.disablePost(Action.Import);
this._ui.disable(Action.Simplify);
}

View File

@ -1,11 +1,11 @@
import { ASSERT } from '../../util';
import { ASSERT, getRandomID } from '../../util';
export class LabelElement {
private _id: string;
private _text: string;
constructor(id: string, text: string) {
this._id = id;
constructor(text: string) {
this._id = getRandomID();
this._text = text;
}

View File

@ -6,7 +6,7 @@ export abstract class LabelledElement<Type> extends BaseUIElement<Type> {
public constructor(label: string) {
super(label);
this._labelElement = new LabelElement(label, label);
this._labelElement = new LabelElement(label);
}
public generateHTML() {

View File

@ -34,8 +34,21 @@ export class SliderElement extends LabelledElement<number> {
public registerEvents() {
const element = document.getElementById(this._id) as HTMLDivElement;
const elementBar = document.getElementById(this._id + '-bar') as HTMLDivElement;
ASSERT(element !== null);
element.onmouseenter = () => {
if (this._isEnabled) {
element.classList.add('new-slider-hover');
elementBar.classList.add('new-slider-bar-hover');
}
};
element.onmouseleave = () => {
element.classList.remove('new-slider-hover');
elementBar.classList.remove('new-slider-bar-hover');
};
element.onmousedown = () => {
this._dragging = true;
};

View File

@ -0,0 +1,199 @@
import { ASSERT, LOG } from '../../util';
import { LabelledElement } from './labelled_element';
import { Vector3 } from '../../vector';
/* eslint-disable */
enum EAxis {
None = 'none',
X = 'x',
Y = 'y',
Z = 'z',
};
/* eslint-enable */
export class VectorSpinboxElement extends LabelledElement<Vector3> {
private _mouseover: EAxis;
private _dragging: EAxis;
private _lastClientX: number;
public constructor(label: string, decimals: number, value: Vector3) {
super(label);
this._value = value;
this._mouseover = EAxis.None;
this._dragging = EAxis.None;
this._lastClientX = 0.0;
}
public generateInnerHTML() {
ASSERT(this._value, 'Value not found');
return `
<div style="display: flex; flex-direction: row;">
<div style="display: flex; flex-direction: row; width: 33%">
<div class="spinbox-key" id="${this._id}-kx" style="background-color: #FF4C4C;">X</div>
<div class="spinbox-value" id="${this._id}-vx">
${this._value.x}
</div>
</div>
<div class="invis-divider"></div>
<div style="display: flex; flex-direction: row; width: 33%"">
<div class="spinbox-key" id="${this._id}-ky" style="background-color: #34BF49;">Y</div>
<div class="spinbox-value" id="${this._id}-vy">
${this._value.y}
</div>
</div>
<div class="invis-divider"></div>
<div style="display: flex; flex-direction: row; width: 33%"">
<div class="spinbox-key" id="${this._id}-kz" style="background-color: #0099E5;">Z</div>
<div class="spinbox-value" id="${this._id}-vz">
${this._value.z}
</div>
</div>
</div>
`;
}
private _registerAxis(axis: EAxis) {
ASSERT(axis !== EAxis.None);
const elementXK = document.getElementById(this._id + '-k' + axis) as HTMLDivElement;
const elementXV = document.getElementById(this._id + '-v' + axis) as HTMLDivElement;
ASSERT(elementXK !== null && elementXV !== null);
elementXK.onmouseenter = () => {
this._mouseover = axis;
if (this._isEnabled) {
elementXK.classList.add('spinbox-key-hover');
elementXV.classList.add('spinbox-value-hover');
}
};
elementXV.onmouseenter = () => {
this._mouseover = axis;
if (this._isEnabled) {
elementXK.classList.add('spinbox-key-hover');
elementXV.classList.add('spinbox-value-hover');
}
};
elementXK.onmouseleave = () => {
this._mouseover = EAxis.None;
if (this._dragging !== axis) {
elementXK.classList.remove('spinbox-key-hover');
elementXV.classList.remove('spinbox-value-hover');
}
};
elementXV.onmouseleave = () => {
this._mouseover = EAxis.None;
if (this._dragging !== axis) {
elementXK.classList.remove('spinbox-key-hover');
elementXV.classList.remove('spinbox-value-hover');
}
};
}
public registerEvents() {
this._registerAxis(EAxis.X);
this._registerAxis(EAxis.Y);
this._registerAxis(EAxis.Z);
document.addEventListener('mousedown', (e: any) => {
if (this._isEnabled && this._mouseover !== EAxis.None) {
this._dragging = this._mouseover;
this._lastClientX = e.clientX;
}
});
document.addEventListener('mousemove', (e: any) => {
if (this._isEnabled && this._dragging !== EAxis.None) {
this._updateValue(e);
}
});
document.addEventListener('mouseup', () => {
const elementXK = document.getElementById(this._id + '-kx') as HTMLDivElement;
const elementYK = document.getElementById(this._id + '-ky') as HTMLDivElement;
const elementZK = document.getElementById(this._id + '-kz') as HTMLDivElement;
const elementXV = document.getElementById(this._id + '-vx') as HTMLDivElement;
const elementYV = document.getElementById(this._id + '-vy') as HTMLDivElement;
const elementZV = document.getElementById(this._id + '-vz') as HTMLDivElement;
switch (this._dragging) {
case EAxis.X:
elementXK.classList.remove('spinbox-key-hover');
elementXV.classList.remove('spinbox-value-hover');
break;
case EAxis.Y:
elementYK.classList.remove('spinbox-key-hover');
elementYV.classList.remove('spinbox-value-hover');
break;
case EAxis.Z:
elementZK.classList.remove('spinbox-key-hover');
elementZV.classList.remove('spinbox-value-hover');
break;
}
this._dragging = EAxis.None;
});
}
private _updateValue(e: MouseEvent) {
ASSERT(this._isEnabled, 'Not enabled');
ASSERT(this._dragging !== EAxis.None, 'Dragging nothing');
ASSERT(this._value, 'No value to update');
const deltaX = e.clientX - this._lastClientX;
this._lastClientX = e.clientX;
switch (this._dragging) {
case EAxis.X:
this._value.x += deltaX;
break;
case EAxis.Y:
this._value.y += deltaX;
break;
case EAxis.Z:
this._value.z += deltaX;
break;
}
const elementXV = document.getElementById(this._id + '-vx') as HTMLDivElement;
const elementYV = document.getElementById(this._id + '-vy') as HTMLDivElement;
const elementZV = document.getElementById(this._id + '-vz') as HTMLDivElement;
elementXV.innerHTML = this._value.x.toString();
elementYV.innerHTML = this._value.y.toString();
elementZV.innerHTML = this._value.z.toString();
}
protected _onEnabledChanged() {
super._onEnabledChanged();
LOG(this._label, 'is now enabled', this._isEnabled);
const keyElements = [
document.getElementById(this._id + '-kx') as HTMLDivElement,
document.getElementById(this._id + '-ky') as HTMLDivElement,
document.getElementById(this._id + '-kz') as HTMLDivElement,
];
const valueElements = [
document.getElementById(this._id + '-vx') as HTMLDivElement,
document.getElementById(this._id + '-vy') as HTMLDivElement,
document.getElementById(this._id + '-vz') as HTMLDivElement,
];
if (this._isEnabled) {
for (const keyElement of keyElements) {
keyElement.classList.remove('spinbox-key-disabled');
}
for (const valueElement of valueElements) {
valueElement.classList.remove('spinbox-value-disabled');
}
} else {
for (const keyElement of keyElements) {
keyElement.classList.add('spinbox-key-disabled');
}
for (const valueElement of valueElements) {
valueElement.classList.add('spinbox-value-disabled');
}
}
}
}

View File

@ -5,7 +5,7 @@ import { FileInputElement } from './elements/file_input';
import { ButtonElement } from './elements/button';
import { OutputElement } from './elements/output';
import { Action, AppContext } from '../app_context';
import { LOG } from '../util';
import { ASSERT, LOG } from '../util';
import fs from 'fs';
import path from 'path';
@ -16,6 +16,8 @@ export interface Group {
elementsOrder: string[];
submitButton: ButtonElement;
output: OutputElement;
postElements?: { [key: string]: BaseUIElement<any> };
postElementsOrder?: string[];
}
export class UI {
@ -155,6 +157,15 @@ export class UI {
groupHTML += this._buildSubcomponent(element);
}
let postGroupHTML = '';
if (group.postElements) {
ASSERT(group.postElementsOrder, 'No post elements order');
for (const elementName of group.postElementsOrder) {
const element = group.postElements[elementName];
postGroupHTML += this._buildSubcomponent(element);
}
}
return `
${groupHTML}
<div class="item item-body">
@ -167,6 +178,7 @@ export class UI {
${group.output.generateHTML()}
</div>
</div>
${postGroupHTML}
`;
}
@ -186,6 +198,13 @@ export class UI {
element.registerEvents();
}
group.submitButton.registerEvents();
if (group.postElements) {
ASSERT(group.postElementsOrder);
for (const elementName in group.postElements) {
const element = group.postElements[elementName];
element.registerEvents();
}
}
}
}
@ -197,29 +216,55 @@ export class UI {
return this._uiDull;
}
public disable(action: Action) {
for (let i = action; i < Action.MAX; ++i) {
const key = this.uiOrder[i];
this._setGroupEnabled(this._uiDull[key], false);
}
}
public enable(action: Action) {
LOG('enabling', action);
// TODO: Remove once Simplify has been implemented
/*
if (action === Action.Simplify) {
action = Action.Voxelise;
}
const key = this.uiOrder[action];
this._setGroupEnabled(this._uiDull[key], true);
*/
const group = this._getActionGroup(action);
for (const compName in group.elements) {
group.elements[compName].setEnabled(true);
}
group.submitButton.setEnabled(true);
// Enable the post elements of the previous group
const prevGroup = this._getActionGroup(action - 1);
if (prevGroup && prevGroup.postElements) {
ASSERT(prevGroup.postElementsOrder);
for (const postElementName in prevGroup.postElements) {
prevGroup.postElements[postElementName].setEnabled(true);
}
}
}
private _setGroupEnabled(group: Group, isEnabled: boolean) {
for (const compName in group.elements) {
const comp = group.elements[compName];
comp.setEnabled(isEnabled);
}
group.submitButton.setEnabled(isEnabled);
if (!isEnabled) {
public disable(action: Action) {
for (let i = action; i < Action.MAX; ++i) {
const group = this._getActionGroup(i);
LOG('disabling', group.label);
for (const compName in group.elements) {
group.elements[compName].setEnabled(false);
}
group.submitButton.setEnabled(false);
group.output.clearMessage();
if (group.postElements) {
LOG(group.label, 'has post-element');
ASSERT(group.postElementsOrder);
for (const postElementName in group.postElements) {
LOG('disabling post-element', postElementName, 'for', group.label);
group.postElements[postElementName].setEnabled(false);
}
}
}
// Disable the post elements of the previous group
const prevGroup = this._getActionGroup(action - 1);
if (prevGroup && prevGroup.postElements) {
ASSERT(prevGroup.postElementsOrder);
for (const postElementName in prevGroup.postElements) {
prevGroup.postElements[postElementName].setEnabled(false);
}
}
}

View File

@ -74,7 +74,7 @@ canvas {
.item-header {
background-color: #2F2F2F;
color: #C6C6C6;
font-weight: 500;
font-weight: 400;
padding: 10px 20px;
}
@ -150,10 +150,12 @@ select {
font-weight: 300;
color: #A8A8A8;
background-color: #2F2F2F;
border: 1px solid rgb(255, 255, 255, 0.0);
}
select:hover {
select:hover:enabled {
color: #C6C6C6;
background-color: #383838;
border: 1px solid rgb(255, 255, 255, 0.1);
}
select:disabled {
background-color: #282828 !important;
@ -188,6 +190,8 @@ select:disabled {
color: #535353;
}
.new-slider {
border-radius: 5px;
font-family: 'Lexend', sans-serif;
@ -196,20 +200,28 @@ select:disabled {
cursor: ew-resize;
height: 30px;
font-size: 90%;
border: 1px solid #1A1A1A;
}
.new-slider-hover {
border: 1px solid rgba(255, 255, 255, 0.1) !important;
background-color: #383838 !important;
}
.new-slider-disabled {
background-color: #242424 !important;
cursor: default !important;
}
.new-slider-bar {
border-radius: 5px;
height: 28px;
background-color: var(--prim-color);
border: 1px solid rgb(255, 255, 255, 0.0);
}
.new-slider-bar:hover {
border: 1px solid rgb(255, 255, 255, 0.2);
background-color: var(--prim-color-hover);
}
.new-slider-disabled {
background-color: #242424;
cursor: default !important;
.new-slider-bar-hover {
border: 1px solid rgb(255, 255, 255, 0.2) !important;
background-color: var(--prim-color-hover) !important;
}
.new-slider-bar-disabled {
background-color: var(--prim-color-disabled) !important;
@ -217,6 +229,8 @@ select:disabled {
border: 1px solid rgb(255, 255, 255, 0.0) !important;
}
.button {
background-color: var(--prim-color);
border-radius: 5px;
@ -311,4 +325,53 @@ select:disabled {
border: 1.5px solid rgb(156, 27, 27);
transition-duration: 1s;
color: rgb(156, 27, 27);
}
.spinbox-key {
border-radius: 5px 0px 0px 5px;
height: calc(32px - 8.5px);
color: #ffffffb9;
padding: 8.5px 8px 0px 8px;
font-size: 85%;
font-weight: 400;
border-width: 1px 0px 1px 1px;
border-style: solid;
border-color: rgba(255, 255, 255, 0.0);
}
.spinbox-key-hover {
border-color: rgba(255, 255, 255, 0.2) !important;
filter: brightness(1.5);
cursor: ew-resize;
}
.spinbox-key-disabled {
filter: brightness(0.4);
}
.spinbox-value {
background-color: #2F2F2F;
border-radius: 0px 5px 5px 0px;
flex-grow: 1;
height: calc(32px - 8.5px);
padding: 8.5px 0px 0px 0px;
font-weight: 300;
border-width: 1px 1px 1px 0px;
border-style: solid;
border-color: rgba(255, 255, 255, 0.0);
color: #A8A8A8;
align-self: center;
text-align: center;
}
.spinbox-value-hover {
border-color: rgba(255, 255, 255, 0.2) !important;
background-color: #383838 !important;
cursor: ew-resize;
}
.spinbox-value-disabled {
color: #535353;
background-color: #242424 !important;
}
.invis-divider {
width: 6px;
}