Skip to content

Commit

Permalink
Displaying labels on Virtual keyboard
Browse files Browse the repository at this point in the history
ref #534
  • Loading branch information
wilckerson authored Apr 19, 2024
1 parent aa10774 commit cd800e3
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 8 deletions.
46 changes: 46 additions & 0 deletions src/components/VirtualKeyInfo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<script setup lang="ts">
import { formatHertz, formatExponential, formatCents } from '@/utils'
const props = defineProps<{
label: string
cent: number
ratio: number
frequency: number
showLabel: boolean
showCent: boolean
showRatio: boolean
showFrequency: boolean
}>()
</script>

<template>
<div class="key-info">
<div v-if="props.showLabel">
<strong>{{ props.label }}</strong>
</div>
<div v-if="props.showCent">{{ formatCents(props.cent, 0) }}</div>
<div v-if="props.showRatio">{{ formatExponential(props.ratio) }}</div>
<div v-if="props.showFrequency">{{ formatHertz(props.frequency) }}</div>
</div>
</template>

<style scoped>
.key-info {
font-size: 1.25em;
text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.3);
}
[data-theme='dark'] .key-info {
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
}
.black-key .key-info {
color: white;
text-shadow: none;
}
.white-key .key-info {
color: black;
text-shadow: none;
}
</style>
45 changes: 40 additions & 5 deletions src/components/VirtualKeyboard.vue
Original file line number Diff line number Diff line change
@@ -1,42 +1,65 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
import VirtualKeyboardKey from '@/components/VirtualKeyboardKey.vue'
import { mmod } from 'xen-dev-utils'
import VirtualKeyInfo from '@/components/VirtualKeyInfo.vue'
type NoteOff = () => void
type NoteOnCallback = (index: number) => NoteOff
type ColorMap = (index: number) => string
type LabelMap = (index: number) => string
const props = defineProps<{
baseIndex: number // Should incorporate equave shift
baseMidiNote: number
keyColors: string[]
isomorphicHorizontal: number
isomorphicVertical: number
noteOn: NoteOnCallback
heldNotes: Map<number, number>
baseFrequency: number
frequencies: number[]
centss: number[]
colorMap: ColorMap
labelMap: LabelMap
showLabel: boolean
showCent: boolean
showRatio: boolean
showFrequency: boolean
}>()
type VirtualKey = {
x: number
y: number
index: number
color: string
frequency: number
cent: number
ratio: number
label: string
}
const virtualKeys = computed(() => {
const colors = props.keyColors.length ? props.keyColors : ['white']
const horizontal = props.isomorphicHorizontal
const vertical = props.isomorphicVertical
const result: [number, VirtualKey[]][] = []
const inverseBaseFreq = 1 / props.baseFrequency
for (let y = 3; y >= -1; y--) {
const row = []
for (let x = 0; x <= 12; ++x) {
const index = props.baseIndex + x * horizontal + y * vertical
const color = props.colorMap(index)
const frequency = props.frequencies[index]
const cent = props.centss[index]
const ratio = frequency * inverseBaseFreq
const label = props.labelMap(index)
row.push({
x,
y,
index,
color: colors[mmod(index - props.baseMidiNote - 1, colors.length)]
color,
frequency,
cent,
ratio,
label
})
}
result.push([y, row])
Expand All @@ -63,7 +86,18 @@ const isMousePressed = ref(false)
:noteOn="() => noteOn(key.index)"
@press="isMousePressed = true"
@unpress="isMousePressed = false"
></VirtualKeyboardKey>
>
<VirtualKeyInfo
:label="key.label"
:cent="key.cent"
:ratio="key.ratio"
:frequency="key.frequency"
:showLabel="props.showLabel"
:showCent="props.showCent"
:showRatio="props.showRatio"
:showFrequency="props.showFrequency"
/>
</VirtualKeyboardKey>
</tr>
</table>
</template>
Expand All @@ -75,5 +109,6 @@ table {
width: 100%;
height: 100%;
min-width: 500px; /* this stops the keys getting too close together for portrait mobile users */
table-layout: fixed;
}
</style>
6 changes: 4 additions & 2 deletions src/components/VirtualKeyboardKey.vue
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,17 @@ onUnmounted(() => {
<td
:data-key-number="index"
:style="'background-color:' + color"
:class="{ active }"
:class="{ active, 'black-key': color === 'black', 'white-key': color === 'white' }"
@touchstart="onTouchStart"
@touchend="onTouchEnd"
@touchcancel="onTouchEnd"
@mousedown="onMouseDown"
@mouseup="onMouseUp"
@mouseenter="onMouseEnter"
@mouseleave="onMouseLeave"
></td>
>
<slot></slot>
</td>
</template>

<style scoped>
Expand Down
12 changes: 12 additions & 0 deletions src/stores/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ export const useStateStore = defineStore('state', () => {
const centsFractionDigits = ref(parseInt(storage.getItem('centsFractionDigits') ?? '3', 10))
const decimalFractionDigits = ref(parseInt(storage.getItem('decimalFractionDigits') ?? '5', 10))
const showVirtualQwerty = ref(storage.getItem('showVirtualQwerty') === 'true')
const showKeyboardLabel = ref(storage.getItem('showKeyboardLabel') !== 'false')
const showKeyboardCents = ref(storage.getItem('showKeyboardCents') !== 'false')
const showKeyboardRatio = ref(storage.getItem('showKeyboardRatio') !== 'false')
const showKeyboardFrequency = ref(storage.getItem('showKeyboardFrequency') !== 'false')

// Analysis preferences
const intervalMatrixIndexing = ref(parseInt(storage.getItem('intervalMatrixIndexing') ?? '0', 10))
Expand All @@ -50,6 +54,10 @@ export const useStateStore = defineStore('state', () => {
centsFractionDigits,
decimalFractionDigits,
showVirtualQwerty,
showKeyboardLabel,
showKeyboardCents,
showKeyboardRatio,
showKeyboardFrequency,
intervalMatrixIndexing,
maxMatrixWidth,
calculateConstantStructureViolations,
Expand Down Expand Up @@ -84,6 +92,10 @@ export const useStateStore = defineStore('state', () => {
centsFractionDigits,
decimalFractionDigits,
showVirtualQwerty,
showKeyboardLabel,
showKeyboardCents,
showKeyboardRatio,
showKeyboardFrequency,
intervalMatrixIndexing,
maxMatrixWidth,
calculateConstantStructureViolations,
Expand Down
4 changes: 4 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,10 @@ export function autoKeyColors(size: number) {
return result
}

export function formatCents(x: number, fractionDigits = 3) {
return formatExponential(x, fractionDigits) + '¢'
}

/**
* Fill in the gaps of a parent scale (in white) with accidentals (in black).
* @param generatorPerPeriod Generator sizre divided by period size (in pitch space).
Expand Down
1 change: 1 addition & 0 deletions src/views/AboutView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const tagline = computed(() => TAGLINES[Math.floor(Math.random() * TAGLINES.leng
Forrest Cahoon - <i>developer</i> <br />
Videco - <i>developer</i> <br />
Inthar - <i>developer</i> <br />
Wilckerson Ganda - <i>developer</i> <br />
Marc Sabat - <i>developer / notation-hardware advisor</i> <br />
Kraig Grady - <i>lattice advisor</i> <br />
Abnormality - <i>quality assurance</i> <br />
Expand Down
25 changes: 25 additions & 0 deletions src/views/SynthView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,31 @@ onUnmounted(() => {
</div>
</template>
</div>
<template v-if="scale.keyboardMode === 'isomorphic'">
<h2>Keyboard notes</h2>
<div class="control-group" style="flex-direction: row; flex-wrap: wrap">
<div class="control checkbox-container">
<input id="keyboard-show-label" type="checkbox" v-model="state.showKeyboardLabel" />
<label for="keyboard-show-label">Display label</label>
</div>
<div class="control checkbox-container">
<input id="keyboard-show-cents" type="checkbox" v-model="state.showKeyboardCents" />
<label for="keyboard-show-cents">Display cents</label>
</div>
<div class="control checkbox-container">
<input id="keyboard-show-ratio" type="checkbox" v-model="state.showKeyboardRatio" />
<label for="keyboard-show-ratio">Display ratio</label>
</div>
<div class="control checkbox-container">
<input
id="keyboard-show-frequency"
type="checkbox"
v-model="state.showKeyboardFrequency"
/>
<label for="keyboard-show-frequency">Display frequency</label>
</div>
</div>
</template>
<template v-if="scale.keyboardMode === 'isomorphic'">
<h2>Isomorphic key mapping</h2>
<p>
Expand Down
10 changes: 9 additions & 1 deletion src/views/VirtualKeyboardView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,17 @@ type NoteOnCallback = (index: number) => NoteOff
:baseMidiNote="scale.scale.baseMidiNote"
:isomorphicHorizontal="state.isomorphicHorizontal"
:isomorphicVertical="state.isomorphicVertical"
:keyColors="scale.colors"
:colorMap="scale.colorForIndex"
:noteOn="noteOn"
:heldNotes="state.heldNotes"
:baseFrequency="scale.baseFrequency"
:frequencies="scale.frequencies"
:centss="scale.centss"
:labelMap="scale.labelForIndex"
:showLabel="state.showKeyboardLabel"
:showCent="state.showKeyboardCents"
:showRatio="state.showKeyboardRatio"
:showFrequency="state.showKeyboardFrequency"
></VirtualKeyboard>
</main>
</template>

0 comments on commit cd800e3

Please sign in to comment.