Skip to content

Commit

Permalink
property editor flow
Browse files Browse the repository at this point in the history
  • Loading branch information
kleber-swf committed Aug 30, 2021
1 parent 2e96827 commit be3a27a
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 77 deletions.
4 changes: 2 additions & 2 deletions .vscode/typescript.code-snippets
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
"import './${TM_FILENAME_BASE}.scss';",
"",
"export class ${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/} extends HTMLElement {",
"\tpublic static readonly tagId = 'phed-${TM_FILENAME_BASE}';",
"\tpublic static readonly tagName = 'phed-${TM_FILENAME_BASE}';",
"",
"\tpublic connectedCallback() {}",
"}",
"",
"customElements.define(${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}.tagId, ${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/});",
"customElements.define(${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}.tagName, ${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/});",
""
]
}
Expand Down
2 changes: 1 addition & 1 deletion src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export class Plugin extends Phaser.Plugin {
public constructor(game: Phaser.Game, group?: Phaser.Group | Phaser.Stage) {
super(game, game.plugins);

const stage = document.createElement(Stage.tagId) as Stage;
const stage = document.createElement(Stage.tagName) as Stage;
document.body.appendChild(stage);

group = group ?? game.world;
Expand Down
4 changes: 2 additions & 2 deletions src/ui/actions/actions-toolbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Widget } from 'ui/widget/widget';
import './actions-toolbar.scss'

export class ActionsToolbar extends Widget {
public static readonly tagId = 'phred-actions-toolbar';
public static readonly tagName = 'phred-actions-toolbar';
}

customElements.define(ActionsToolbar.tagId, ActionsToolbar);
customElements.define(ActionsToolbar.tagName, ActionsToolbar);
29 changes: 29 additions & 0 deletions src/ui/properties-editors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { StringPropertyEditor } from './properties/editors/string/string-property-editor';

class PropertiesEditorsClass {
private readonly editors = {
string: StringPropertyEditor.tagName,
default: StringPropertyEditor.tagName,
};

public findEditorFor(name: string, value: any) {
// TODO what abount null / undefined values?

const editors = this.editors;
// first, try to find by the name of the property
if (name in editors) return editors[name];

// second, try to find by its type
const type = typeof value;
if (type !== 'object' && type in editors)
return editors[type];

// next, since it's an object, try to find by its contructor name
const ctor = value.contructor?.name;
if (ctor && ctor in editors) return editors[ctor];

return editors.default;
}
}

export const PropertiesEditors = new PropertiesEditorsClass();
37 changes: 37 additions & 0 deletions src/ui/properties/editors/property-editor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@import 'colors';

$property-input-background: rgba(white, 0.05);
$property-foreground: $on-background-color;

.property-editor {
display: flex;
flex-direction: row;
padding: 2px 0;

.property-title {
width: 30%;
padding: 4px 2px 2px 0;
font-size: 14px;
color: rgba($on-background-color, 0.6);
}

.property-content {
flex: 1;
color: $property-foreground;

input[type="text"] {
width: 100%;
font-size: 16px;
background-color: $property-input-background;
color: $property-foreground;
border: 1px solid transparent;
padding: 2px 4px;
outline: none !important;
transition: all 0.1s;

&:focus {
border-color: rgba($on-background-color, 0.5);
}
}
}
}
25 changes: 25 additions & 0 deletions src/ui/properties/editors/property-editor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import './property-editor.scss';

export abstract class PropertyEditor<T> extends HTMLElement {
public connectedCallback() {
this.classList.add('property-editor');
}

protected createLabel(title: string, propertyId: string): HTMLElement {
const label = document.createElement('label');
label.classList.add('property-title');
label.append(title);
label.setAttribute('for', propertyId);
return label;
}

protected abstract createValue(value: T, propertyId: string): HTMLElement;

public setContent(name: string, value: T) {
const propId = `prop-${name}`;
const title = this.createLabel(name, propId);
const content = this.createValue(value, propId);
this.appendChild(title);
this.appendChild(content);
}
}
21 changes: 21 additions & 0 deletions src/ui/properties/editors/string/string-property-editor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { PropertyEditor } from '../property-editor';
// import './string-property-editor.scss';

export class StringPropertyEditor extends PropertyEditor<string> {
public static readonly tagName = 'phed-string-property-editor';

protected createValue(value: string, propertyId: string) {
const propContent = document.createElement('div');
propContent.classList.add('property-content');

const propValue = document.createElement('input');
propValue.id = propertyId;
propValue.setAttribute('type', 'text');
propValue.setAttribute('value', value ?? '');
propContent.append(propValue);

return propContent;
}
}

customElements.define(StringPropertyEditor.tagName, StringPropertyEditor);
36 changes: 0 additions & 36 deletions src/ui/properties/panel/properties-panel.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
@import "colors";

$property-input-background: rgba(white, 0.05);
$property-foreground: $on-background-color;

phed-properties-panel {
display: flex;
flex-direction: column;
Expand All @@ -20,37 +17,4 @@ phed-properties-panel {
padding: 12px 18px;
box-shadow: 0 2px 2px $shadow-color;
}

.property-editor {
display: flex;
flex-direction: row;
padding: 2px 0;

.property-title {
width: 30%;
padding: 4px 2px 2px 0;
font-size: 14px;
color: rgba($on-background-color, 0.6);
}

.property-content {
flex: 1;
color: $property-foreground;

input[type="text"] {
width: 100%;
font-size: 16px;
background-color: $property-input-background;
color: $property-foreground;
border: 1px solid transparent;
padding: 2px 4px;
outline: none !important;
transition: all 0.1s;

&:focus {
border-color: rgba($on-background-color, 0.5);
}
}
}
}
}
47 changes: 18 additions & 29 deletions src/ui/properties/panel/properties-panel.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { PropertiesEditors } from 'ui/properties-editors';
import { Widget } from 'ui/widget/widget';
import { PropertyEditor } from '../editors/property-editor';
import './properties-panel.scss';

export class PropertiesPanel extends Widget {
public static readonly tagId = 'phed-properties-panel';
public static readonly tagName = 'phed-properties-panel';

private content: HTMLElement;

Expand All @@ -19,41 +21,28 @@ export class PropertiesPanel extends Widget {
this.appendChild(content);
}

private createPropertyRow(name: string, value: any) {
const propId = `prop-value-${name}`;

const prop = document.createElement('div');
prop.classList.add('property-editor');
this.content.appendChild(prop);

const propTitle = document.createElement('label');
propTitle.classList.add('property-title');
propTitle.append(name);
propTitle.setAttribute('for', propId);
prop.append(propTitle);

const propContent = document.createElement('div');
propContent.classList.add('property-content');
prop.append(propContent);

// TODO make this specific for each type of property
const propValue = document.createElement('input');
propValue.id = propId;
propValue.setAttribute('type', 'text');
propValue.setAttribute('value', value);
propContent.append(propValue);
private createPropertyRow(name: string, value: any, tagName: string) {
const row = document.createElement(tagName) as PropertyEditor<any>;
row.setContent(name, value);
this.content.appendChild(row);
}

public selectObject(obj: PIXI.DisplayObject) {
const emptyContent = this.content.cloneNode(false);
this.replaceChild(emptyContent, this.content);
this.content = emptyContent as HTMLElement;

if (!obj) return;
['name', 'scale'].forEach(prop => {
if (prop in obj) this.createPropertyRow(prop, obj[prop]);

if (!obj) {
this.content.style.visibility = 'hidden';
return;
}
this.content.style.visibility = 'visible';
['name', 'alpha'].forEach(prop => {
if (!(prop in obj)) return;
const elementId = PropertiesEditors.findEditorFor(prop, obj[prop]);
this.createPropertyRow(prop, obj[prop], elementId);
});
}
}

customElements.define(PropertiesPanel.tagId, PropertiesPanel);
customElements.define(PropertiesPanel.tagName, PropertiesPanel);
6 changes: 3 additions & 3 deletions src/ui/properties/toolbar/properties-toolbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { PropertiesPanel } from '../panel/properties-panel';
import './properties-toolbar.scss';

export class PropertiesToolbar extends Widget {
public static readonly tagId = 'phred-properties-toolbar';
public static readonly tagName = 'phred-properties-toolbar';
private readonly panels: PropertiesPanel[] = []; // TODO depend on an interface or abstract class here

public connectedCallback() {
super.connectedCallback();
const panel = document.createElement(PropertiesPanel.tagId) as PropertiesPanel;
const panel = document.createElement(PropertiesPanel.tagName) as PropertiesPanel;
this.appendChild(panel);
this.panels.push(panel);
}
Expand All @@ -18,4 +18,4 @@ export class PropertiesToolbar extends Widget {
}
}

customElements.define(PropertiesToolbar.tagId, PropertiesToolbar);
customElements.define(PropertiesToolbar.tagName, PropertiesToolbar);
8 changes: 4 additions & 4 deletions src/ui/stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Widget } from './widget/widget';
import './stage.scss';

export class Stage extends Widget {
public static readonly tagId = 'phred-stage';
public static readonly tagName = 'phred-stage';

private _game: Phaser.Game;
private actions: ActionsToolbar;
Expand Down Expand Up @@ -34,14 +34,14 @@ export class Stage extends Widget {
content.classList.add('phred-content');
this.appendChild(content);

this.actions = document.createElement(ActionsToolbar.tagId) as ActionsToolbar;
this.actions = document.createElement(ActionsToolbar.tagName) as ActionsToolbar;
content.appendChild(this.actions);

this.gameContainer = document.createElement('div');
this.gameContainer.classList.add('phred-game-container');
content.appendChild(this.gameContainer);

this.properties = document.createElement(PropertiesToolbar.tagId) as PropertiesToolbar;
this.properties = document.createElement(PropertiesToolbar.tagName) as PropertiesToolbar;
this.appendChild(this.properties);
}

Expand All @@ -50,4 +50,4 @@ export class Stage extends Widget {
}
}

customElements.define(Stage.tagId, Stage);
customElements.define(Stage.tagName, Stage);

0 comments on commit be3a27a

Please sign in to comment.