From a2ea957b2ce11f420448cf68adfd60e9f493379f Mon Sep 17 00:00:00 2001 From: Andrio Celos Date: Tue, 25 Oct 2022 14:39:47 +1100 Subject: [PATCH] Enhance list buttons style --- TableturfBattleClient/src/CardButton.ts | 23 ++++--------- TableturfBattleClient/src/CheckButton.ts | 32 +++++++++++++++++++ .../src/Pages/DeckListPage.ts | 22 +++++++------ TableturfBattleClient/src/Pages/GamePage.ts | 22 +++++++------ TableturfBattleClient/src/Pages/LobbyPage.ts | 28 ++++++++++------ TableturfBattleClient/tableturf.css | 32 ++++++++++++------- 6 files changed, 103 insertions(+), 56 deletions(-) create mode 100644 TableturfBattleClient/src/CheckButton.ts diff --git a/TableturfBattleClient/src/CardButton.ts b/TableturfBattleClient/src/CardButton.ts index b76ed00..7aed086 100644 --- a/TableturfBattleClient/src/CardButton.ts +++ b/TableturfBattleClient/src/CardButton.ts @@ -4,6 +4,7 @@ class CardButton { readonly element: HTMLLabelElement; readonly inputElement: HTMLInputElement; readonly card: Card; + readonly button: CheckButton; constructor(type: 'checkbox' | 'radio', card: Card) { this.card = card; @@ -84,24 +85,14 @@ class CardButton { el2.appendChild(el3); } + this.button = new CheckButton(checkBox); + CardButton.idNumber++; } - get enabled() { return !this.inputElement.disabled; } - set enabled(value: boolean) { - this.inputElement.disabled = !value; - if (value) - this.element.classList.remove('disabled'); - else - this.element.classList.add('disabled'); - } + get enabled() { return this.button.enabled; } + set enabled(value: boolean) { this.button.enabled = value; } - get checked() { return this.inputElement.checked; } - set checked(value: boolean) { - this.inputElement.checked = value; - if (this.inputElement.checked) - this.element.classList.add('checked'); - else - this.element.classList.remove('checked'); - } + get checked() { return this.button.checked; } + set checked(value: boolean) { this.button.checked = value; } } diff --git a/TableturfBattleClient/src/CheckButton.ts b/TableturfBattleClient/src/CheckButton.ts new file mode 100644 index 0000000..9428319 --- /dev/null +++ b/TableturfBattleClient/src/CheckButton.ts @@ -0,0 +1,32 @@ +class CheckButton { + readonly input: HTMLInputElement; + readonly label: HTMLLabelElement; + + constructor(input: HTMLInputElement) { + this.input = input; + this.label = input.labels![0]; + this.input.addEventListener('input', () => { + this.checked = this.input.checked; + }); + } + + static fromId(id: string) { return new CheckButton(document.getElementById(id) as HTMLInputElement); } + + get enabled() { return !this.input.disabled; } + set enabled(value: boolean) { + this.input.disabled = !value; + if (value) + this.label.classList.remove('disabled'); + else + this.label.classList.add('disabled'); + } + + get checked() { return this.input.checked; } + set checked(value: boolean) { + this.input.checked = value; + if (this.input.checked) + this.label.classList.add('checked'); + else + this.label.classList.remove('checked'); + } +} \ No newline at end of file diff --git a/TableturfBattleClient/src/Pages/DeckListPage.ts b/TableturfBattleClient/src/Pages/DeckListPage.ts index 28a33f4..20dfe14 100644 --- a/TableturfBattleClient/src/Pages/DeckListPage.ts +++ b/TableturfBattleClient/src/Pages/DeckListPage.ts @@ -24,12 +24,12 @@ const deckImportTextBox = document.getElementById('deckImportTextBox') as HTMLTe const deckImportErrorBox = document.getElementById('deckImportErrorBox')!; const deckImportOkButton = document.getElementById('deckImportOkButton') as HTMLButtonElement; +const deckButtons: CheckButton[] = [ ]; + function showDeckList() { showPage('deckList'); deselectDeck(); - for (const el of deckList.getElementsByTagName('input')) { - (el as HTMLInputElement).checked = false; - } + for (const button of deckButtons) button.checked = false; } deckListBackButton.addEventListener('click', e => { @@ -82,20 +82,24 @@ function saveDecks() { function createDeckButton(index: number, deck: Deck) { const label = document.createElement('label'); + const input = document.createElement('input'); - const button = document.createElement('input'); - button.name = 'selectedDeck'; - button.type = 'radio'; - button.dataset.index = index.toString(); - button.addEventListener('click', e => { + input.name = 'selectedDeck'; + input.type = 'radio'; + input.dataset.index = index.toString(); + input.addEventListener('click', e => { + for(const button2 of deckButtons) { + if (button2.input != input) button2.checked = false; + } selectedDeck = decks[parseInt((e.target as HTMLInputElement).dataset.index!)]; selectDeck(); }); - label.appendChild(button); + label.appendChild(input); label.appendChild(document.createTextNode(deck.name)); deckList.insertBefore(label, addDeckControls); + deckButtons.push(new CheckButton(input)); return label; } diff --git a/TableturfBattleClient/src/Pages/GamePage.ts b/TableturfBattleClient/src/Pages/GamePage.ts index 04d6f33..a7ed212 100644 --- a/TableturfBattleClient/src/Pages/GamePage.ts +++ b/TableturfBattleClient/src/Pages/GamePage.ts @@ -1,10 +1,12 @@ +/// + const gamePage = document.getElementById('gamePage')!; const board = new Board(document.getElementById('gameBoard') as HTMLTableElement); const turnNumberLabel = new TurnNumberLabel(document.getElementById('turnNumberContainer')!, document.getElementById('turnNumberLabel')!); const handButtons: CardButton[] = [ ]; -const passButton = document.getElementById('passButton') as HTMLInputElement; -const specialButton = document.getElementById('specialButton') as HTMLInputElement; +const passButton = CheckButton.fromId('passButton'); +const specialButton = CheckButton.fromId('specialButton'); const gameButtonsContainer = document.getElementById('gameButtonsContainer')!; const rotateLeftButton = document.getElementById('rotateLeftButton') as HTMLButtonElement; const rotateRightButton = document.getElementById('rotateRightButton') as HTMLButtonElement; @@ -83,7 +85,7 @@ function setupControlsForPlay() { board.specialAttack = false; board.cardPlaying = null; if (canPlay && currentGame?.me?.hand != null) { - passButton.disabled = false; + passButton.enabled = true; for (let i = 0; i < 4; i++) { canPlayCard[i] = board.canPlayCard(currentGame.me.playerIndex, currentGame.me.hand[i], false); @@ -92,14 +94,14 @@ function setupControlsForPlay() { handButtons[i].enabled = canPlayCard[i]; } - specialButton.disabled = !canPlayCardAsSpecialAttack.includes(true); + specialButton.enabled = canPlayCardAsSpecialAttack.includes(true); board.autoHighlight = true; } else { for (const button of handButtons) { button.enabled = false; - passButton.disabled = true; - specialButton.disabled = true; } + passButton.enabled = false; + specialButton.enabled = false; } } @@ -291,7 +293,7 @@ function passButton_input() { } } } -passButton.addEventListener('input', passButton_input); +passButton.input.addEventListener('input', passButton_input); function specialButton_input() { board.specialAttack = specialButton.checked; @@ -311,7 +313,7 @@ function specialButton_input() { } } } -specialButton.addEventListener('input', specialButton_input); +specialButton.input.addEventListener('input', specialButton_input); board.onclick = (x, y) => { if (board.cardPlaying == null || !currentGame?.me) @@ -395,7 +397,7 @@ document.addEventListener('keydown', e => { if (!pages.get('game')!.hidden) { switch (e.key) { case 'p': - if (!passButton.disabled) { + if (passButton.enabled) { passButton.checked = !passButton.checked; passButton_input(); focusFirstEnabledHandCard(); @@ -403,7 +405,7 @@ document.addEventListener('keydown', e => { e.preventDefault(); break; case 's': - if (!specialButton.disabled) { + if (specialButton.enabled) { specialButton.checked = !specialButton.checked; specialButton_input(); focusFirstEnabledHandCard(); diff --git a/TableturfBattleClient/src/Pages/LobbyPage.ts b/TableturfBattleClient/src/Pages/LobbyPage.ts index 0455bcf..ef44db1 100644 --- a/TableturfBattleClient/src/Pages/LobbyPage.ts +++ b/TableturfBattleClient/src/Pages/LobbyPage.ts @@ -13,6 +13,7 @@ const lobbySelectedStageSection = document.getElementById('lobbySelectedStageSec const lobbyStageSection = document.getElementById('lobbyStageSection')!; const lobbyDeckSection = document.getElementById('lobbyDeckSection')!; const lobbyDeckList = document.getElementById('lobbyDeckList')!; +const lobbyDeckButtons: CheckButton[] = [ ]; const qrCodeDialog = document.getElementById('qrCodeDialog') as HTMLDialogElement; let qrCode: QRCode | null; @@ -96,33 +97,40 @@ function initDeckSelection() { selectedDeck = null; if (currentGame?.me) { clearChildren(lobbyDeckList); + lobbyDeckButtons.splice(0); for (let i = 0; i < decks.length; i++) { const deck = decks[i]; const label = document.createElement('label'); - const button = document.createElement('input'); - button.name = 'gameSelectedDeck'; - button.type = 'radio'; - button.dataset.index = i.toString(); - button.addEventListener('click', () => { - selectedDeck = deck; - submitDeckButton.disabled = false; + const input = document.createElement('input'); + input.name = 'gameSelectedDeck'; + input.type = 'radio'; + input.dataset.index = i.toString(); + input.addEventListener('input', () => { + if (input.checked) { + for (const button of lobbyDeckButtons) { + if (button.input != input) button.checked = false; + } + selectedDeck = deck; + submitDeckButton.disabled = false; + } }); - label.appendChild(button); + label.appendChild(input); label.appendChild(document.createTextNode(deck.name)); if (!deck.isValid) { label.classList.add('disabled'); - button.disabled = true; + input.disabled = true; } else if (deck.name == lastDeckName) { selectedDeck = deck; - button.checked = true; + input.checked = true; } lobbyDeckList.appendChild(label); + lobbyDeckButtons.push(new CheckButton(input)); } submitDeckButton.disabled = selectedDeck == null; lobbyDeckSection.hidden = false; diff --git a/TableturfBattleClient/tableturf.css b/TableturfBattleClient/tableturf.css index b06a66b..247bd91 100644 --- a/TableturfBattleClient/tableturf.css +++ b/TableturfBattleClient/tableturf.css @@ -452,19 +452,18 @@ dialog::backdrop { margin: 0.5em; padding: 0 0.5em; text-align: center; - background: var(--special-colour-1); + background: var(--primary-colour-1); text-shadow: 0 0 4px black; border-radius: 0.5em; } #playControls > label input { - display: none; -} -#playControls > label.checked { - background: var(--special-accent-colour-1); -} -#playControls > label:disabled { - background: grey; + position: absolute; + left: -333px; } +#playControls > label:hover { background: var(--special-colour-1); } +#playControls > label:focus-within { outline: 2px solid var(--special-accent-colour-2); } +#playControls > label:is(:active, .checked) { background: var(--special-accent-colour-1); } +#playControls > label.disabled { background: grey; } .playContainer { text-align: center; } @@ -498,7 +497,7 @@ dialog::backdrop { width: 1.5em; height: 1.5em; } -#gameButtonsContainer button:hover { +#gameButtonsContainer button:is(:hover, :focus) { opacity: 1; } #gameButtonsContainer button:active { @@ -783,7 +782,6 @@ dialog::backdrop { } .deckList > label, #addDeckControls > button { - background: dimgrey; display: flex; justify-content: center; align-items: center; @@ -791,12 +789,18 @@ dialog::backdrop { color: inherit; font-size: inherit; border: inherit; + text-shadow: 0 0 4px black; } .deckList > * { width: 20rem; height: 3rem; margin: 0.5em; } +.deckList > label { background: var(--primary-colour-2); } +.deckList > label:hover { background: var(--special-colour-2); } +.deckList > label:focus-within { outline: 2px solid var(--special-accent-colour-2); } +.deckList > label:is(:active, .checked) { background: var(--special-accent-colour-2); } +.deckList > label.disabled { background: grey; } #addDeckControls { display: flex; align-items: stretch; @@ -804,7 +808,12 @@ dialog::backdrop { } #addDeckControls > button { flex-grow: 1; + background: black; + border: 0.25em solid var(--primary-colour-2); } +#addDeckControls > button:hover { border-color: var(--special-colour-2); } +#addDeckControls > button:focus-within { outline: 2px solid var(--special-accent-colour-2); } +#addDeckControls > button:is(:active, .checked) { border-color: var(--special-accent-colour-2); } .deckList { display: flex; @@ -812,7 +821,8 @@ dialog::backdrop { } .deckList input { - display: none; + position: absolute; + left: -333px; } .card.emptySlot {