From 7f63b8b1ff59c90d7cbec810610f97cbae332634 Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Sun, 13 Jun 2021 18:22:21 -0700 Subject: [PATCH] Groups are the only object with children --- packages/webamp-modern-2/src/skin/Bitmap.ts | 3 ++- .../webamp-modern-2/src/skin/Container.ts | 15 ++++++++---- packages/webamp-modern-2/src/skin/Group.ts | 9 +++++++- packages/webamp-modern-2/src/skin/GuiObj.ts | 7 +++++- packages/webamp-modern-2/src/skin/Layer.ts | 2 ++ packages/webamp-modern-2/src/skin/Layout.ts | 23 +++++++------------ packages/webamp-modern-2/src/skin/parse.ts | 12 ++++++---- 7 files changed, 44 insertions(+), 27 deletions(-) diff --git a/packages/webamp-modern-2/src/skin/Bitmap.ts b/packages/webamp-modern-2/src/skin/Bitmap.ts index 29786aba..1ef672b1 100644 --- a/packages/webamp-modern-2/src/skin/Bitmap.ts +++ b/packages/webamp-modern-2/src/skin/Bitmap.ts @@ -39,8 +39,9 @@ export default class Bitmap { this._gammagroup = value; break; default: - console.log({ key }); + return false; } + return true; } getWidth() { diff --git a/packages/webamp-modern-2/src/skin/Container.ts b/packages/webamp-modern-2/src/skin/Container.ts index 2dbdd032..53fa284c 100644 --- a/packages/webamp-modern-2/src/skin/Container.ts +++ b/packages/webamp-modern-2/src/skin/Container.ts @@ -3,8 +3,15 @@ import Group from "./Group"; import Layout from "./Layout"; import XmlObj from "./XmlObj"; +// > A container is a top level object and it basically represents a window. +// > Nothing holds a container. It is an object that holds multiple related +// > layouts. Each layout represents an appearance for that window. You can design +// > different layouts for each window but only one can be visible at a time. +// +// -- http://wiki.winamp.com/wiki/Modern_Skin:_Container export default class Container extends XmlObj { _layouts: Layout[] = []; + _activeLayout: Layout | null = null; _defaultVisible: boolean = true; constructor() { super(); @@ -17,6 +24,7 @@ export default class Container extends XmlObj { switch (key) { case "default_visible": this._defaultVisible = toBool(value); + break; default: return false; } @@ -26,14 +34,13 @@ export default class Container extends XmlObj { addLayout(layout: Layout) { layout.setParent(this); this._layouts.push(layout); + this._activeLayout = layout; } getDebugDom(): HTMLDivElement { const div = window.document.createElement("div"); - if (this._defaultVisible) { - for (const layout of this._layouts) { - div.appendChild(layout.getDebugDom()); - } + if (this._defaultVisible && this._activeLayout) { + div.appendChild(this._activeLayout.getDebugDom()); } return div; } diff --git a/packages/webamp-modern-2/src/skin/Group.ts b/packages/webamp-modern-2/src/skin/Group.ts index 96edde85..e1e3e130 100644 --- a/packages/webamp-modern-2/src/skin/Group.ts +++ b/packages/webamp-modern-2/src/skin/Group.ts @@ -1,7 +1,6 @@ import * as Utils from "../utils"; import UI_ROOT from "../UIRoot"; import GuiObj from "./GuiObj"; -import Script from "./Script"; import SystemObject from "./SystemObject"; export default class Group extends GuiObj { @@ -13,6 +12,7 @@ export default class Group extends GuiObj { _minimumWidth: number; _maximumWidth: number; _systemObjects: SystemObject[] = []; + _children: GuiObj[] = []; setXmlAttr(key: string, value: string): boolean { if (super.setXmlAttr(key, value)) { @@ -48,6 +48,10 @@ export default class Group extends GuiObj { this._systemObjects.push(systemObj); } + addChild(child: GuiObj) { + this._children.push(child); + } + getDebugDom(): HTMLDivElement { const div = super.getDebugDom(); div.style.height = Utils.px(this._maximumHeight); @@ -56,6 +60,9 @@ export default class Group extends GuiObj { const bitmap = UI_ROOT.getBitmap(this._background); div.style.background = bitmap.getBackgrondCSSAttribute(); } + for (const child of this._children) { + div.appendChild(child.getDebugDom()); + } return div; } } diff --git a/packages/webamp-modern-2/src/skin/GuiObj.ts b/packages/webamp-modern-2/src/skin/GuiObj.ts index 2e8e9559..4104627e 100644 --- a/packages/webamp-modern-2/src/skin/GuiObj.ts +++ b/packages/webamp-modern-2/src/skin/GuiObj.ts @@ -1,6 +1,7 @@ import * as Utils from "../utils"; import XmlObj from "./XmlObj"; +// http://wiki.winamp.com/wiki/XML_GUI_Objects#GuiObject_.28Global_params.29 export default class GuiObj extends XmlObj { _id: string; _width: number; @@ -8,6 +9,7 @@ export default class GuiObj extends XmlObj { _x: number = 0; _y: number = 0; _droptarget: string; + _visible: boolean = true; setXmlAttr(key: string, value: string): boolean { switch (key) { @@ -29,6 +31,9 @@ export default class GuiObj extends XmlObj { case "droptarget": this._droptarget = value; break; + case "visible": + this._visible = Utils.toBool(value); + break; default: return false; } @@ -37,7 +42,7 @@ export default class GuiObj extends XmlObj { getDebugDom(): HTMLDivElement { const div = window.document.createElement("div"); - div.style.display = "inline-block"; + div.style.display = this._visible ? "inline-block" : "none"; div.style.position = "absolute"; if (this._x) { div.style.left = Utils.px(this._x); diff --git a/packages/webamp-modern-2/src/skin/Layer.ts b/packages/webamp-modern-2/src/skin/Layer.ts index 987c371e..11640516 100644 --- a/packages/webamp-modern-2/src/skin/Layer.ts +++ b/packages/webamp-modern-2/src/skin/Layer.ts @@ -2,6 +2,7 @@ import GuiObj from "./GuiObj"; import UI_ROOT from "../UIRoot"; import { px } from "../utils"; +// http://wiki.winamp.com/wiki/XML_GUI_Objects#.3Clayer.2F.3E export default class Layer extends GuiObj { _image: string; @@ -12,6 +13,7 @@ export default class Layer extends GuiObj { switch (key) { case "image": this._image = value; + break; default: return false; } diff --git a/packages/webamp-modern-2/src/skin/Layout.ts b/packages/webamp-modern-2/src/skin/Layout.ts index f0d4684e..1d974106 100644 --- a/packages/webamp-modern-2/src/skin/Layout.ts +++ b/packages/webamp-modern-2/src/skin/Layout.ts @@ -3,10 +3,16 @@ import * as Utils from "../utils"; import Container from "./Container"; import Layer from "./Layer"; +// > A layout is a special kind of group, which shown inside a container. Each +// > layout represents an appearance for that window. Layouts give you the ability +// > to design different looks for the same container (or window). However, only +// > one layout can be visible at a time. You must toggle among layouts you +// > defined. An example is the normal mode and windowshade mode in the Default +// > skin. +// +// -- http://wiki.winamp.com/wiki/Modern_Skin:_Container export default class Layout extends Group { _parent: Container | null = null; - // TODO: I don't think Layers are actually children of Layouts - _layers: Layer[] = []; setXmlAttr(key: string, value: string): boolean { if (super.setXmlAttr(key, value)) { @@ -25,17 +31,4 @@ export default class Layout extends Group { setParent(container: Container) { this._parent = container; } - - // TODO: I don't think this is right. - addLayer(layer: Layer) { - this._layers.push(layer); - } - - getDebugDom(): HTMLDivElement { - const div = super.getDebugDom(); - for (const layer of this._layers) { - div.appendChild(layer.getDebugDom()); - } - return div; - } } diff --git a/packages/webamp-modern-2/src/skin/parse.ts b/packages/webamp-modern-2/src/skin/parse.ts index 1a55110b..6be0b8e1 100644 --- a/packages/webamp-modern-2/src/skin/parse.ts +++ b/packages/webamp-modern-2/src/skin/parse.ts @@ -242,18 +242,20 @@ export default class SkinParser { } async groupdef(node: XmlElement) { - await this.traverseChildren(node); + // await this.traverseChildren(node); } async layer(node: XmlElement) { const layer = new Layer(); layer.setXmlAttributes(node.attributes); - const { layout } = this._context; - if (layout == null) { - console.warn("FIXME: Expected to be within a "); + const { parentGroup } = this._context; + if (parentGroup == null) { + console.warn( + `FIXME: Expected to be within a | ` + ); return; } - layout.addLayer(layer); + parentGroup.addChild(layer); await this.traverseChildren(node); }