var Editor: Editor = { elements: { container: document.querySelector('.edit'), appearence: { text: { content: document.querySelector('.ap_text_value'), size: document.querySelector('.ap_text_size'), color: document.querySelector('.ap_text_color'), offsetX: document.querySelector('.ap_text_offsetx').querySelector('input[type="range"]'), offsetY: document.querySelector('.ap_text_offsety').querySelector('input[type="range"]') }, background: { color: document.querySelector('.ap_background_color') }, image: { size: document.querySelector('.ap_image_size').querySelector('input[type="range"]'), offsetX: document.querySelector('.ap_image_offsetx').querySelector('input[type="range"]'), offsetY: document.querySelector('.ap_image_offsety').querySelector('input[type="range"]'), rotation: document.querySelector('.ap_image_rotation').querySelector('input[type="range"]') } }, imageui: { imagetypes: document.querySelector('.imagetype'), imageinfopanels: document.querySelector('.imagemenu').querySelector('.info'), imagepanels: document.querySelector('.row.image').querySelector('.panels'), advanced: document.querySelector('.row.image').querySelector('.advanced') }, buttonui: { buttontypes: document.querySelector('.buttontype'), visual: document.querySelector('.vis'), actioninner: document.querySelector('.actioninner'), containerTitles: document.querySelector('.editcontainer').querySelectorAll('.containertitle') }, checks: { toggle: { container: document.querySelector('.checks').querySelector('.check.toggle'), checkbox: document.querySelector('.checks').querySelector('.check.toggle').querySelector('input') }, confirm: { container: document.querySelector('.checks').querySelector('.check.confirm'), checkbox: document.querySelector('.checks').querySelector('.check.confirm').querySelector('input') } } }, currentX: null, currentY: null, currentKey: null, currentImageType: null, currentButtonType: null, isToggle: null, isConfirm: null, isOpen: false, registerChange() { if (Editor.currentKey != null) { var editorExport = Editor.export(); KeyHandler.render(Editor.currentX, Editor.currentY, editorExport); socket.emit( 'page', 'setkey', PageHandler.currentPageID, Editor.currentX, Editor.currentY, editorExport, responseToken ); } }, listeners() { for (var inputCategory in Editor.elements.appearence) { for (var inputName in Editor.elements.appearence[inputCategory]) { var inputElement: HTMLInputElement = Editor.elements.appearence[inputCategory][inputName]; inputElement.oninput = Editor.registerChange; if (inputElement.type == 'range') ((range: HTMLInputElement, number: HTMLInputElement) => { range.addEventListener('input', () => { number.value = range.value; }); number.addEventListener('input', () => { range.value = number.value; Editor.registerChange(); }); })(inputElement, inputElement.parentElement.querySelector('input[type="number"]')); } } Editor.elements.imageui.imagetypes.querySelectorAll('.selectoritem').forEach((item: HTMLDivElement) => { item.onclick = () => { var panelType: 'none' | 'icon' | 'upload' = item.getAttribute('panel'); Editor.selectImageTab(panelType); }; }); Editor.elements.buttonui.buttontypes.querySelectorAll('.buttonitem').forEach((item: HTMLDivElement) => { item.onclick = () => { var buttonType: 'empty' | 'custom' | 'pageup' | 'pagedown' = item.getAttribute('type'); Editor.selectButtonType(buttonType); }; }); Editor.elements.checks.toggle.container.onclick = () => Editor.setActionOptions(!Editor.elements.checks.toggle.checkbox.checked, Editor.isConfirm); Editor.elements.checks.confirm.container.onclick = () => Editor.setActionOptions(Editor.isToggle, !Editor.elements.checks.confirm.checkbox.checked); }, export(): Page_Key { if (Editor.isOpen) { return { id: Editor.currentKey.id, actions: Editor.currentKey.actions, state: { type: Editor.currentButtonType, confirm: Editor.isConfirm, toggle: Editor.isToggle }, appearence: { text: Editor.getElementCategoryValues('text'), background: Editor.getElementCategoryValues('background'), image: Editor.getElementCategoryValues('image') } }; } return null; }, open(x: string, y: string, key: Page_Key) { if (Editor.isOpen) Editor.close(); Editor.currentKey = key; Editor.currentX = x; Editor.currentY = y; Editor.isOpen = true; document.querySelectorAll('.actionselector').forEach((selector: HTMLInputElement) => { selector.value = ''; }); // --------- TEXT --------- { var textElems = Editor.elements.appearence.text; var textData: Page_Key_Text = Editor.getAppearenceCategory('text', key); textElems.content.value = textData.value != undefined ? textData.value : ''; textElems.size.value = textData.size != undefined ? String(textData.size) : '10'; textElems.color.value = textData.color != undefined ? textData.color : '#000000'; textElems.offsetX.value = textData.offsetX != undefined ? String(textData.offsetX) : '0'; var offsetXNumber: HTMLInputElement = textElems.offsetX.parentElement.querySelector('input[type="number"]'); offsetXNumber.value = textData.offsetX != undefined ? String(textData.offsetX) : '0'; textElems.offsetY.value = textData.offsetY != undefined ? String(textData.offsetY) : '0'; var offsetYNumber: HTMLInputElement = textElems.offsetY.parentElement.querySelector('input[type="number"]'); offsetYNumber.value = textData.offsetY != undefined ? String(textData.offsetY) : '0'; } // --------- BACKGROUND --------- { var backgroundElems = Editor.elements.appearence.background; var backgroundData: Page_Key_Background = Editor.getAppearenceCategory('background', key); backgroundElems.color.value = backgroundData.color != undefined ? backgroundData.color : '#000000'; } // --------- IMAGE --------- { var imageElems = Editor.elements.appearence.image; var imageData: Page_Key_Image = Editor.getAppearenceCategory('image', key); imageElems.size.value = imageData.size != undefined ? String(imageData.size) : '100'; var sizeNumber: HTMLInputElement = imageElems.size.parentElement.querySelector('input[type="number"]'); sizeNumber.value = imageData.size != undefined ? String(imageData.size) : '100'; imageElems.rotation.value = imageData.rotation != undefined ? String(imageData.rotation) : '0'; var rotationNumber: HTMLInputElement = imageElems.rotation.parentElement.querySelector( 'input[type="number"]' ); rotationNumber.value = imageData.rotation != undefined ? String(imageData.rotation) : '0'; imageElems.offsetX.value = imageData.offsetX != undefined ? String(imageData.offsetX) : '0'; var offsetXNumber: HTMLInputElement = imageElems.offsetX.parentElement.querySelector( 'input[type="number"]' ); offsetXNumber.value = imageData.offsetX != undefined ? String(imageData.offsetX) : '0'; imageElems.offsetY.value = imageData.offsetY != undefined ? String(imageData.offsetY) : '0'; var offsetYNumber: HTMLInputElement = imageElems.offsetY.parentElement.querySelector( 'input[type="number"]' ); offsetYNumber.value = imageData.offsetY != undefined ? String(imageData.offsetY) : '0'; } if (imageData.address != undefined) { Editor.selectImageTab('upload', true); } else if (imageData.iconid != undefined) { Editor.selectImageTab('icon', true); Icons.select(imageData.iconid); } Editor.selectButtonType(key.state.type, true); Editor.setActionOptions(key.state.toggle, key.state.confirm, true); var actions = key.actions != undefined ? key.actions : { up: {}, down: {} }; ActionEditor.open(actions, x, y, key, PageHandler.currentPageID); Editor.elements.container.classList.remove('disabled'); }, close() { Editor.isOpen = false; Editor.currentKey = null; Editor.currentX = null; Editor.currentY = null; document.querySelectorAll('.actionselector').forEach((selector: HTMLInputElement) => { selector.value = ''; }); var text = Editor.elements.appearence.text; text.content.value = 'Button'; text.size.value = '20'; text.color.value = '#ffffff'; var background = Editor.elements.appearence.background; background.color.value = '#000000'; Editor.elements.container.classList.add('disabled'); Editor.selectImageTab('none', true); ActionEditor.close(); Icons.deselect(); }, selectImageTab(panelType: 'none' | 'icon' | 'upload', ignoreUpdate = false) { Editor.elements.imageui.imagetypes.querySelectorAll('.selectoritem').forEach((selectoritem: HTMLDivElement) => { if (panelType == selectoritem.getAttribute('panel')) selectoritem.classList.add('selected'); else selectoritem.classList.remove('selected'); }); Editor.elements.imageui.imagepanels.querySelectorAll('.panel').forEach((panel: HTMLDivElement) => { if (panelType == panel.getAttribute('panel')) panel.classList.add('selected'); else panel.classList.remove('selected'); }); Editor.elements.imageui.imageinfopanels.querySelectorAll('.infopanel').forEach((infopanel: HTMLDivElement) => { if (panelType == infopanel.getAttribute('panel')) infopanel.classList.add('selected'); else infopanel.classList.remove('selected'); }); Editor.currentImageType = panelType != 'none' ? panelType : null; if (panelType == 'none') Editor.elements.imageui.advanced.style.display = 'none'; else Editor.elements.imageui.advanced.style.display = 'flex'; if (panelType == 'icon') Icons.loadOnScreen(); if (ignoreUpdate == false) Editor.registerChange(); }, selectButtonType(buttonType: KeyTypes, ignoreUpdate = false) { if (buttonType == 'ghost') buttonType = 'custom'; Editor.elements.buttonui.buttontypes.querySelectorAll('.buttonitem').forEach((selectoritem: HTMLDivElement) => { if (buttonType == selectoritem.getAttribute('type')) selectoritem.classList.add('selected'); else selectoritem.classList.remove('selected'); }); Editor.currentButtonType = buttonType; switch (buttonType) { case 'empty': case 'pageup': case 'pagedown': case 'currentpage': Editor.elements.buttonui.visual.style.display = 'none'; Editor.elements.buttonui.actioninner.style.display = 'none'; Editor.elements.buttonui.containerTitles.forEach((title) => (title.style.display = 'none')); break; case 'custom': Editor.elements.buttonui.visual.style.display = 'block'; Editor.elements.buttonui.actioninner.style.display = 'block'; Editor.elements.buttonui.containerTitles.forEach((title) => (title.style.display = 'flex')); break; } if (ignoreUpdate == false) Editor.registerChange(); }, setActionOptions(toggle: boolean, confirm: boolean, ignoreUpdate = false) { if (toggle) { ActionEditor.elements.up.container.style.display = 'none'; ActionEditor.elements.latch.container.style.display = 'block'; } else { ActionEditor.elements.up.container.style.display = 'block'; ActionEditor.elements.latch.container.style.display = 'none'; } if (confirm) { ActionEditor.elements.down.container.style.display = 'none'; } else { ActionEditor.elements.down.container.style.display = 'block'; } Editor.isToggle = toggle; Editor.isConfirm = confirm; Editor.elements.checks.toggle.checkbox.checked = toggle; Editor.elements.checks.confirm.checkbox.checked = confirm; if (ignoreUpdate == false) Editor.registerChange(); }, getAppearenceCategory(category: Editor_Categories, key: Page_Key = Editor.currentKey) { switch (category) { case 'text': var textData: Page_Key_Text = key.appearence != undefined && key.appearence.text != undefined ? key.appearence.text : { value: '', size: 10, color: '#000000', offsetX: 0, offsetY: 0 }; return textData; case 'background': var backgroundData: Page_Key_Background = key.appearence != undefined && key.appearence.background != undefined ? key.appearence.background : { color: '#000000' }; return backgroundData; case 'image': var imageData: Page_Key_Image = key.appearence != undefined && key.appearence.image != undefined ? key.appearence.image : { offsetX: 0, offsetY: 0, size: 100, rotation: 0 }; return imageData; } }, getElementCategoryValues(category: Editor_Categories) { switch (category) { case 'text': var textData: Page_Key_Text = { value: Editor.currentButtonType != 'empty' ? Editor.elements.appearence.text.content.value : '', color: Editor.currentButtonType != 'empty' ? Editor.elements.appearence.text.color.value : '#ffffff', size: Editor.currentButtonType != 'empty' ? parseInt(Editor.elements.appearence.text.size.value) : 20, offsetX: Editor.currentButtonType != 'empty' ? parseFloat(Editor.elements.appearence.text.offsetX.value) : 0, offsetY: Editor.currentButtonType != 'empty' ? parseFloat(Editor.elements.appearence.text.offsetY.value) : 0 }; return textData; case 'background': var backgroundData: Page_Key_Background = { color: Editor.currentButtonType != 'empty' ? Editor.elements.appearence.background.color.value : '#000000' }; return backgroundData; case 'image': var imageData: Page_Key_Image = { size: Editor.currentButtonType != 'empty' ? parseFloat(Editor.elements.appearence.image.size.value) : 100, rotation: Editor.currentButtonType != 'empty' ? parseFloat(Editor.elements.appearence.image.rotation.value) : 0, offsetX: Editor.currentButtonType != 'empty' ? parseFloat(Editor.elements.appearence.image.offsetX.value) : 0, offsetY: Editor.currentButtonType != 'empty' ? parseFloat(Editor.elements.appearence.image.offsetY.value) : 0 }; if (Editor.currentImageType != null && Editor.currentButtonType != 'empty') { switch (Editor.currentImageType) { case 'icon': imageData.iconid = Icons.currentSelected; imageData.iconstyle = 'white'; break; } } return imageData; } } }; Editor.listeners(); interface Editor { elements: { container: HTMLDivElement; appearence: { text: { content: HTMLInputElement; size: HTMLSelectElement; color: HTMLInputElement; offsetX: HTMLInputElement; offsetY: HTMLInputElement; }; background: { color: HTMLInputElement; }; image: { size: HTMLInputElement; offsetX: HTMLInputElement; offsetY: HTMLInputElement; rotation: HTMLInputElement; }; }; imageui: { imagetypes: HTMLDivElement; imageinfopanels: HTMLDivElement; imagepanels: HTMLDivElement; advanced: HTMLDivElement; }; buttonui: { buttontypes: HTMLDivElement; visual: HTMLDivElement; actioninner: HTMLDivElement; containerTitles: NodeListOf; }; checks: { toggle: { container: HTMLDivElement; checkbox: HTMLInputElement; }; confirm: { container: HTMLDivElement; checkbox: HTMLInputElement; }; }; }; isOpen: boolean; currentKey: Page_Key; currentX: string; currentY: string; currentImageType: 'icon' | 'upload'; currentButtonType: KeyTypes; isToggle: boolean; isConfirm: boolean; listeners: () => void; export: () => Page_Key; open: (x: string, y: string, key: Page_Key) => void; close: () => void; registerChange: () => void; selectImageTab: (panelType: string, ignoreUpdate?: boolean) => void; selectButtonType: (buttonType: KeyTypes, ignoreUpdate?: boolean) => void; setActionOptions: (toggle: boolean, confirm: boolean, ignoreUpdate?: boolean) => void; getAppearenceCategory: (category: Editor_Categories, key?: Page_Key) => any; getElementCategoryValues: (category: Editor_Categories) => any; } type Editor_Categories = 'text' | 'background' | 'image';