pxt-ev3/sim/visuals/nodes/moduleView.ts

162 lines
4.7 KiB
TypeScript
Raw Permalink Normal View History

2017-12-18 22:04:17 +01:00
namespace pxsim.visuals {
export function normalizeId(prefix: string, svgId: string) {
return `${prefix}-${svgId}`;
}
export function normalizeXml(prefix: string, xml: string): string {
xml = xml.replace(/id=\"(.*?)\"/g, (m: string, id: string) => {
return `id="${normalizeId(prefix, id)}"`;
});
xml = xml.replace(/url\(#(.*?)\)/g, (m: string, id: string) => {
return `url(#${normalizeId(prefix, id)})`;
});
xml = xml.replace(/xlink:href=\"#(.*?)\"/g, (m: string, id: string) => {
return `xlink:href="#${normalizeId(prefix, id)}"`;
});
return xml;
}
2017-12-18 22:04:17 +01:00
export class ModuleView extends View implements LayoutElement {
2017-12-18 22:04:17 +01:00
protected content: SVGSVGElement;
protected controlShown: boolean;
protected opacity: number;
2017-12-18 22:04:17 +01:00
constructor(protected xml: string, protected prefix: string, protected id: NodeType, protected port: NodeType) {
super();
this.xml = normalizeXml(this.prefix, xml);
2017-12-18 22:04:17 +01:00
}
private normalizeXml(xml: string) {
return pxsim.visuals.normalizeXml(this.prefix, xml);
2017-12-18 22:04:17 +01:00
}
protected normalizeId(svgId: string) {
return `${this.prefix}-${svgId}`;
}
public getId() {
return this.id;
}
public getPort() {
return this.port;
}
public getPaddingRatio() {
return 0;
}
public getWiringRatio() {
return 0.5;
}
protected buildDom(): SVGElement {
2017-12-18 22:04:17 +01:00
this.content = svg.parseString(this.xml);
this.buildDomCore();
if (pxsim.inLightMode()) this.optimizeForLightMode();
2017-12-18 22:04:17 +01:00
this.attachEvents();
if (this.hasClick())
this.content.style.cursor = "pointer";
return this.content;
}
protected buildDomCore() {
}
protected optimizeForLightMode() {
}
2017-12-18 22:04:17 +01:00
public getInnerHeight() {
if (!this.content) {
return 0;
}
if (!this.content.hasAttribute("viewBox")) {
2018-04-10 01:24:01 +02:00
return this.getContentHeight();
2017-12-18 22:04:17 +01:00
}
return parseFloat(this.content.getAttribute("viewBox").split(" ")[3]);
}
public getInnerWidth() {
if (!this.content) {
return 0;
}
if (!this.content.hasAttribute("viewBox")) {
2018-04-10 01:24:01 +02:00
return this.getContentWidth();
2017-12-18 22:04:17 +01:00
}
return parseFloat(this.content.getAttribute("viewBox").split(" ")[2]);
}
2018-04-10 01:24:01 +02:00
public getContentHeight() {
if (!this.content) {
return 0;
}
return parseFloat(this.content.getAttribute("height"));
}
public getContentWidth() {
if (!this.content) {
return 0;
}
return parseFloat(this.content.getAttribute("width"));
}
2017-12-18 22:04:17 +01:00
public attachEvents() {
}
public resize(width: number, height: number, strict?: boolean) {
super.resize(width, height);
this.updateDimensions(width, height);
2017-12-18 22:04:17 +01:00
}
2018-04-10 01:24:01 +02:00
protected updateDimensions(width: number, height: number) {
2017-12-18 22:04:17 +01:00
if (this.content) {
const currentWidth = this.getInnerWidth();
const currentHeight = this.getInnerHeight();
const newHeight = currentHeight / currentWidth * width;
const newWidth = currentWidth / currentHeight * height;
2017-12-18 22:04:17 +01:00
this.content.setAttribute('width', `${width}`);
this.content.setAttribute('height', `${newHeight}`);
this.height = newHeight;
2017-12-18 22:04:17 +01:00
}
}
public hasClick() {
return true;
}
public setSelected(selected: boolean) {
super.setSelected(selected);
2017-12-18 22:04:17 +01:00
this.updateOpacity();
}
public updateState() {
this.updateOpacity();
}
2017-12-18 22:04:17 +01:00
protected updateOpacity() {
if (this.rendered) {
const opacity = this.selected && this.fadeWhenSelected() ? 0.2 : 1;
if (this.hasClick() && this.opacity != opacity) {
this.opacity = opacity;
this.setOpacity(this.opacity);
}
if (this.hasClick()) {
2017-12-18 22:04:17 +01:00
if (this.selected) this.content.style.cursor = "";
else this.content.style.cursor = "pointer";
}
}
}
protected fadeWhenSelected() {
return true;
}
protected setOpacity(opacity: number) {
this.element.setAttribute("opacity", `${opacity}`);
2017-12-18 22:04:17 +01:00
}
}
}