import React from 'react'; import { Container, Graphics } from 'pixi.js'; import { Entity } from '../entity'; import { Debug } from '../debug'; import { IGameState } from 'Library'; type HierarchyProps = { root: Entity | Container; setSelected: (obj: Entity | Container) => void; setMoused: (obj: Entity | Container | null) => void; gameState: IGameState; selectedEntity: Entity | Container | null; }; export class Hierarchy extends React.Component<HierarchyProps, { hover: boolean; collapsed: boolean; }> { constructor(props: HierarchyProps) { super(props); this.state = { hover: false, collapsed: true, }; setInterval(() => { this.updateDebugGraphics(); }, 200); } oldTint: { [key: number]: number } = {}; hoverGraphics: Graphics[] = []; hoverTarget: Entity | Container | null = null; updateDebugGraphics = () => { // clear debug graphics for (const graphic of this.hoverGraphics) { graphic.parent.removeChild(graphic); graphic.destroy(); } this.hoverGraphics = []; if (this.hoverTarget !== null) { this.hoverGraphics = [...Debug.DrawBounds(this.props.root, 0xff0000, true, "stage")]; if (this.props.root instanceof Entity) { const point = Debug.DrawPoint(this.props.root.position, 0xff0000, true); this.hoverGraphics = [ ...this.hoverGraphics, point, ]; } } if (this.props.selectedEntity === this.props.root) { this.hoverGraphics = [...this.hoverGraphics, ...Debug.DrawBounds(this.props.selectedEntity, 0xff0000, true, "stage")]; if (this.props.root instanceof Entity) { const point = Debug.DrawPoint(this.props.selectedEntity.position, 0xff0000, true); this.hoverGraphics = [ ...this.hoverGraphics, point, ]; } } }; mouseOver = () => { this.setState({ hover: true }) if (this.props.root instanceof Entity) { this.oldTint[this.props.root.id] = this.props.root.sprite.tint; this.props.root.sprite.tint = 0x000099; } this.hoverTarget = this.props.root; this.props.setMoused(this.props.root); }; mouseOut = () => { this.setState({ hover: false }) if (this.props.root instanceof Entity) { this.props.root.sprite.tint = this.oldTint[this.props.root.id]; } this.hoverTarget = null; this.props.setMoused(null); }; click = () => { this.props.setSelected(this.props.root); console.log(this.props.root); }; renderLeaf(root: any) { let active = true; if (root instanceof Entity) { active = root.activeModes.includes(this.props.gameState.mode); } return (<div style={{ color: active ? "white" : "gray", }}> {this.props.selectedEntity === this.props.root ? <strong>{root.name}</strong> : root.name} (depth: { root.zIndex}) </div>) } render() { const root = this.props.root; let allChildren = ( root instanceof Entity ? root.children() : [] ); let children = allChildren; let canCollapse = children.length > 20; let didCollapse = false; if (canCollapse) { if (this.state.collapsed) { children = children.slice(0, 20); didCollapse = true; } } if (children) return ( <div style={{ paddingLeft: "10px", fontFamily: 'Arial', fontSize: '14px', backgroundColor: this.state.hover ? "darkgray" : "black" }} > <div onMouseEnter={this.mouseOver} onMouseLeave={this.mouseOut} onClick={this.click} > {this.renderLeaf(root)} </div> { canCollapse ? <div onClick={() => this.setState({ collapsed: !this.state.collapsed })} style={{ padding: "8px 0" }}> { didCollapse ? <span>[see {allChildren.length - 20} more]</span> : <span>[collapse]</span> } </div> : null } { children.map(child => { return <Hierarchy selectedEntity={this.props.selectedEntity} setMoused={this.props.setMoused} setSelected={this.props.setSelected} root={child} gameState={this.props.gameState} /> }) } </div> ) }; }