let devices be removed

This commit is contained in:
Rachel Powers
2024-04-17 19:22:43 -07:00
parent 651a4ad067
commit c4a11bf696
5 changed files with 140 additions and 18 deletions

View File

@@ -28,6 +28,9 @@ export const defaultCss = [
.mt-auto {
margin-top: auto !important;
}
.me-2 {
margin-right: 2rem !important;
}
.hstack {
display: flex;
flex-direction: row;
@@ -36,6 +39,9 @@ export const defaultCss = [
display: flex;
flex-direction: column;
}
.flex-g {
flex-grow: 1;
}
`,
];

View File

@@ -44,6 +44,7 @@ import SlSelect from "@shoelace-style/shoelace/dist/components/select/select.js"
import SlDrawer from "@shoelace-style/shoelace/dist/components/drawer/drawer.js";
import { DeviceDB, DeviceDBEntry } from "./device_db";
import { connectionFromDeviceDBConnection } from "./utils";
import { SlDialog } from "@shoelace-style/shoelace";
@customElement("vm-device-card")
export class VMDeviceCard extends VMDeviceMixin(BaseElement) {
@@ -74,6 +75,7 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) {
.header {
display: flex;
flex-direction: row;
flex-grow: 1;
}
.header-name {
display: flex;
@@ -130,6 +132,24 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) {
max-height: 20rem;
overflow-y: auto;
}
sl-icon-button.remove-button::part(base) {
color: var(--sl-color-danger-600);
}
sl-icon-button.remove-button::part(base):hover,
sl-icon-button.remove-button::part(base):focus {
color: var(--sl-color-danger-500);
}
sl-icon-button.remove-button::part(base):active {
color: var(--sl-color-danger-600);
}
.remove-dialog-body {
display: flex;
flex-direction: row;
}
.dialog-image {
width: 3rem;
height: 3rem;
}
`,
];
@@ -163,6 +183,7 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) {
renderHeader(): HTMLTemplateResult {
const activeIc = window.VM?.activeIC;
const thisIsActiveIc = activeIc.id === this.deviceID;
const badges: HTMLTemplateResult[] = [];
if (this.deviceID == activeIc?.id) {
badges.push(html`<sl-badge variant="primary" pill pulse>db</sl-badge>`);
@@ -197,6 +218,11 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) {
</sl-input>
${badges.map((badge) => badge)}
</div>
<div class="ms-auto mt-auto mb-auto me-2">
<sl-tooltip content=${thisIsActiveIc ? "Removing the selected Active IC is disabled" : "Remove Device"}>
<sl-icon-button class="remove-button" name="trash" label="Remove Device" ?disabled=${thisIsActiveIc} @click=${this._handleDeviceRemoveButton}></sl-icon-button>
</sl-tooltip>
</div>
`;
}
@@ -354,14 +380,42 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) {
<sl-tab-panel name="pins">${this.renderPins()}</sl-tab-panel>
</sl-tab-group>
</ic10-details>
<sl-dialog class="remove-device-dialog" no-header @sl-request-close=${this._preventOverlayClose}>
<div class="remove-dialog-body">
<img class="dialog-image mt-auto mb-auto me-2" src="img/stationpedia/${this.prefabName}.png"
onerror="this.src = '${VMDeviceCard.transparentImg}'" />
<div class="flex-g">
<p><strong>Are you sure you want to remove this device?</strong></p>
<span>Id ${this.deviceID} : ${this.name ?? this.prefabName}</span>
</div>
</div>
<div slot="footer">
<sl-button variant="primary" autofocus @click=${this._closeRemoveDialog}>Close</sl-button>
<sl-button variant="danger" @click=${this._removeDialogRemove}>Remove</sl-button>
</div>
</sl-dialog>
`;
}
@query(".remove-device-dialog") removeDialog: SlDialog;
_preventOverlayClose(event: CustomEvent) {
if (event.detail.source === 'overlay') {
event.preventDefault();
}
}
_closeRemoveDialog() {
this.removeDialog.hide()
}
_handleChangeID(e: CustomEvent) {
const input = e.target as SlInput;
const val = parseIntWithHexOrBinary(input.value);
if (!isNaN(val)) {
window.VM.changeDeviceId(this.deviceID, val);
if (!window.VM.changeDeviceId(this.deviceID, val)) {
input.value = this.deviceID.toString();
}
} else {
input.value = this.deviceID.toString();
}
@@ -370,7 +424,9 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) {
_handleChangeName(e: CustomEvent) {
const input = e.target as SlInput;
const name = input.value.length === 0 ? undefined : input.value;
window.VM?.setDeviceName(this.deviceID, name);
if (!window.VM?.setDeviceName(this.deviceID, name)) {
input.value = this.name;
};
this.updateDevice();
}
@@ -391,6 +447,15 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) {
this.updateDevice();
}
_handleDeviceRemoveButton(_e: Event) {
this.removeDialog.show()
}
_removeDialogRemove() {
this.removeDialog.hide()
window.VM.removeDevice(this.deviceID)
}
_handleChangeConnection(e: CustomEvent) {
const select = e.target as SlSelect;
const conn = parseInt(select.getAttribute("key")!);

View File

@@ -116,7 +116,7 @@ class VirtualMachine extends EventTarget {
if (update_flag) {
const ids = Array.from(device_ids);
ids.sort()
ids.sort();
this.dispatchEvent(
new CustomEvent("vm-devices-update", {
detail: ids,
@@ -132,8 +132,8 @@ class VirtualMachine extends EventTarget {
const ic = this._ics.get(id);
const prog = progs.get(id);
if (ic && prog) {
console.time(`CompileProgram_${id}_${attempt}`);
try {
console.time(`CompileProgram_${id}_${attempt}`);
this.ics.get(id)!.setCodeInvalid(progs.get(id)!);
const compiled = this.ics.get(id)?.program!;
window.App?.session.setProgramErrors(id, compiled.errors);
@@ -142,8 +142,9 @@ class VirtualMachine extends EventTarget {
);
} catch (err) {
this.handleVmError(err);
} finally{
console.timeEnd(`CompileProgram_${id}_${attempt}`);
}
console.timeEnd(`CompileProgram_${id}_${attempt}`);
}
}
this.update();
@@ -220,49 +221,59 @@ class VirtualMachine extends EventTarget {
this.dispatchEvent(new CustomEvent("vm-message", { detail: message }));
}
changeDeviceId(old_id: number, new_id: number) {
changeDeviceId(old_id: number, new_id: number): boolean {
try {
this.ic10vm.changeDeviceId(old_id, new_id);
this.updateDevices();
if (window.App.session.activeIC === old_id) {
window.App.session.activeIC = new_id;
}
return true;
} catch (err) {
this.handleVmError(err);
return false;
}
}
setRegister(index: number, val: number) {
setRegister(index: number, val: number): boolean {
const ic = this.activeIC!;
try {
ic.setRegister(index, val);
this.updateDevice(ic);
return true;
} catch (err) {
this.handleVmError(err);
return false;
}
}
setStack(addr: number, val: number) {
setStack(addr: number, val: number): boolean {
const ic = this.activeIC!;
try {
ic!.setStack(addr, val);
this.updateDevice(ic);
return true;
} catch (err) {
this.handleVmError(err);
return false;
}
}
setDeviceName(id: number, name: string): boolean {
const device = this._devices.get(id);
if (device) {
device.setName(name);
this.dispatchEvent(new CustomEvent("vm-device-modified", { detail: id }));
return true;
try {
device.setName(name);
this.dispatchEvent(new CustomEvent("vm-device-modified", { detail: id }));
return true;
} catch(e) {
this.handleVmError(e);
}
}
return false;
}
setDeviceField(id: number, field: string, val: number) {
setDeviceField(id: number, field: string, val: number): boolean {
const device = this._devices.get(id);
if (device) {
try {
@@ -276,7 +287,7 @@ class VirtualMachine extends EventTarget {
return false;
}
setDeviceSlotField(id: number, slot: number, field: string, val: number) {
setDeviceSlotField(id: number, slot: number, field: string, val: number): boolean {
const device = this._devices.get(id);
if (device) {
try {
@@ -290,29 +301,32 @@ class VirtualMachine extends EventTarget {
return false;
}
setDeviceConnection(id: number, conn: number, val: number | undefined) {
setDeviceConnection(id: number, conn: number, val: number | undefined): boolean {
const device = this._devices.get(id);
if (typeof device !== "undefined") {
try {
this.ic10vm.setDeviceConnection(id, conn, val);
this.updateDevice(device);
return true
} catch (err) {
this.handleVmError(err);
}
}
return false
}
setDevicePin(id: number, pin: number, val: number | undefined) {
setDevicePin(id: number, pin: number, val: number | undefined): boolean {
const device = this._devices.get(id);
if (typeof device !== "undefined") {
try {
this.ic10vm.setPin(id, pin, val)
this.ic10vm.setPin(id, pin, val);
this.updateDevice(device);
return true;
} catch (err) {
this.handleVmError(err);
}
}
return false;
}
setupDeviceDatabase(db: DeviceDB) {
@@ -323,7 +337,7 @@ class VirtualMachine extends EventTarget {
);
}
addDeviceFromTemplate(template: DeviceTemplate) {
addDeviceFromTemplate(template: DeviceTemplate): boolean {
try {
console.log("adding device", template);
const id = this.ic10vm.addDeviceFromTemplate(template);
@@ -334,8 +348,21 @@ class VirtualMachine extends EventTarget {
detail: Array.from(device_ids),
}),
);
return true;
} catch (err) {
this.handleVmError(err);
return false;
}
}
removeDevice(id: number): boolean {
try {
this.ic10vm.removeDevice(id);
this.updateDevices();
return true;
} catch (err) {
this.handleVmError(err);
return false;
}
}
}