Skip to content

Commit

Permalink
Scrollview remove entity reference (#7206)
Browse files Browse the repository at this point in the history
* optimize render component rootBone property

* expose rootBone property

* Update src/framework/components/render/component.js

Co-authored-by: Will Eastcott <willeastcott@gmail.com>

* use jsdo import

* .

* ButtonComponent remove EntityReference

* remove reliance on component system global event lists

* remove EntityReference from ScrollbarComponent

* remove EntityReference, optimize ScrollVeiw and Scrollbar

* lint

---------

Co-authored-by: Will Eastcott <willeastcott@gmail.com>
# Conflicts:
#	src/framework/components/scroll-view/component.js
#	src/framework/components/scroll-view/data.js
#	src/framework/components/scrollbar/component.js
#	src/framework/components/scrollbar/data.js
#	test/framework/utils/entity-reference.test.mjs
  • Loading branch information
Maksims authored and Martin Valigursky committed Jan 13, 2025
1 parent e81199c commit 0cae571
Show file tree
Hide file tree
Showing 10 changed files with 615 additions and 1,044 deletions.
613 changes: 476 additions & 137 deletions src/framework/components/scroll-view/component.js

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions src/framework/components/scroll-view/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,22 @@ class ScrollViewComponentData {
mouseWheelSensitivity = new Vec2(1, 1);

/** @type {number} */
horizontalScrollbarVisibility;
horizontalScrollbarVisibility = 0;

/** @type {number} */
verticalScrollbarVisibility;
verticalScrollbarVisibility = 0;

/** @type {Entity} */
viewportEntity;
/** @type {Entity|null} */
viewportEntity = null;

/** @type {Entity} */
contentEntity;
/** @type {Entity|null} */
contentEntity = null;

/** @type {Entity} */
horizontalScrollbarEntity;
/** @type {Entity|null} */
horizontalScrollbarEntity = null;

/** @type {Entity} */
verticalScrollbarEntity;
/** @type {Entity|null} */
verticalScrollbarEntity = null;
}

export { ScrollViewComponentData };
11 changes: 6 additions & 5 deletions src/framework/components/scroll-view/system.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ const _schema = [
{ name: 'useMouseWheel', type: 'boolean' },
{ name: 'mouseWheelSensitivity', type: 'vec2' },
{ name: 'horizontalScrollbarVisibility', type: 'number' },
{ name: 'verticalScrollbarVisibility', type: 'number' },
{ name: 'viewportEntity', type: 'entity' },
{ name: 'contentEntity', type: 'entity' },
{ name: 'horizontalScrollbarEntity', type: 'entity' },
{ name: 'verticalScrollbarEntity', type: 'entity' }
{ name: 'verticalScrollbarVisibility', type: 'number' }
];

const DEFAULT_DRAG_THRESHOLD = 10;
Expand Down Expand Up @@ -66,6 +62,11 @@ class ScrollViewComponentSystem extends ComponentSystem {
}

super.initializeComponentData(component, data, _schema);

component.viewportEntity = data.viewportEntity;
component.contentEntity = data.contentEntity;
component.horizontalScrollbarEntity = data.horizontalScrollbarEntity;
component.verticalScrollbarEntity = data.verticalScrollbarEntity;
}

onUpdate(dt) {
Expand Down
126 changes: 104 additions & 22 deletions src/framework/components/scrollbar/component.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { math } from '../../../core/math/math.js';
import { ORIENTATION_HORIZONTAL } from '../../../scene/constants.js';

import { GraphNode } from '../../../scene/graph-node.js';

import { Component } from '../component.js';
import { ElementDragHelper } from '../element/element-drag-helper.js';
import { EntityReference } from '../../utils/entity-reference.js';

/**
* @import { EventHandle } from '../../../core/event-handle.js'
* @import { Entity } from '../../entity.js'
* @import { ScrollbarComponentData } from './data.js'
* @import { ScrollbarComponentSystem } from './system.js'
Expand All @@ -29,6 +32,24 @@ class ScrollbarComponent extends Component {
*/
static EVENT_SETVALUE = 'set:value';

/**
* @type {Entity|null}
* @private
*/
_handleEntity = null;

/**
* @type {EventHandle|null}
* @private
*/
_evtHandleEntityElementAdd = null;

/**
* @type {EventHandle[]}
* @private
*/
_evtHandleEntityChanges = [];

/**
* Create a new ScrollbarComponent.
*
Expand All @@ -37,15 +58,6 @@ class ScrollbarComponent extends Component {
*/
constructor(system, entity) {
super(system, entity);

this._handleReference = new EntityReference(this, 'handleEntity', {
'element#gain': this._onHandleElementGain,
'element#lose': this._onHandleElementLose,
'element#set:anchor': this._onSetHandleAlignment,
'element#set:margin': this._onSetHandleAlignment,
'element#set:pivot': this._onSetHandleAlignment
});

this._toggleLifecycleListeners('on');
}

Expand Down Expand Up @@ -142,19 +154,48 @@ class ScrollbarComponent extends Component {
* Sets the entity to be used as the scrollbar handle. This entity must have a
* {@link ScrollbarComponent}.
*
* @type {Entity}
* @type {Entity|string|null}
*/
set handleEntity(arg) {
this._setValue('handleEntity', arg);
if (this._handleEntity === arg) {
return;
}

const isString = typeof arg === 'string';
if (this._handleEntity && isString && this._handleEntity.getGuid() === arg) {
return;
}

if (this._handleEntity) {
this._handleEntityUnsubscribe();
}

if (arg instanceof GraphNode) {
this._handleEntity = arg;
} else if (isString) {
this._handleEntity = this.system.app.getEntityFromIndex(arg) || null;
} else {
this._handleEntity = null;
}

if (this._handleEntity) {
this._handleEntitySubscribe();
}

if (this._handleEntity) {
this.data.handleEntity = this._handleEntity.getGuid();
} else if (isString && arg) {
this.data.handleEntity = arg;
}
}

/**
* Gets the entity to be used as the scrollbar handle.
*
* @type {Entity}
* @type {Entity|null}
*/
get handleEntity() {
return this.data.handleEntity;
return this._handleEntity;
}

/** @ignore */
Expand All @@ -177,20 +218,56 @@ class ScrollbarComponent extends Component {
// TODO Handle scrollwheel events
}

_handleEntitySubscribe() {
this._evtHandleEntityElementAdd = this._handleEntity.on('element:add', this._onHandleElementGain, this);

if (this._handleEntity.element) {
this._onHandleElementGain();
}
}

_handleEntityUnsubscribe() {
this._evtHandleEntityElementAdd?.off();
this._evtHandleEntityElementAdd = null;

if (this._handleEntity?.element) {
this._onHandleElementLose();
}
}

_handleEntityElementSubscribe() {
const element = this._handleEntity.element;

const handles = this._evtHandleEntityChanges;
handles.push(element.once('beforeremove', this._onHandleElementLose, this));
handles.push(element.on('set:anchor', this._onSetHandleAlignment, this));
handles.push(element.on('set:margin', this._onSetHandleAlignment, this));
handles.push(element.on('set:pivot', this._onSetHandleAlignment, this));
}

_handleEntityElementUnsubscribe() {
for (let i = 0; i < this._evtHandleEntityChanges.length; i++) {
this._evtHandleEntityChanges[i].off();
}
this._evtHandleEntityChanges.length = 0;
}

_onHandleElementGain() {
this._handleEntityElementSubscribe();
this._destroyDragHelper();
this._handleDragHelper = new ElementDragHelper(this._handleReference.entity.element, this._getAxis());
this._handleDragHelper = new ElementDragHelper(this._handleEntity.element, this._getAxis());
this._handleDragHelper.on('drag:move', this._onHandleDrag, this);

this._updateHandlePositionAndSize();
}

_onHandleElementLose() {
this._handleEntityElementUnsubscribe();
this._destroyDragHelper();
}

_onHandleDrag(position) {
if (this._handleReference.entity && this.enabled && this.entity.enabled) {
if (this._handleEntity && this.enabled && this.entity.enabled) {
this.value = this._handlePositionToScrollValue(position[this._getAxis()]);
}
}
Expand All @@ -215,19 +292,19 @@ class ScrollbarComponent extends Component {
}

_onSetOrientation(name, oldValue, newValue) {
if (newValue !== oldValue && this._handleReference.hasComponent('element')) {
this._handleReference.entity.element[this._getOppositeDimension()] = 0;
if (newValue !== oldValue && this._handleEntity?.element) {
this._handleEntity.element[this._getOppositeDimension()] = 0;
}
}

_updateHandlePositionAndSize() {
const handleEntity = this._handleReference.entity;
const handleElement = handleEntity && handleEntity.element;
const handleEntity = this._handleEntity;
const handleElement = handleEntity?.element;

if (handleEntity) {
const position = handleEntity.getLocalPosition();
position[this._getAxis()] = this._getHandlePosition();
this._handleReference.entity.setLocalPosition(position);
handleEntity.setLocalPosition(position);
}

if (handleElement) {
Expand Down Expand Up @@ -292,7 +369,6 @@ class ScrollbarComponent extends Component {
}

onEnable() {
this._handleReference.onParentComponentEnable();
this._setHandleDraggingEnabled(true);
}

Expand All @@ -304,6 +380,12 @@ class ScrollbarComponent extends Component {
this._destroyDragHelper();
this._toggleLifecycleListeners('off');
}

resolveDuplicatedEntityReferenceProperties(oldScrollbar, duplicatedIdsMap) {
if (oldScrollbar.handleEntity) {
this.handleEntity = duplicatedIdsMap[oldScrollbar.handleEntity.getGuid()];
}
}
}

export { ScrollbarComponent };
4 changes: 2 additions & 2 deletions src/framework/components/scrollbar/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ class ScrollbarComponentData {
value = 0;

/** @type {number} */
handleSize;
handleSize = 0;

/** @type {Entity} */
handleEntity;
handleEntity = null;
}

export { ScrollbarComponentData };
9 changes: 7 additions & 2 deletions src/framework/components/scrollbar/system.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ const _schema = [
{ name: 'enabled', type: 'boolean' },
{ name: 'orientation', type: 'number' },
{ name: 'value', type: 'number' },
{ name: 'handleSize', type: 'number' },
{ name: 'handleEntity', type: 'entity' }
{ name: 'handleSize', type: 'number' }
];

/**
Expand All @@ -36,11 +35,17 @@ class ScrollbarComponentSystem extends ComponentSystem {

this.schema = _schema;

this.on('add', this._onAddComponent, this);
this.on('beforeremove', this._onRemoveComponent, this);
}

initializeComponentData(component, data, properties) {
super.initializeComponentData(component, data, _schema);
component.handleEntity = data.handleEntity;
}

_onAddComponent(entity) {
entity.fire('scrollbar:add');
}

_onRemoveComponent(entity, component) {
Expand Down
10 changes: 10 additions & 0 deletions src/framework/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,16 @@ function resolveDuplicatedEntityReferenceProperties(oldSubtreeRoot, oldEntity, n
newEntity.button.resolveDuplicatedEntityReferenceProperties(components.button, duplicatedIdsMap);
}

// Handle entity scrollview attributes
if (components.scrollview) {
newEntity.scrollview.resolveDuplicatedEntityReferenceProperties(components.scrollview, duplicatedIdsMap);
}

// Handle entity scrollbar attributes
if (components.scrollbar) {
newEntity.scrollbar.resolveDuplicatedEntityReferenceProperties(components.scrollbar, duplicatedIdsMap);
}

// Handle entity anim attributes
if (components.anim) {
newEntity.anim.resolveDuplicatedEntityReferenceProperties(components.anim, duplicatedIdsMap);
Expand Down
Loading

0 comments on commit 0cae571

Please sign in to comment.