From 4411b4e56d0205e4be1791b880158238de555fae Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Sat, 26 Jun 2021 15:18:30 -0700 Subject: [PATCH] First stab at render updates --- packages/webamp-modern-2/src/index.ts | 3 +- .../webamp-modern-2/src/maki/interpreter.tsx | 5 +- .../webamp-modern-2/src/skin/AnimatedLayer.ts | 11 ++- packages/webamp-modern-2/src/skin/Bitmap.ts | 3 +- .../webamp-modern-2/src/skin/BitmapFont.ts | 3 +- packages/webamp-modern-2/src/skin/Button.ts | 67 ++++++++++++++----- .../webamp-modern-2/src/skin/Container.ts | 19 ++++-- packages/webamp-modern-2/src/skin/Group.ts | 19 +++--- packages/webamp-modern-2/src/skin/GuiObj.ts | 45 ++++++++----- packages/webamp-modern-2/src/skin/Layer.ts | 19 +++--- packages/webamp-modern-2/src/skin/Layout.ts | 7 +- packages/webamp-modern-2/src/skin/Text.ts | 16 ++--- .../webamp-modern-2/src/skin/ToggleButton.ts | 5 ++ 13 files changed, 142 insertions(+), 80 deletions(-) diff --git a/packages/webamp-modern-2/src/index.ts b/packages/webamp-modern-2/src/index.ts index fac5df96..7f48ee47 100644 --- a/packages/webamp-modern-2/src/index.ts +++ b/packages/webamp-modern-2/src/index.ts @@ -27,7 +27,8 @@ async function main() { let node = document.createElement("div"); for (const container of parser._containers) { - node.appendChild(container.getDebugDom()); + container.draw(); + node.appendChild(container.getDiv()); } document.body.appendChild(node); diff --git a/packages/webamp-modern-2/src/maki/interpreter.tsx b/packages/webamp-modern-2/src/maki/interpreter.tsx index 8b1375e5..2bd1b8d7 100644 --- a/packages/webamp-modern-2/src/maki/interpreter.tsx +++ b/packages/webamp-modern-2/src/maki/interpreter.tsx @@ -5,6 +5,7 @@ import { getClass, getMethod } from "./objects"; import { classResolver } from "../skin/resolver"; function validateMaki(program: ParsedMaki) { + return; // Comment this out to get warnings about missing methods for (const method of program.methods) { if (method.name.startsWith("on")) { continue; @@ -82,8 +83,8 @@ class Interpreter { const offsetIntoVariables = command.arg; const current = this.variables[offsetIntoVariables]; assume( - aValue.type === current.type, - "Assigned from one type to a different type." + typeof aValue.value === typeof current.value, + `Assigned from one type to a different type ${typeof aValue.value}, ${typeof current.value}.` ); current.value = aValue.value; diff --git a/packages/webamp-modern-2/src/skin/AnimatedLayer.ts b/packages/webamp-modern-2/src/skin/AnimatedLayer.ts index 4e4093bc..616e27dc 100644 --- a/packages/webamp-modern-2/src/skin/AnimatedLayer.ts +++ b/packages/webamp-modern-2/src/skin/AnimatedLayer.ts @@ -1,7 +1,8 @@ import Layer from "./Layer"; export default class AnimatedLayer extends Layer { - setXmlAttr(key: string, value: string): boolean { + setXmlAttr(_key: string, value: string): boolean { + const key = _key.toLowerCase(); if (super.setXmlAttr(key, value)) { return true; } @@ -16,10 +17,8 @@ export default class AnimatedLayer extends Layer { } gotoframe(framenum: number) {} - getDebugDom(): HTMLDivElement { - const div = super.getDebugDom(); - - div.setAttribute("data-obj-name", "AnimatedLayer"); - return div; + draw() { + super.draw(); + this._div.setAttribute("data-obj-name", "AnimatedLayer"); } } diff --git a/packages/webamp-modern-2/src/skin/Bitmap.ts b/packages/webamp-modern-2/src/skin/Bitmap.ts index 3e966f6b..d34df2c3 100644 --- a/packages/webamp-modern-2/src/skin/Bitmap.ts +++ b/packages/webamp-modern-2/src/skin/Bitmap.ts @@ -16,7 +16,8 @@ export default class Bitmap { } } - setXmlAttr(key: string, value: string) { + setXmlAttr(_key: string, value: string) { + const key = _key.toLowerCase(); switch (key) { case "id": this._id = value; diff --git a/packages/webamp-modern-2/src/skin/BitmapFont.ts b/packages/webamp-modern-2/src/skin/BitmapFont.ts index a6f75550..e7dc3ce3 100644 --- a/packages/webamp-modern-2/src/skin/BitmapFont.ts +++ b/packages/webamp-modern-2/src/skin/BitmapFont.ts @@ -11,7 +11,8 @@ export default class BitmapFont { } } - setXmlAttr(key: string, value: string) { + setXmlAttr(_key: string, value: string) { + const key = _key.toLowerCase(); switch (key) { case "id": this._id = value; diff --git a/packages/webamp-modern-2/src/skin/Button.ts b/packages/webamp-modern-2/src/skin/Button.ts index 35d82898..024a5f6a 100644 --- a/packages/webamp-modern-2/src/skin/Button.ts +++ b/packages/webamp-modern-2/src/skin/Button.ts @@ -1,11 +1,16 @@ import GuiObj from "./GuiObj"; import UI_ROOT from "../UIRoot"; import { px } from "../utils"; +import { VM } from "./VM"; // http://wiki.winamp.com/wiki/XML_GUI_Objects#.3Cbutton.2F.3E_.26_.3Ctogglebutton.2F.3E export default class Button extends GuiObj { _image: string; - setXmlAttr(key: string, value: string): boolean { + _downimage: string; + _active: boolean = false; + + setXmlAttr(_key: string, value: string): boolean { + const key = _key.toLowerCase(); if (super.setXmlAttr(key, value)) { return true; } @@ -13,6 +18,9 @@ export default class Button extends GuiObj { case "image": this._image = value; break; + case "downimage": + this._downimage = value; + break; default: return false; } @@ -20,27 +28,56 @@ export default class Button extends GuiObj { } getactivated(): boolean { - return true; + return this._active; } setactivated(onoff: boolean) { - // TODO + const previous = this._active; + this._active = onoff; + if (onoff !== previous) { + VM.dispatch(this, "onactivate", [ + { type: "BOOL", value: this._active ? 0 : 1 }, + ]); + this._renderBackground(); + } } - getDebugDom(): HTMLDivElement { - const div = super.getDebugDom(); - div.setAttribute("data-obj-name", "Button"); - if (this._image != null) { - const bitmap = UI_ROOT.getBitmap(this._image); - div.style.backgroundImage = bitmap.getBackgrondImageCSSAttribute(); - div.style.backgroundPosition = bitmap.getBackgrondPositionCSSAttribute(); - if (div.style.width === "" && bitmap.getWidth()) { - div.style.width = px(bitmap.getWidth()); + _renderBackground() { + let image = this._image; + if (this._active && this._downimage) { + image = this._downimage; + } + if (image != null) { + const bitmap = UI_ROOT.getBitmap(image); + this._div.style.backgroundImage = bitmap.getBackgrondImageCSSAttribute(); + this._div.style.backgroundPosition = bitmap.getBackgrondPositionCSSAttribute(); + if (this._div.style.width === "" && bitmap.getWidth()) { + this._div.style.width = px(bitmap.getWidth()); } - if (div.style.height === "" && bitmap.getHeight()) { - div.style.height = px(bitmap.getHeight()); + if (this._div.style.height === "" && bitmap.getHeight()) { + this._div.style.height = px(bitmap.getHeight()); } } - return div; + } + + _bindToDom() { + // TODO: Cleanup! + this._div.addEventListener("mousedown", this._handleMouseDown.bind(this)); + this._div.addEventListener("mouseup", this._handleMouseUp.bind(this)); + } + + _handleMouseDown(e: MouseEvent) { + this.setactivated(true); + } + + _handleMouseUp(e: MouseEvent) { + this.setactivated(false); + } + + draw() { + super.draw(); + this._div.setAttribute("data-obj-name", "Button"); + this._bindToDom(); + this._renderBackground(); } /* diff --git a/packages/webamp-modern-2/src/skin/Container.ts b/packages/webamp-modern-2/src/skin/Container.ts index 11a060e8..f7f05735 100644 --- a/packages/webamp-modern-2/src/skin/Container.ts +++ b/packages/webamp-modern-2/src/skin/Container.ts @@ -14,11 +14,13 @@ export default class Container extends XmlObj { _activeLayout: Layout | null = null; _defaultVisible: boolean = true; _id: string; + _div: HTMLDivElement = document.createElement("div"); constructor() { super(); } - setXmlAttr(key: string, value: string): boolean { + setXmlAttr(_key: string, value: string): boolean { + const key = _key.toLowerCase(); if (super.setXmlAttr(key, value)) { return true; } @@ -45,6 +47,10 @@ export default class Container extends XmlObj { return this._id; } + getDiv(): HTMLDivElement { + return this._div; + } + /* Required for Maki */ /** * Get the layout associated with the an id. @@ -72,14 +78,13 @@ export default class Container extends XmlObj { } } - getDebugDom(): HTMLDivElement { - const div = window.document.createElement("div"); - div.setAttribute("data-xml-id", this.getId()); - div.setAttribute("data-obj-name", "Container"); + draw() { + this._div.setAttribute("data-xml-id", this.getId()); + this._div.setAttribute("data-obj-name", "Container"); if (this._defaultVisible && this._activeLayout) { - div.appendChild(this._activeLayout.getDebugDom()); + this._activeLayout.draw(); + this._div.appendChild(this._activeLayout.getDiv()); } - return div; } } diff --git a/packages/webamp-modern-2/src/skin/Group.ts b/packages/webamp-modern-2/src/skin/Group.ts index f51ed98b..acb27579 100644 --- a/packages/webamp-modern-2/src/skin/Group.ts +++ b/packages/webamp-modern-2/src/skin/Group.ts @@ -17,7 +17,8 @@ export default class Group extends GuiObj { _systemObjects: SystemObject[] = []; _children: GuiObj[] = []; - setXmlAttr(key: string, value: string): boolean { + setXmlAttr(_key: string, value: string): boolean { + const key = _key.toLowerCase(); if (super.setXmlAttr(key, value)) { return true; } @@ -86,18 +87,18 @@ export default class Group extends GuiObj { ); } - getDebugDom(): HTMLDivElement { - const div = super.getDebugDom(); - div.setAttribute("data-obj-name", "Group"); - div.style.height = Utils.px(this._maximumHeight); - div.style.width = Utils.px(this._maximumWidth); + draw() { + super.draw(); + this._div.setAttribute("data-obj-name", "Group"); + this._div.style.height = Utils.px(this._maximumHeight); + this._div.style.width = Utils.px(this._maximumWidth); if (this._background != null && this._drawBackground) { const bitmap = UI_ROOT.getBitmap(this._background); - div.style.background = bitmap.getBackgrondCSSAttribute(); + this._div.style.background = bitmap.getBackgrondCSSAttribute(); } for (const child of this._children) { - div.appendChild(child.getDebugDom()); + child.draw(); + this._div.appendChild(child.getDiv()); } - return div; } } diff --git a/packages/webamp-modern-2/src/skin/GuiObj.ts b/packages/webamp-modern-2/src/skin/GuiObj.ts index c0f38ba2..e807d8f0 100644 --- a/packages/webamp-modern-2/src/skin/GuiObj.ts +++ b/packages/webamp-modern-2/src/skin/GuiObj.ts @@ -14,8 +14,11 @@ export default class GuiObj extends XmlObj { _visible: boolean = true; _dirty: boolean = false; _alpha: number = 255; + _ghost: boolean = false; + _div: HTMLDivElement = document.createElement("div"); - setXmlAttr(key: string, value: string): boolean { + setXmlAttr(_key: string, value: string): boolean { + const key = _key.toLowerCase(); switch (key) { case "id": this._id = value.toLowerCase(); @@ -35,6 +38,9 @@ export default class GuiObj extends XmlObj { case "droptarget": this._droptarget = value; break; + case "ghost": + this._ghost = Utils.toBool(value); + break; case "visible": this._visible = Utils.toBool(value); break; @@ -51,6 +57,10 @@ export default class GuiObj extends XmlObj { // pass } + getDiv(): HTMLDivElement { + return this._div; + } + getId(): string { return this._id; } @@ -182,34 +192,39 @@ export default class GuiObj extends XmlObj { */ setalpha(alpha: number) { this._alpha = alpha; - // TODO Trigger an update + this._renderAlpha(); } - getDebugDom(): HTMLDivElement { - const div = window.document.createElement("div"); - div.setAttribute("data-id", this.getId()); - div.style.display = this._visible ? "inline-block" : "none"; - div.style.position = "absolute"; - div.style.opacity = `${this._alpha / 255}`; + _renderAlpha() { + this._div.style.opacity = `${this._alpha / 255}`; + } + + draw() { + this._div.setAttribute("data-id", this.getId()); + this._div.style.display = this._visible ? "inline-block" : "none"; + this._div.style.position = "absolute"; + this._renderAlpha(); + if (this._ghost) { + this._div.style.pointerEvents = "none"; + } if (this._x) { - div.style.left = Utils.px(this._x); + this._div.style.left = Utils.px(this._x); } if (this._y) { - div.style.top = Utils.px(this._y); + this._div.style.top = Utils.px(this._y); } if (this._width) { - div.style.width = Utils.px(this._width); + this._div.style.width = Utils.px(this._width); } if (this._height) { - div.style.height = Utils.px(this._height); + this._div.style.height = Utils.px(this._height); } - div.addEventListener("mouseup", (e) => { + this._div.addEventListener("mouseup", (e) => { this.onLeftButtonUp(e.clientX, e.clientX); }); - div.addEventListener("mousedown", (e) => { + this._div.addEventListener("mousedown", (e) => { this.onLeftButtonDown(e.clientX, e.clientX); }); - return div; } } diff --git a/packages/webamp-modern-2/src/skin/Layer.ts b/packages/webamp-modern-2/src/skin/Layer.ts index 57a222d6..cdc7c4e8 100644 --- a/packages/webamp-modern-2/src/skin/Layer.ts +++ b/packages/webamp-modern-2/src/skin/Layer.ts @@ -20,20 +20,19 @@ export default class Layer extends GuiObj { return true; } - getDebugDom(): HTMLDivElement { - const div = super.getDebugDom(); - div.setAttribute("data-obj-name", "Layer"); + draw() { + super.draw(); + this._div.setAttribute("data-obj-name", "Layer"); if (this._image != null) { const bitmap = UI_ROOT.getBitmap(this._image); - div.style.backgroundImage = bitmap.getBackgrondImageCSSAttribute(); - div.style.backgroundPosition = bitmap.getBackgrondPositionCSSAttribute(); - if (!div.style.width && bitmap.getWidth()) { - div.style.width = px(bitmap.getWidth()); + this._div.style.backgroundImage = bitmap.getBackgrondImageCSSAttribute(); + this._div.style.backgroundPosition = bitmap.getBackgrondPositionCSSAttribute(); + if (!this._div.style.width && bitmap.getWidth()) { + this._div.style.width = px(bitmap.getWidth()); } - if (!div.style.height && bitmap.getHeight()) { - div.style.height = px(bitmap.getHeight()); + if (!this._div.style.height && bitmap.getHeight()) { + this._div.style.height = px(bitmap.getHeight()); } } - return div; } } diff --git a/packages/webamp-modern-2/src/skin/Layout.ts b/packages/webamp-modern-2/src/skin/Layout.ts index 2866fb21..d282a041 100644 --- a/packages/webamp-modern-2/src/skin/Layout.ts +++ b/packages/webamp-modern-2/src/skin/Layout.ts @@ -31,9 +31,8 @@ export default class Layout extends Group { this._parent = container; } - getDebugDom(): HTMLDivElement { - const div = super.getDebugDom(); - div.setAttribute("data-obj-name", "Layout"); - return div; + draw() { + super.draw(); + this._div.setAttribute("data-obj-name", "Layout"); } } diff --git a/packages/webamp-modern-2/src/skin/Text.ts b/packages/webamp-modern-2/src/skin/Text.ts index ecd2ca64..bfe37baa 100644 --- a/packages/webamp-modern-2/src/skin/Text.ts +++ b/packages/webamp-modern-2/src/skin/Text.ts @@ -106,24 +106,22 @@ offsety - (int) Extra pixels to be added to or subtracted from the calculated x // TODO } - getDebugDom(): HTMLDivElement { - const div = super.getDebugDom(); - div.innerText = this.getText(); + draw() { + super.draw(); + this._div.innerText = this.getText(); if (this._bold) { - div.style.fontWeight = "bold"; + this._div.style.fontWeight = "bold"; } if (this._align) { - div.style.textAlign = this._align; + this._div.style.textAlign = this._align; } if (this._font) { const font = UI_ROOT.getFont(this._font); - div.style.fontFamily = font.getFontFamily(); + this._div.style.fontFamily = font.getFontFamily(); } - div.style.fontSize = Utils.px(this._fontSize ?? 14); - - return div; + this._div.style.fontSize = Utils.px(this._fontSize ?? 14); } /* diff --git a/packages/webamp-modern-2/src/skin/ToggleButton.ts b/packages/webamp-modern-2/src/skin/ToggleButton.ts index d8b8144b..ffec4f14 100644 --- a/packages/webamp-modern-2/src/skin/ToggleButton.ts +++ b/packages/webamp-modern-2/src/skin/ToggleButton.ts @@ -13,6 +13,11 @@ export default class ToggleButton extends Button { return true; } + draw() { + super.draw(); + this._div.setAttribute("data-obj-name", "ToggleButton"); + } + /* extern ToggleButton.onToggle(Boolean onoff); extern int TOggleButton.getCurCfgVal()