Rename application identifier to space.rcmd.android.sizzle

Global rename of the app/package identifier from
com.reactorcoremeltdown.sizzletracker to space.rcmd.android.sizzle:

- build.gradle.kts: applicationId + namespace.
- Move the Kotlin source tree (main + test) and rewrite every package/import.
- native_audio.cpp: JNI symbol names (Java_space_rcmd_android_sizzle_...) so the
  Oboe callback still links against the relocated NativeAudioBridge.
- docs: package/file-map header.

The desktop-project GitHub URLs (github.com/reactorcoremeltdown/sizzletracker)
and the Reactorcoremeltdown copyright/SPDX author identity are intentionally left
unchanged. Note: the new applicationId installs as a separate package (existing
installs won't upgrade in place).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Reactorcoremeltdown
2026-07-17 18:59:51 +02:00
parent a5fdc7b6c4
commit 4bd8aac4d5
61 changed files with 289 additions and 289 deletions

View File

@@ -8,7 +8,7 @@ plugins {
} }
android { android {
namespace = "com.reactorcoremeltdown.sizzletracker" namespace = "space.rcmd.android.sizzle"
compileSdk = 34 compileSdk = 34
// Native (Oboe) low-latency output backend; see src/main/cpp. // Native (Oboe) low-latency output backend; see src/main/cpp.
@@ -17,7 +17,7 @@ android {
ndkVersion = "27.2.12479018" ndkVersion = "27.2.12479018"
defaultConfig { defaultConfig {
applicationId = "com.reactorcoremeltdown.sizzletracker" applicationId = "space.rcmd.android.sizzle"
// minSdk 26 (Android 8.0) is the floor for the native MIDI API // minSdk 26 (Android 8.0) is the floor for the native MIDI API
// (android.media.midi) and AAudio low-latency audio we rely on. // (android.media.midi) and AAudio low-latency audio we rely on.
minSdk = 26 minSdk = 26

View File

@@ -214,7 +214,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void * /*reserved*/) {
} }
extern "C" JNIEXPORT jboolean JNICALL extern "C" JNIEXPORT jboolean JNICALL
Java_com_reactorcoremeltdown_sizzletracker_audio_NativeAudioBridge_nativeStart( Java_space_rcmd_android_sizzle_audio_NativeAudioBridge_nativeStart(
JNIEnv *env, jobject /*thiz*/, jobject callback, jint sampleRate, jint framesPerCallback) { JNIEnv *env, jobject /*thiz*/, jobject callback, jint sampleRate, jint framesPerCallback) {
g_callback = env->NewGlobalRef(callback); g_callback = env->NewGlobalRef(callback);
jclass cls = env->GetObjectClass(callback); jclass cls = env->GetObjectClass(callback);
@@ -241,7 +241,7 @@ Java_com_reactorcoremeltdown_sizzletracker_audio_NativeAudioBridge_nativeStart(
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
Java_com_reactorcoremeltdown_sizzletracker_audio_NativeAudioBridge_nativeStop( Java_space_rcmd_android_sizzle_audio_NativeAudioBridge_nativeStop(
JNIEnv *env, jobject /*thiz*/) { JNIEnv *env, jobject /*thiz*/) {
g_wantRunning = false; // stop the disconnect-recovery from reopening g_wantRunning = false; // stop the disconnect-recovery from reopening
if (g_stream) { if (g_stream) {

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker package space.rcmd.android.sizzle
import android.Manifest import android.Manifest
import android.content.pm.PackageManager import android.content.pm.PackageManager
@@ -16,13 +16,13 @@ import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.initializer import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory import androidx.lifecycle.viewmodel.viewModelFactory
import com.reactorcoremeltdown.sizzletracker.input.GamepadInput import space.rcmd.android.sizzle.input.GamepadInput
import com.reactorcoremeltdown.sizzletracker.input.KeyboardInput import space.rcmd.android.sizzle.input.KeyboardInput
import com.reactorcoremeltdown.sizzletracker.input.MidiInput import space.rcmd.android.sizzle.input.MidiInput
import com.reactorcoremeltdown.sizzletracker.playback.PlaybackService import space.rcmd.android.sizzle.playback.PlaybackService
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel import space.rcmd.android.sizzle.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.SizzleApp as SizzleAppUi import space.rcmd.android.sizzle.ui.SizzleApp as SizzleAppUi
import com.reactorcoremeltdown.sizzletracker.ui.theme.SizzleTheme import space.rcmd.android.sizzle.ui.theme.SizzleTheme
/** /**
* The single Activity. Its jobs are narrow and clear: * The single Activity. Its jobs are narrow and clear:

View File

@@ -1,21 +1,21 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker package space.rcmd.android.sizzle
import android.app.Application import android.app.Application
import com.reactorcoremeltdown.sizzletracker.audio.AudioEngine import space.rcmd.android.sizzle.audio.AudioEngine
import com.reactorcoremeltdown.sizzletracker.input.BindingStore import space.rcmd.android.sizzle.input.BindingStore
import com.reactorcoremeltdown.sizzletracker.input.GamepadInput import space.rcmd.android.sizzle.input.GamepadInput
import com.reactorcoremeltdown.sizzletracker.input.InputRouter import space.rcmd.android.sizzle.input.InputRouter
import com.reactorcoremeltdown.sizzletracker.input.KeyboardInput import space.rcmd.android.sizzle.input.KeyboardInput
import com.reactorcoremeltdown.sizzletracker.input.MidiInput import space.rcmd.android.sizzle.input.MidiInput
import com.reactorcoremeltdown.sizzletracker.io.PresetLibrary import space.rcmd.android.sizzle.io.PresetLibrary
import com.reactorcoremeltdown.sizzletracker.io.ProjectStore import space.rcmd.android.sizzle.io.ProjectStore
import com.reactorcoremeltdown.sizzletracker.io.SettingsStore import space.rcmd.android.sizzle.io.SettingsStore
import com.reactorcoremeltdown.sizzletracker.io.SongLibrary import space.rcmd.android.sizzle.io.SongLibrary
import com.reactorcoremeltdown.sizzletracker.io.ThemeLibrary import space.rcmd.android.sizzle.io.ThemeLibrary
import com.reactorcoremeltdown.sizzletracker.model.Project import space.rcmd.android.sizzle.model.Project
import java.io.File import java.io.File
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking

View File

@@ -1,10 +1,10 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio package space.rcmd.android.sizzle.audio
import com.reactorcoremeltdown.sizzletracker.model.AmbiencePresets import space.rcmd.android.sizzle.model.AmbiencePresets
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot import space.rcmd.android.sizzle.model.ToolboxSlot
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.exp import kotlin.math.exp
import kotlin.math.floor import kotlin.math.floor

View File

@@ -1,18 +1,18 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio package space.rcmd.android.sizzle.audio
import android.media.AudioAttributes import android.media.AudioAttributes
import android.media.AudioFormat import android.media.AudioFormat
import android.media.AudioTrack import android.media.AudioTrack
import com.reactorcoremeltdown.sizzletracker.model.Arrangement import space.rcmd.android.sizzle.model.Arrangement
import com.reactorcoremeltdown.sizzletracker.model.Pattern import space.rcmd.android.sizzle.model.Pattern
import com.reactorcoremeltdown.sizzletracker.model.Project import space.rcmd.android.sizzle.model.Project
import com.reactorcoremeltdown.sizzletracker.model.SamplerPads import space.rcmd.android.sizzle.model.SamplerPads
import com.reactorcoremeltdown.sizzletracker.model.TimeDivision import space.rcmd.android.sizzle.model.TimeDivision
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot import space.rcmd.android.sizzle.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.model.ToolboxType import space.rcmd.android.sizzle.model.ToolboxType
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlin.concurrent.thread import kotlin.concurrent.thread
@@ -682,7 +682,7 @@ class AudioEngine(
* its own MIDI effects (Transposer shifts pitch; an Arpeggiator captures the * its own MIDI effects (Transposer shifts pitch; an Arpeggiator captures the
* note and hands retriggering to [advanceArps]). * note and hands retriggering to [advanceArps]).
*/ */
private fun triggerCell(proj: Project, lane: Int, cell: com.reactorcoremeltdown.sizzletracker.model.Cell) { private fun triggerCell(proj: Project, lane: Int, cell: space.rcmd.android.sizzle.model.Cell) {
for (bus in 0 until Pattern.TRACK_COUNT) { for (bus in 0 until Pattern.TRACK_COUNT) {
if (proj.mixer.channels[bus].midiChannel != cell.channel) continue if (proj.mixer.channels[bus].midiChannel != cell.channel) continue
val arp = arps[lane * Pattern.TRACK_COUNT + bus] val arp = arps[lane * Pattern.TRACK_COUNT + bus]

View File

@@ -1,11 +1,11 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio package space.rcmd.android.sizzle.audio
import com.reactorcoremeltdown.sizzletracker.model.DelayDivisions import space.rcmd.android.sizzle.model.DelayDivisions
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot import space.rcmd.android.sizzle.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.model.ToolboxType import space.rcmd.android.sizzle.model.ToolboxType
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.cos import kotlin.math.cos

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio package space.rcmd.android.sizzle.audio
import java.io.File import java.io.File
import java.io.RandomAccessFile import java.io.RandomAccessFile

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio package space.rcmd.android.sizzle.audio
/** /**
* Bridges the native Oboe (AAudio) output backend to the Kotlin [AudioEngine]. * Bridges the native Oboe (AAudio) output backend to the Kotlin [AudioEngine].

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio package space.rcmd.android.sizzle.audio
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.media.AudioFormat import android.media.AudioFormat

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio package space.rcmd.android.sizzle.audio
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.nio.ByteOrder import java.nio.ByteOrder

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio package space.rcmd.android.sizzle.audio
import kotlin.math.exp import kotlin.math.exp

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio package space.rcmd.android.sizzle.audio
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.nio.ByteOrder import java.nio.ByteOrder

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio package space.rcmd.android.sizzle.audio
/** /**
* One playing note (a "voice"). This is a deliberately simple NES/Famicom-style * One playing note (a "voice"). This is a deliberately simple NES/Famicom-style

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.audio package space.rcmd.android.sizzle.audio
/** /**
* A small, immutable snapshot of "where playback is" that the audio thread * A small, immutable snapshot of "where playback is" that the audio thread

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.input package space.rcmd.android.sizzle.input
import android.content.Context import android.content.Context
import androidx.datastore.core.DataStore import androidx.datastore.core.DataStore

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.input package space.rcmd.android.sizzle.input
import android.view.InputDevice import android.view.InputDevice
import android.view.KeyEvent import android.view.KeyEvent

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.input package space.rcmd.android.sizzle.input
/** /**
* The heart of the "four equal input methods" requirement. Touch, physical * The heart of the "four equal input methods" requirement. Touch, physical

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.input package space.rcmd.android.sizzle.input
/** /**
* The single source of truth mapping a stable action-id string to the neutral * The single source of truth mapping a stable action-id string to the neutral

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.input package space.rcmd.android.sizzle.input
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharedFlow

View File

@@ -1,10 +1,10 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.input package space.rcmd.android.sizzle.input
import android.view.KeyEvent import android.view.KeyEvent
import com.reactorcoremeltdown.sizzletracker.model.Pitch import space.rcmd.android.sizzle.model.Pitch
/** /**
* Translates physical (USB / Bluetooth) keyboard events into [InputAction]s. * Translates physical (USB / Bluetooth) keyboard events into [InputAction]s.

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.input package space.rcmd.android.sizzle.input
import android.content.Context import android.content.Context
import android.media.midi.MidiDeviceInfo import android.media.midi.MidiDeviceInfo

View File

@@ -1,10 +1,10 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io package space.rcmd.android.sizzle.io
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot import space.rcmd.android.sizzle.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.model.ToolboxType import space.rcmd.android.sizzle.model.ToolboxType
/** /**
* Reads and writes a single instrument/effect preset as plain, human-readable * Reads and writes a single instrument/effect preset as plain, human-readable

View File

@@ -1,14 +1,14 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io package space.rcmd.android.sizzle.io
import com.reactorcoremeltdown.sizzletracker.audio.SampleStore import space.rcmd.android.sizzle.audio.SampleStore
import com.reactorcoremeltdown.sizzletracker.model.AmbiencePresets import space.rcmd.android.sizzle.model.AmbiencePresets
import com.reactorcoremeltdown.sizzletracker.model.Project import space.rcmd.android.sizzle.model.Project
import com.reactorcoremeltdown.sizzletracker.model.SamplerPads import space.rcmd.android.sizzle.model.SamplerPads
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot import space.rcmd.android.sizzle.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.model.ToolboxType import space.rcmd.android.sizzle.model.ToolboxType
import java.io.File import java.io.File
import java.io.InputStream import java.io.InputStream
import java.util.zip.ZipEntry import java.util.zip.ZipEntry

View File

@@ -1,15 +1,15 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io package space.rcmd.android.sizzle.io
import com.reactorcoremeltdown.sizzletracker.model.Cell import space.rcmd.android.sizzle.model.Cell
import com.reactorcoremeltdown.sizzletracker.model.Mixer import space.rcmd.android.sizzle.model.Mixer
import com.reactorcoremeltdown.sizzletracker.model.Pattern import space.rcmd.android.sizzle.model.Pattern
import com.reactorcoremeltdown.sizzletracker.model.Project import space.rcmd.android.sizzle.model.Project
import com.reactorcoremeltdown.sizzletracker.model.Scale import space.rcmd.android.sizzle.model.Scale
import com.reactorcoremeltdown.sizzletracker.model.TimeSignature import space.rcmd.android.sizzle.model.TimeSignature
import com.reactorcoremeltdown.sizzletracker.model.ToolboxType import space.rcmd.android.sizzle.model.ToolboxType
/** /**
* Saves and loads a whole [Project] to/from the `.sng` text format. * Saves and loads a whole [Project] to/from the `.sng` text format.
@@ -87,7 +87,7 @@ object ProjectIo {
// Reset everything to a clean slate first. // Reset everything to a clean slate first.
project.patterns.clear() project.patterns.clear()
for (lane in project.arrangement.slots.indices) for (lane in project.arrangement.slots.indices)
project.arrangement.slots[lane].fill(com.reactorcoremeltdown.sizzletracker.model.Arrangement.EMPTY) project.arrangement.slots[lane].fill(space.rcmd.android.sizzle.model.Arrangement.EMPTY)
project.arrangement.laneMuted.fill(false) project.arrangement.laneMuted.fill(false)
project.toolbox.forEach { it.clearSlot() } project.toolbox.forEach { it.clearSlot() }
project.mixer.channels.forEach { ch -> project.mixer.channels.forEach { ch ->
@@ -119,7 +119,7 @@ object ProjectIo {
// are restored from the explicit lane,beat,pid lines regardless). // are restored from the explicit lane,beat,pid lines regardless).
project.arrangement.lengthBars = project.arrangement.lengthBars =
attrs["bars"]?.toIntOrNull() attrs["bars"]?.toIntOrNull()
?: com.reactorcoremeltdown.sizzletracker.model.Arrangement.MAX_BARS ?: space.rcmd.android.sizzle.model.Arrangement.MAX_BARS
project.arrangement.loopEnabled = attrs["loop"] == "1" project.arrangement.loopEnabled = attrs["loop"] == "1"
attrs["mutes"]?.let { m -> attrs["mutes"]?.let { m ->
val lanes = project.arrangement.laneMuted val lanes = project.arrangement.laneMuted
@@ -142,7 +142,7 @@ object ProjectIo {
} }
// Guarantee one block per lane (lane i is tied to block i), padding any // Guarantee one block per lane (lane i is tied to block i), padding any
// that the file did not define so the arrangement/editor always resolve. // that the file did not define so the arrangement/editor always resolve.
for (id in 0 until com.reactorcoremeltdown.sizzletracker.model.Arrangement.LANE_COUNT) { for (id in 0 until space.rcmd.android.sizzle.model.Arrangement.LANE_COUNT) {
if (project.patterns.none { it.id == id }) project.patterns.add(Pattern(id, name = "BLK${id + 1}")) if (project.patterns.none { it.id == id }) project.patterns.add(Pattern(id, name = "BLK${id + 1}"))
} }
project.patterns.sortBy { it.id } project.patterns.sortBy { it.id }
@@ -193,7 +193,7 @@ object ProjectIo {
p.arrangement.set(lane, beat, pid) p.arrangement.set(lane, beat, pid)
} }
private fun applyRegion(region: com.reactorcoremeltdown.sizzletracker.model.LoopRegion, a: Map<String, String>) { private fun applyRegion(region: space.rcmd.android.sizzle.model.LoopRegion, a: Map<String, String>) {
region.enabled = a["en"] == "1" region.enabled = a["en"] == "1"
region.start = a["s"]?.toIntOrNull() ?: 0 region.start = a["s"]?.toIntOrNull() ?: 0
region.end = a["e"]?.toIntOrNull() ?: 0 region.end = a["e"]?.toIntOrNull() ?: 0

View File

@@ -1,9 +1,9 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io package space.rcmd.android.sizzle.io
import com.reactorcoremeltdown.sizzletracker.model.Project import space.rcmd.android.sizzle.model.Project
import java.io.File import java.io.File
/** /**

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io package space.rcmd.android.sizzle.io
import android.content.Context import android.content.Context
import androidx.datastore.core.DataStore import androidx.datastore.core.DataStore
@@ -32,7 +32,7 @@ data class AppSettings(
* Persists app-level UI/audio settings (the colour theme and the low-latency * Persists app-level UI/audio settings (the colour theme and the low-latency
* engine toggle). Song/mixer/toolbox parameters live in the project and are * engine toggle). Song/mixer/toolbox parameters live in the project and are
* handled by [ProjectStore]; input bindings by * handled by [ProjectStore]; input bindings by
* [com.reactorcoremeltdown.sizzletracker.input.BindingStore]. * [space.rcmd.android.sizzle.input.BindingStore].
* *
* Audio output/input *device* selection is intentionally not persisted: Android * Audio output/input *device* selection is intentionally not persisted: Android
* device ids are session-scoped and don't identify the same hardware next launch. * device ids are session-scoped and don't identify the same hardware next launch.

View File

@@ -1,14 +1,14 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io package space.rcmd.android.sizzle.io
import com.reactorcoremeltdown.sizzletracker.model.Arrangement import space.rcmd.android.sizzle.model.Arrangement
import com.reactorcoremeltdown.sizzletracker.model.Cell import space.rcmd.android.sizzle.model.Cell
import com.reactorcoremeltdown.sizzletracker.model.Pattern import space.rcmd.android.sizzle.model.Pattern
import com.reactorcoremeltdown.sizzletracker.model.Pitch import space.rcmd.android.sizzle.model.Pitch
import com.reactorcoremeltdown.sizzletracker.model.Project import space.rcmd.android.sizzle.model.Project
import com.reactorcoremeltdown.sizzletracker.model.TimeSignature import space.rcmd.android.sizzle.model.TimeSignature
/** /**
* Reads and writes the reference desktop **sizzletracker `.sng`** format * Reads and writes the reference desktop **sizzletracker `.sng`** format

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io package space.rcmd.android.sizzle.io
import java.io.File import java.io.File

View File

@@ -1,10 +1,10 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io package space.rcmd.android.sizzle.io
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import com.reactorcoremeltdown.sizzletracker.ui.theme.RetroPalette import space.rcmd.android.sizzle.ui.theme.RetroPalette
/** /**
* Reads and writes a colour [RetroPalette] as plain, human-editable text the same * Reads and writes a colour [RetroPalette] as plain, human-editable text the same

View File

@@ -1,9 +1,9 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io package space.rcmd.android.sizzle.io
import com.reactorcoremeltdown.sizzletracker.ui.theme.RetroPalette import space.rcmd.android.sizzle.ui.theme.RetroPalette
import java.io.File import java.io.File
/** /**

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.model package space.rcmd.android.sizzle.model
/** /**
* Factory data for the [ToolboxType.AMBIENCE] reverb, ported from OTODESK's * Factory data for the [ToolboxType.AMBIENCE] reverb, ported from OTODESK's

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.model package space.rcmd.android.sizzle.model
/** /**
* The lower-half piano-roll arrangement. It has [LANE_COUNT] lanes stacked * The lower-half piano-roll arrangement. It has [LANE_COUNT] lanes stacked

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.model package space.rcmd.android.sizzle.model
/** /**
* The mixer has exactly [CHANNEL_COUNT] channels, one per tracker track. Each * The mixer has exactly [CHANNEL_COUNT] channels, one per tracker track. Each

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.model package space.rcmd.android.sizzle.model
/** /**
* Musical primitives shared across the whole app: pitches, scales and time * Musical primitives shared across the whole app: pitches, scales and time

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.model package space.rcmd.android.sizzle.model
/** /**
* One cell in the tracker grid: a single note event on a single line of a single * One cell in the tracker grid: a single note event on a single line of a single

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.model package space.rcmd.android.sizzle.model
/** /**
* The whole song in memory. This single object is what gets saved to / loaded * The whole song in memory. This single object is what gets saved to / loaded
@@ -9,7 +9,7 @@ package com.reactorcoremeltdown.sizzletracker.model
* Keeping one root object makes serialization and undo/redo straightforward. * Keeping one root object makes serialization and undo/redo straightforward.
* *
* Persistence is done by our own text serializer (see * Persistence is done by our own text serializer (see
* [com.reactorcoremeltdown.sizzletracker.io.ProjectIo]), not kotlinx, so the * [space.rcmd.android.sizzle.io.ProjectIo]), not kotlinx, so the
* model classes carry no serialization annotations. * model classes carry no serialization annotations.
*/ */
class Project { class Project {

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.model package space.rcmd.android.sizzle.model
/** /**
* The third tab is a toolbox of 16 slots. Every slot can hold one instrument OR * The third tab is a toolbox of 16 slots. Every slot can hold one instrument OR
@@ -273,7 +273,7 @@ enum class TimeDivision(val label: String, val beatFraction: Double) {
* sample file path live in the same map under keys the engine knows about * sample file path live in the same map under keys the engine knows about
* (e.g. "samplePath", "target"). * (e.g. "samplePath", "target").
* *
* (Serialized via [com.reactorcoremeltdown.sizzletracker.io.PresetIo], not * (Serialized via [space.rcmd.android.sizzle.io.PresetIo], not
* kotlinx, so no @Serializable annotation is needed here.) * kotlinx, so no @Serializable annotation is needed here.)
*/ */
class ToolboxSlot( class ToolboxSlot(

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.playback package space.rcmd.android.sizzle.playback
import android.os.Looper import android.os.Looper
import androidx.media3.common.MediaItem import androidx.media3.common.MediaItem
@@ -11,7 +11,7 @@ import androidx.media3.common.SimpleBasePlayer
import androidx.media3.common.util.UnstableApi import androidx.media3.common.util.UnstableApi
import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.ListenableFuture
import com.reactorcoremeltdown.sizzletracker.audio.AudioEngine import space.rcmd.android.sizzle.audio.AudioEngine
/** /**
* Adapts our custom [AudioEngine] to the media3 [Player] interface via * Adapts our custom [AudioEngine] to the media3 [Player] interface via

View File

@@ -1,14 +1,14 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.playback package space.rcmd.android.sizzle.playback
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import androidx.media3.common.util.UnstableApi import androidx.media3.common.util.UnstableApi
import androidx.media3.session.MediaSession import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService import androidx.media3.session.MediaSessionService
import com.reactorcoremeltdown.sizzletracker.SizzleApp import space.rcmd.android.sizzle.SizzleApp
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui package space.rcmd.android.sizzle.ui
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background import androidx.compose.foundation.background
@@ -29,11 +29,11 @@ import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import com.reactorcoremeltdown.sizzletracker.ui.mixer.MixerScreen import space.rcmd.android.sizzle.ui.mixer.MixerScreen
import com.reactorcoremeltdown.sizzletracker.ui.settings.SettingsScreen import space.rcmd.android.sizzle.ui.settings.SettingsScreen
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro import space.rcmd.android.sizzle.ui.theme.LocalRetro
import com.reactorcoremeltdown.sizzletracker.ui.toolbox.ToolboxScreen import space.rcmd.android.sizzle.ui.toolbox.ToolboxScreen
import com.reactorcoremeltdown.sizzletracker.ui.tracker.TrackerScreen import space.rcmd.android.sizzle.ui.tracker.TrackerScreen
/** /**
* The top-level layout: the active tab's screen fills the space above a standard * The top-level layout: the active tab's screen fills the space above a standard

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui package space.rcmd.android.sizzle.ui
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
@@ -10,15 +10,15 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.reactorcoremeltdown.sizzletracker.audio.AudioEngine import space.rcmd.android.sizzle.audio.AudioEngine
import com.reactorcoremeltdown.sizzletracker.input.InputAction import space.rcmd.android.sizzle.input.InputAction
import com.reactorcoremeltdown.sizzletracker.input.InputRouter import space.rcmd.android.sizzle.input.InputRouter
import com.reactorcoremeltdown.sizzletracker.model.Cell import space.rcmd.android.sizzle.model.Cell
import com.reactorcoremeltdown.sizzletracker.model.CellColumn import space.rcmd.android.sizzle.model.CellColumn
import com.reactorcoremeltdown.sizzletracker.model.Pattern import space.rcmd.android.sizzle.model.Pattern
import com.reactorcoremeltdown.sizzletracker.model.Pitch import space.rcmd.android.sizzle.model.Pitch
import com.reactorcoremeltdown.sizzletracker.model.Project import space.rcmd.android.sizzle.model.Project
import com.reactorcoremeltdown.sizzletracker.model.TimeSignature import space.rcmd.android.sizzle.model.TimeSignature
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
/** /**
@@ -36,14 +36,14 @@ class AppViewModel(
val project: Project, val project: Project,
private val engine: AudioEngine, private val engine: AudioEngine,
private val router: InputRouter, private val router: InputRouter,
private val gamepadInput: com.reactorcoremeltdown.sizzletracker.input.GamepadInput, private val gamepadInput: space.rcmd.android.sizzle.input.GamepadInput,
private val midiInput: com.reactorcoremeltdown.sizzletracker.input.MidiInput, private val midiInput: space.rcmd.android.sizzle.input.MidiInput,
private val keyboardInput: com.reactorcoremeltdown.sizzletracker.input.KeyboardInput, private val keyboardInput: space.rcmd.android.sizzle.input.KeyboardInput,
private val bindingStore: com.reactorcoremeltdown.sizzletracker.input.BindingStore, private val bindingStore: space.rcmd.android.sizzle.input.BindingStore,
private val presetLibrary: com.reactorcoremeltdown.sizzletracker.io.PresetLibrary, private val presetLibrary: space.rcmd.android.sizzle.io.PresetLibrary,
private val songLibrary: com.reactorcoremeltdown.sizzletracker.io.SongLibrary, private val songLibrary: space.rcmd.android.sizzle.io.SongLibrary,
private val settingsStore: com.reactorcoremeltdown.sizzletracker.io.SettingsStore, private val settingsStore: space.rcmd.android.sizzle.io.SettingsStore,
private val themeLibrary: com.reactorcoremeltdown.sizzletracker.io.ThemeLibrary, private val themeLibrary: space.rcmd.android.sizzle.io.ThemeLibrary,
private val appContext: android.content.Context, private val appContext: android.content.Context,
) : ViewModel() { ) : ViewModel() {
@@ -52,7 +52,7 @@ class AppViewModel(
var revision by mutableIntStateOf(0); private set // bump to force grid redraw var revision by mutableIntStateOf(0); private set // bump to force grid redraw
/** Active colour theme; read by [MainActivity] to drive SizzleTheme. Set via /** Active colour theme; read by [MainActivity] to drive SizzleTheme. Set via
* [selectPalette] so the choice is persisted. */ * [selectPalette] so the choice is persisted. */
var palette by mutableStateOf(com.reactorcoremeltdown.sizzletracker.ui.theme.RetroPalette.AMBER) var palette by mutableStateOf(space.rcmd.android.sizzle.ui.theme.RetroPalette.AMBER)
private set private set
// Tracker cursor position. // Tracker cursor position.
@@ -110,7 +110,7 @@ class AppViewModel(
// ----- Binding-learn state (Settings tab) ----- // ----- Binding-learn state (Settings tab) -----
/** The action id currently waiting to be bound, or null. */ /** The action id currently waiting to be bound, or null. */
var learnTarget by mutableStateOf<String?>(null); private set var learnTarget by mutableStateOf<String?>(null); private set
private var learnSource: com.reactorcoremeltdown.sizzletracker.input.InputSource? = null private var learnSource: space.rcmd.android.sizzle.input.InputSource? = null
init { init {
// Collect neutral input actions from every non-touch device. // Collect neutral input actions from every non-touch device.
@@ -444,7 +444,7 @@ class AppViewModel(
// ------------------------------------------------------- binding learn // ------------------------------------------------------- binding learn
/** Arm MIDI-learn / gamepad-rebind: the next matching control is bound to /** Arm MIDI-learn / gamepad-rebind: the next matching control is bound to
* [actionId]. [source] restricts which device kind will be captured. */ * [actionId]. [source] restricts which device kind will be captured. */
fun beginLearn(actionId: String, source: com.reactorcoremeltdown.sizzletracker.input.InputSource) { fun beginLearn(actionId: String, source: space.rcmd.android.sizzle.input.InputSource) {
learnTarget = actionId learnTarget = actionId
learnSource = source learnSource = source
router.learnSource = source router.learnSource = source
@@ -465,15 +465,15 @@ class AppViewModel(
val target = learnTarget ?: return val target = learnTarget ?: return
if (action.source != learnSource) return if (action.source != learnSource) return
when (action.source) { when (action.source) {
com.reactorcoremeltdown.sizzletracker.input.InputSource.MIDI -> space.rcmd.android.sizzle.input.InputSource.MIDI ->
midiInput.ccBindings[action.code] = target midiInput.ccBindings[action.code] = target
com.reactorcoremeltdown.sizzletracker.input.InputSource.GAMEPAD -> { space.rcmd.android.sizzle.input.InputSource.GAMEPAD -> {
gamepadInput.bindings.entries.removeAll { it.value == target } gamepadInput.bindings.entries.removeAll { it.value == target }
gamepadInput.bindings[ gamepadInput.bindings[
com.reactorcoremeltdown.sizzletracker.input.GamepadChord(action.modifier, action.code), space.rcmd.android.sizzle.input.GamepadChord(action.modifier, action.code),
] = target ] = target
} }
com.reactorcoremeltdown.sizzletracker.input.InputSource.KEYBOARD -> { space.rcmd.android.sizzle.input.InputSource.KEYBOARD -> {
keyboardInput.bindings.entries.removeAll { it.value == target } keyboardInput.bindings.entries.removeAll { it.value == target }
keyboardInput.bindings[action.code] = target keyboardInput.bindings[action.code] = target
} }
@@ -490,20 +490,20 @@ class AppViewModel(
/** Current gamepad chord (modifier + button, or plain button) bound to /** Current gamepad chord (modifier + button, or plain button) bound to
* [actionId], or null. */ * [actionId], or null. */
fun gamepadBindingFor(actionId: String): com.reactorcoremeltdown.sizzletracker.input.GamepadChord? = fun gamepadBindingFor(actionId: String): space.rcmd.android.sizzle.input.GamepadChord? =
gamepadInput.bindings.entries.firstOrNull { it.value == actionId }?.key gamepadInput.bindings.entries.firstOrNull { it.value == actionId }?.key
/** Current keyboard key code bound to [actionId], or null. */ /** Current keyboard key code bound to [actionId], or null. */
fun keyboardBindingFor(actionId: String): Int? = fun keyboardBindingFor(actionId: String): Int? =
keyboardInput.bindings.entries.firstOrNull { it.value == actionId }?.key keyboardInput.bindings.entries.firstOrNull { it.value == actionId }?.key
fun clearBinding(actionId: String, source: com.reactorcoremeltdown.sizzletracker.input.InputSource) { fun clearBinding(actionId: String, source: space.rcmd.android.sizzle.input.InputSource) {
when (source) { when (source) {
com.reactorcoremeltdown.sizzletracker.input.InputSource.MIDI -> space.rcmd.android.sizzle.input.InputSource.MIDI ->
midiInput.ccBindings.entries.removeAll { it.value == actionId } midiInput.ccBindings.entries.removeAll { it.value == actionId }
com.reactorcoremeltdown.sizzletracker.input.InputSource.GAMEPAD -> space.rcmd.android.sizzle.input.InputSource.GAMEPAD ->
gamepadInput.bindings.entries.removeAll { it.value == actionId } gamepadInput.bindings.entries.removeAll { it.value == actionId }
com.reactorcoremeltdown.sizzletracker.input.InputSource.KEYBOARD -> space.rcmd.android.sizzle.input.InputSource.KEYBOARD ->
keyboardInput.bindings.entries.removeAll { it.value == actionId } keyboardInput.bindings.entries.removeAll { it.value == actionId }
else -> {} else -> {}
} }
@@ -538,26 +538,26 @@ class AppViewModel(
/** Nudge an A/B loop region's repeat count and apply it to live playback /** Nudge an A/B loop region's repeat count and apply it to live playback
* immediately (without restarting the transport). */ * immediately (without restarting the transport). */
fun changeRegionRepeats(region: com.reactorcoremeltdown.sizzletracker.model.LoopRegion, delta: Int) { fun changeRegionRepeats(region: space.rcmd.android.sizzle.model.LoopRegion, delta: Int) {
region.repeats = (region.repeats + delta).coerceAtLeast(1) region.repeats = (region.repeats + delta).coerceAtLeast(1)
engine.refreshLoopPlaylist() engine.refreshLoopPlaylist()
touched() touched()
} }
// -------------------------------------------------------------- sampler // -------------------------------------------------------------- sampler
private val recorder = com.reactorcoremeltdown.sizzletracker.audio.SampleRecorder() private val recorder = space.rcmd.android.sizzle.audio.SampleRecorder()
var isRecording by mutableStateOf(false); private set var isRecording by mutableStateOf(false); private set
/** Decode a WAV and assign it to Sampler [slot]'s [pad] (from a file import). */ /** Decode a WAV and assign it to Sampler [slot]'s [pad] (from a file import). */
fun loadSampleInto( fun loadSampleInto(
slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, slot: space.rcmd.android.sizzle.model.ToolboxSlot,
pad: Int, pad: Int,
id: String, id: String,
bytes: ByteArray, bytes: ByteArray,
): Boolean { ): Boolean {
val sample = com.reactorcoremeltdown.sizzletracker.audio.SampleStore.decodeWav(bytes) ?: return false val sample = space.rcmd.android.sizzle.audio.SampleStore.decodeWav(bytes) ?: return false
com.reactorcoremeltdown.sizzletracker.audio.SampleStore.put(id, sample) space.rcmd.android.sizzle.audio.SampleStore.put(id, sample)
val pads = com.reactorcoremeltdown.sizzletracker.model.SamplerPads val pads = space.rcmd.android.sizzle.model.SamplerPads
slot.set(pads.key(pad), id) slot.set(pads.key(pad), id)
slot.set(pads.sliceStartKey(pad), 0f); slot.set(pads.sliceEndKey(pad), 1f) slot.set(pads.sliceStartKey(pad), 0f); slot.set(pads.sliceEndKey(pad), 1f)
touched() touched()
@@ -567,12 +567,12 @@ class AppViewModel(
/** Load an SF2 / XI (or WAV) file into a SoundFont [slot]: parse it, cache the /** Load an SF2 / XI (or WAV) file into a SoundFont [slot]: parse it, cache the
* extracted sample, and store its id + root note on the slot. */ * extracted sample, and store its id + root note on the slot. */
fun loadSoundFont( fun loadSoundFont(
slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, slot: space.rcmd.android.sizzle.model.ToolboxSlot,
id: String, id: String,
bytes: ByteArray, bytes: ByteArray,
): Boolean { ): Boolean {
val loaded = com.reactorcoremeltdown.sizzletracker.audio.SoundFontLoader.load(bytes) ?: return false val loaded = space.rcmd.android.sizzle.audio.SoundFontLoader.load(bytes) ?: return false
com.reactorcoremeltdown.sizzletracker.audio.SampleStore.put(id, loaded.sample) space.rcmd.android.sizzle.audio.SampleStore.put(id, loaded.sample)
slot.set("sfSample", id) slot.set("sfSample", id)
slot.set("sfRoot", loaded.rootNote.toFloat()) slot.set("sfRoot", loaded.rootNote.toFloat())
touched() touched()
@@ -585,9 +585,9 @@ class AppViewModel(
* and the markers reset to the full (new) sample. There is no undo re-import * and the markers reset to the full (new) sample. There is no undo re-import
* or re-record to start over. Returns false if there's nothing to trim. * or re-record to start over. Returns false if there's nothing to trim.
*/ */
fun trimSamplerPad(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, pad: Int): Boolean { fun trimSamplerPad(slot: space.rcmd.android.sizzle.model.ToolboxSlot, pad: Int): Boolean {
val pads = com.reactorcoremeltdown.sizzletracker.model.SamplerPads val pads = space.rcmd.android.sizzle.model.SamplerPads
val store = com.reactorcoremeltdown.sizzletracker.audio.SampleStore val store = space.rcmd.android.sizzle.audio.SampleStore
val sample = store.get(slot.string(pads.key(pad))) ?: return false val sample = store.get(slot.string(pads.key(pad))) ?: return false
val len = sample.data.size val len = sample.data.size
if (len <= 1) return false if (len <= 1) return false
@@ -598,7 +598,7 @@ class AppViewModel(
if (start == 0 && end == len) return false // slice already spans the whole sample if (start == 0 && end == len) return false // slice already spans the whole sample
// A fresh id so other pads sharing the original sample are left untouched. // A fresh id so other pads sharing the original sample are left untouched.
val id = "trim:" + System.nanoTime() val id = "trim:" + System.nanoTime()
store.put(id, com.reactorcoremeltdown.sizzletracker.audio.SampleStore.Sample( store.put(id, space.rcmd.android.sizzle.audio.SampleStore.Sample(
sample.data.copyOfRange(start, end), sample.sampleRate)) sample.data.copyOfRange(start, end), sample.sampleRate))
slot.set(pads.key(pad), id) slot.set(pads.key(pad), id)
slot.set(pads.sliceStartKey(pad), 0f) slot.set(pads.sliceStartKey(pad), 0f)
@@ -613,9 +613,9 @@ class AppViewModel(
* the same). No undo. Returns false if the pad is empty, silent, or already * the same). No undo. Returns false if the pad is empty, silent, or already
* normalized. * normalized.
*/ */
fun normalizeSamplerPad(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, pad: Int): Boolean { fun normalizeSamplerPad(slot: space.rcmd.android.sizzle.model.ToolboxSlot, pad: Int): Boolean {
val pads = com.reactorcoremeltdown.sizzletracker.model.SamplerPads val pads = space.rcmd.android.sizzle.model.SamplerPads
val store = com.reactorcoremeltdown.sizzletracker.audio.SampleStore val store = space.rcmd.android.sizzle.audio.SampleStore
val sample = store.get(slot.string(pads.key(pad))) ?: return false val sample = store.get(slot.string(pads.key(pad))) ?: return false
val data = sample.data val data = sample.data
if (data.isEmpty()) return false if (data.isEmpty()) return false
@@ -626,15 +626,15 @@ class AppViewModel(
if (gain in 0.999f..1.001f) return false // already at full scale if (gain in 0.999f..1.001f) return false // already at full scale
val out = FloatArray(data.size) { (data[it] * gain).coerceIn(-1f, 1f) } val out = FloatArray(data.size) { (data[it] * gain).coerceIn(-1f, 1f) }
val id = "norm:" + System.nanoTime() // fresh id so shared samples are untouched val id = "norm:" + System.nanoTime() // fresh id so shared samples are untouched
store.put(id, com.reactorcoremeltdown.sizzletracker.audio.SampleStore.Sample(out, sample.sampleRate)) store.put(id, space.rcmd.android.sizzle.audio.SampleStore.Sample(out, sample.sampleRate))
slot.set(pads.key(pad), id) slot.set(pads.key(pad), id)
touched() touched()
return true return true
} }
/** Clear the sample assigned to a Sampler [slot]'s [pad]. */ /** Clear the sample assigned to a Sampler [slot]'s [pad]. */
fun clearSamplerPad(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, pad: Int) { fun clearSamplerPad(slot: space.rcmd.android.sizzle.model.ToolboxSlot, pad: Int) {
val pads = com.reactorcoremeltdown.sizzletracker.model.SamplerPads val pads = space.rcmd.android.sizzle.model.SamplerPads
slot.values.remove(pads.key(pad)) slot.values.remove(pads.key(pad))
slot.values.remove(pads.sliceStartKey(pad)) slot.values.remove(pads.sliceStartKey(pad))
slot.values.remove(pads.sliceEndKey(pad)) slot.values.remove(pads.sliceEndKey(pad))
@@ -664,19 +664,19 @@ class AppViewModel(
fun dismissNativeAudioError() { nativeAudioError = null } fun dismissNativeAudioError() { nativeAudioError = null }
/** Choose the colour theme and persist the choice. */ /** Choose the colour theme and persist the choice. */
fun selectPalette(p: com.reactorcoremeltdown.sizzletracker.ui.theme.RetroPalette) { fun selectPalette(p: space.rcmd.android.sizzle.ui.theme.RetroPalette) {
palette = p palette = p
persistSettings() persistSettings()
} }
// ------------------------------------------------------------ colour themes // ------------------------------------------------------------ colour themes
private val stockThemes get() = com.reactorcoremeltdown.sizzletracker.ui.theme.RetroPalette.ALL private val stockThemes get() = space.rcmd.android.sizzle.ui.theme.RetroPalette.ALL
/** The two built-in themes are read-only and can never be deleted. */ /** The two built-in themes are read-only and can never be deleted. */
fun isStockTheme(name: String): Boolean = stockThemes.any { it.name == name } fun isStockTheme(name: String): Boolean = stockThemes.any { it.name == name }
/** Every selectable theme: the two stock themes followed by user themes. */ /** Every selectable theme: the two stock themes followed by user themes. */
fun allThemes(): List<com.reactorcoremeltdown.sizzletracker.ui.theme.RetroPalette> = fun allThemes(): List<space.rcmd.android.sizzle.ui.theme.RetroPalette> =
stockThemes + themeLibrary.loadAll() stockThemes + themeLibrary.loadAll()
/** All theme names for the selector dropdown (stock first, then user). */ /** All theme names for the selector dropdown (stock first, then user). */
@@ -705,7 +705,7 @@ class AppViewModel(
if (isStockTheme(name)) return false if (isStockTheme(name)) return false
val ok = themeLibrary.delete(name) val ok = themeLibrary.delete(name)
if (ok) { if (ok) {
if (palette.name == name) selectPalette(com.reactorcoremeltdown.sizzletracker.ui.theme.RetroPalette.AMBER) if (palette.name == name) selectPalette(space.rcmd.android.sizzle.ui.theme.RetroPalette.AMBER)
touched() touched()
} }
return ok return ok
@@ -759,13 +759,13 @@ class AppViewModel(
} }
/** Stop recording and assign the captured audio to Sampler [slot]'s [pad]. */ /** Stop recording and assign the captured audio to Sampler [slot]'s [pad]. */
fun stopRecordingInto(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, pad: Int) { fun stopRecordingInto(slot: space.rcmd.android.sizzle.model.ToolboxSlot, pad: Int) {
val sample = recorder.stop() val sample = recorder.stop()
isRecording = false isRecording = false
if (sample != null) { if (sample != null) {
val id = "rec-" + System.currentTimeMillis() val id = "rec-" + System.currentTimeMillis()
com.reactorcoremeltdown.sizzletracker.audio.SampleStore.put(id, sample) space.rcmd.android.sizzle.audio.SampleStore.put(id, sample)
val pads = com.reactorcoremeltdown.sizzletracker.model.SamplerPads val pads = space.rcmd.android.sizzle.model.SamplerPads
slot.set(pads.key(pad), id) slot.set(pads.key(pad), id)
slot.set(pads.sliceStartKey(pad), 0f); slot.set(pads.sliceEndKey(pad), 1f) slot.set(pads.sliceStartKey(pad), 0f); slot.set(pads.sliceEndKey(pad), 1f)
touched() touched()
@@ -775,7 +775,7 @@ class AppViewModel(
/** Point an LFO slot at another device's parameter, capturing that param's /** Point an LFO slot at another device's parameter, capturing that param's
* current value as the modulation centre. Pass targetSlotIndex < 0 to clear. */ * current value as the modulation centre. Pass targetSlotIndex < 0 to clear. */
fun setLfoTarget( fun setLfoTarget(
lfoSlot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, lfoSlot: space.rcmd.android.sizzle.model.ToolboxSlot,
targetSlotIndex: Int, targetSlotIndex: Int,
key: String, key: String,
) { ) {
@@ -791,7 +791,7 @@ class AppViewModel(
} }
/** Preview a note of the Sampler slot's loaded sample (one-shot, editor use). */ /** Preview a note of the Sampler slot's loaded sample (one-shot, editor use). */
fun auditionSample(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, midi: Int) { fun auditionSample(slot: space.rcmd.android.sizzle.model.ToolboxSlot, midi: Int) {
engine.auditionSlotOn(slot.index, midi) engine.auditionSlotOn(slot.index, midi)
} }
@@ -803,18 +803,18 @@ class AppViewModel(
// ------------------------------------------------------------ project I/O // ------------------------------------------------------------ project I/O
/** Serialize the current song to `.sng` text. */ /** Serialize the current song to `.sng` text. */
fun saveProjectText(): String = fun saveProjectText(): String =
com.reactorcoremeltdown.sizzletracker.io.ProjectIo.save(project) space.rcmd.android.sizzle.io.ProjectIo.save(project)
/** Replace the current song's contents from our full internal text (in place). */ /** Replace the current song's contents from our full internal text (in place). */
fun loadProjectText(text: String) { fun loadProjectText(text: String) {
com.reactorcoremeltdown.sizzletracker.io.ProjectIo.loadInto(project, text) space.rcmd.android.sizzle.io.ProjectIo.loadInto(project, text)
cursorLine = 0; cursorTrack = 0 cursorLine = 0; cursorTrack = 0
touched() touched()
} }
/** Export to the reference desktop sizzletracker `.sng` format (musical data). */ /** Export to the reference desktop sizzletracker `.sng` format (musical data). */
fun exportSng(): String = fun exportSng(): String =
com.reactorcoremeltdown.sizzletracker.io.SngFormat.export(project) space.rcmd.android.sizzle.io.SngFormat.export(project)
/** Import a reference `.sng` file (in place). Returns false if the text doesn't /** Import a reference `.sng` file (in place). Returns false if the text doesn't
* look like a `.sng` (so the caller can surface a popup) rather than silently * look like a `.sng` (so the caller can surface a popup) rather than silently
@@ -823,7 +823,7 @@ class AppViewModel(
val looksLikeSng = Regex("(?m)^\\s*(version|bpm|sig|block)\\b").containsMatchIn(text) val looksLikeSng = Regex("(?m)^\\s*(version|bpm|sig|block)\\b").containsMatchIn(text)
if (!looksLikeSng) return false if (!looksLikeSng) return false
runCatching { runCatching {
com.reactorcoremeltdown.sizzletracker.io.SngFormat.importInto(project, text) space.rcmd.android.sizzle.io.SngFormat.importInto(project, text)
}.getOrElse { return false } }.getOrElse { return false }
cursorLine = 0; cursorTrack = 0 cursorLine = 0; cursorTrack = 0
touched() touched()
@@ -854,7 +854,7 @@ class AppViewModel(
*/ */
fun newProject() { fun newProject() {
engine.stop() engine.stop()
loadProjectText(com.reactorcoremeltdown.sizzletracker.io.ProjectIo.save(Project())) loadProjectText(space.rcmd.android.sizzle.io.ProjectIo.save(Project()))
project.name = "untitled" project.name = "untitled"
engine.rebuildFxChains() // all FX routing was cleared engine.rebuildFxChains() // all FX routing was cleared
} }
@@ -882,11 +882,11 @@ class AppViewModel(
// ------------------------------------------------------ instrument/effect presets // ------------------------------------------------------ instrument/effect presets
/** Preset names available for a device type (for the editor's browser dropdown). */ /** Preset names available for a device type (for the editor's browser dropdown). */
fun presetNames(type: com.reactorcoremeltdown.sizzletracker.model.ToolboxType): List<String> = fun presetNames(type: space.rcmd.android.sizzle.model.ToolboxType): List<String> =
presetLibrary.list(type) presetLibrary.list(type)
/** Save [slot] as a named preset in the library. Returns the preset file. */ /** Save [slot] as a named preset in the library. Returns the preset file. */
fun savePreset(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, name: String): java.io.File { fun savePreset(slot: space.rcmd.android.sizzle.model.ToolboxSlot, name: String): java.io.File {
val file = presetLibrary.save(slot, name) val file = presetLibrary.save(slot, name)
touched() touched()
return file return file
@@ -894,7 +894,7 @@ class AppViewModel(
/** Load a named preset for [slot]'s current type into it. The slot is renamed to /** Load a named preset for [slot]'s current type into it. The slot is renamed to
* the preset so the toolbox tile and mixer inserts read as the loaded sound. */ * the preset so the toolbox tile and mixer inserts read as the loaded sound. */
fun loadPreset(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, name: String): Boolean { fun loadPreset(slot: space.rcmd.android.sizzle.model.ToolboxSlot, name: String): Boolean {
val type = slot.type ?: return false val type = slot.type ?: return false
val ok = presetLibrary.load(slot, type, name) val ok = presetLibrary.load(slot, type, name)
if (ok) { slot.name = name; engine.rebuildFxChains(); touched() } if (ok) { slot.name = name; engine.rebuildFxChains(); touched() }
@@ -902,7 +902,7 @@ class AppViewModel(
} }
/** Import a preset from picked bytes: a `.zip` bundle (Sampler) or plain text. */ /** Import a preset from picked bytes: a `.zip` bundle (Sampler) or plain text. */
fun importPreset(slot: com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot, bytes: ByteArray): Boolean { fun importPreset(slot: space.rcmd.android.sizzle.model.ToolboxSlot, bytes: ByteArray): Boolean {
val isZip = bytes.size >= 2 && bytes[0] == 'P'.code.toByte() && bytes[1] == 'K'.code.toByte() val isZip = bytes.size >= 2 && bytes[0] == 'P'.code.toByte() && bytes[1] == 'K'.code.toByte()
val ok = if (isZip) presetLibrary.importZip(slot, java.io.ByteArrayInputStream(bytes)) val ok = if (isZip) presetLibrary.importZip(slot, java.io.ByteArrayInputStream(bytes))
else presetLibrary.importText(slot, String(bytes, Charsets.UTF_8)) else presetLibrary.importText(slot, String(bytes, Charsets.UTF_8))
@@ -911,11 +911,11 @@ class AppViewModel(
} }
/** A shareable file for a stored preset (a zip bundle for the Sampler). */ /** A shareable file for a stored preset (a zip bundle for the Sampler). */
fun presetShareFile(type: com.reactorcoremeltdown.sizzletracker.model.ToolboxType, name: String): java.io.File? = fun presetShareFile(type: space.rcmd.android.sizzle.model.ToolboxType, name: String): java.io.File? =
presetLibrary.bundleForShare(type, name) presetLibrary.bundleForShare(type, name)
/** Delete a stored preset (and, for the Sampler, its bundled sample). */ /** Delete a stored preset (and, for the Sampler, its bundled sample). */
fun deletePreset(type: com.reactorcoremeltdown.sizzletracker.model.ToolboxType, name: String): Boolean { fun deletePreset(type: space.rcmd.android.sizzle.model.ToolboxType, name: String): Boolean {
val ok = presetLibrary.delete(type, name) val ok = presetLibrary.delete(type, name)
if (ok) touched() if (ok) touched()
return ok return ok

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui package space.rcmd.android.sizzle.ui
import android.content.res.Configuration import android.content.res.Configuration
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui package space.rcmd.android.sizzle.ui
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitEachGesture import androidx.compose.foundation.gestures.awaitEachGesture
@@ -26,11 +26,11 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.Pitch import space.rcmd.android.sizzle.model.Pitch
import com.reactorcoremeltdown.sizzletracker.ui.components.PianoKey import space.rcmd.android.sizzle.ui.components.PianoKey
import com.reactorcoremeltdown.sizzletracker.ui.components.PianoOctave import space.rcmd.android.sizzle.ui.components.PianoOctave
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroButton import space.rcmd.android.sizzle.ui.components.RetroButton
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro import space.rcmd.android.sizzle.ui.theme.LocalRetro
private const val VEL_STEP = 8 private const val VEL_STEP = 8

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.components package space.rcmd.android.sizzle.ui.components
import androidx.compose.ui.text.TextLayoutResult import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.TextMeasurer import androidx.compose.ui.text.TextMeasurer

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.components package space.rcmd.android.sizzle.ui.components
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
@@ -23,7 +23,7 @@ import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro import space.rcmd.android.sizzle.ui.theme.LocalRetro
/** /**
* Lays out one octave as a real piano keyboard: seven white keys across the bottom * Lays out one octave as a real piano keyboard: seven white keys across the bottom

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.components package space.rcmd.android.sizzle.ui.components
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
@@ -26,7 +26,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro import space.rcmd.android.sizzle.ui.theme.LocalRetro
/** /**
* A tiny library of "pixel" UI building blocks. They are intentionally plain * A tiny library of "pixel" UI building blocks. They are intentionally plain

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.mixer package space.rcmd.android.sizzle.ui.mixer
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
@@ -34,15 +34,15 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.Mixer import space.rcmd.android.sizzle.model.Mixer
import com.reactorcoremeltdown.sizzletracker.model.MixerChannel import space.rcmd.android.sizzle.model.MixerChannel
import com.reactorcoremeltdown.sizzletracker.model.ToolboxKind import space.rcmd.android.sizzle.model.ToolboxKind
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel import space.rcmd.android.sizzle.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.isLandscape import space.rcmd.android.sizzle.ui.isLandscape
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroButton import space.rcmd.android.sizzle.ui.components.RetroButton
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroDropdown import space.rcmd.android.sizzle.ui.components.RetroDropdown
import com.reactorcoremeltdown.sizzletracker.ui.components.SectionLabel import space.rcmd.android.sizzle.ui.components.SectionLabel
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro import space.rcmd.android.sizzle.ui.theme.LocalRetro
/** /**
* The second tab: a four-channel mixer, one strip per tracker track. Each strip * The second tab: a four-channel mixer, one strip per tracker track. Each strip

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.settings package space.rcmd.android.sizzle.ui.settings
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -60,10 +60,10 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import com.reactorcoremeltdown.sizzletracker.input.GamepadChord import space.rcmd.android.sizzle.input.GamepadChord
import com.reactorcoremeltdown.sizzletracker.input.GamepadInput import space.rcmd.android.sizzle.input.GamepadInput
import com.reactorcoremeltdown.sizzletracker.input.InputSource import space.rcmd.android.sizzle.input.InputSource
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel import space.rcmd.android.sizzle.ui.AppViewModel
/** /**
* The fourth tab, built from STANDARD Material 3 components (Cards, Buttons, * The fourth tab, built from STANDARD Material 3 components (Cards, Buttons,

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.theme package space.rcmd.android.sizzle.ui.theme
import android.app.Activity import android.app.Activity
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.toolbox package space.rcmd.android.sizzle.ui.toolbox
import androidx.compose.foundation.Canvas import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background import androidx.compose.foundation.background
@@ -25,11 +25,11 @@ import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.DelayDivisions import space.rcmd.android.sizzle.model.DelayDivisions
import com.reactorcoremeltdown.sizzletracker.model.ParamSpec import space.rcmd.android.sizzle.model.ParamSpec
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot import space.rcmd.android.sizzle.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel import space.rcmd.android.sizzle.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro import space.rcmd.android.sizzle.ui.theme.LocalRetro
/** /**
* The Tape Delay's custom editor: four tape heads side by side, each a vertical * The Tape Delay's custom editor: four tape heads side by side, each a vertical

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.toolbox package space.rcmd.android.sizzle.ui.toolbox
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@@ -13,10 +13,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot import space.rcmd.android.sizzle.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel import space.rcmd.android.sizzle.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroDropdown import space.rcmd.android.sizzle.ui.components.RetroDropdown
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro import space.rcmd.android.sizzle.ui.theme.LocalRetro
/** /**
* A modulation target: a numeric parameter on another device the LFO can drive. * A modulation target: a numeric parameter on another device the LFO can drive.

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.toolbox package space.rcmd.android.sizzle.ui.toolbox
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@@ -13,11 +13,11 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.ParamSpec import space.rcmd.android.sizzle.model.ParamSpec
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot import space.rcmd.android.sizzle.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel import space.rcmd.android.sizzle.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroDropdown import space.rcmd.android.sizzle.ui.components.RetroDropdown
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro import space.rcmd.android.sizzle.ui.theme.LocalRetro
import kotlin.math.roundToInt import kotlin.math.roundToInt
/** /**

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.toolbox package space.rcmd.android.sizzle.ui.toolbox
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
@@ -37,13 +37,13 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.audio.SampleStore import space.rcmd.android.sizzle.audio.SampleStore
import com.reactorcoremeltdown.sizzletracker.model.Pitch import space.rcmd.android.sizzle.model.Pitch
import com.reactorcoremeltdown.sizzletracker.model.SamplerPads import space.rcmd.android.sizzle.model.SamplerPads
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot import space.rcmd.android.sizzle.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel import space.rcmd.android.sizzle.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroButton import space.rcmd.android.sizzle.ui.components.RetroButton
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro import space.rcmd.android.sizzle.ui.theme.LocalRetro
import kotlin.math.abs import kotlin.math.abs
/** /**

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.toolbox package space.rcmd.android.sizzle.ui.toolbox
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
@@ -38,20 +38,20 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.audio.SampleStore import space.rcmd.android.sizzle.audio.SampleStore
import com.reactorcoremeltdown.sizzletracker.model.Pitch import space.rcmd.android.sizzle.model.Pitch
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot import space.rcmd.android.sizzle.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel import space.rcmd.android.sizzle.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.components.PianoKey import space.rcmd.android.sizzle.ui.components.PianoKey
import com.reactorcoremeltdown.sizzletracker.ui.components.PianoOctave import space.rcmd.android.sizzle.ui.components.PianoOctave
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroButton import space.rcmd.android.sizzle.ui.components.RetroButton
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro import space.rcmd.android.sizzle.ui.theme.LocalRetro
/** /**
* The SoundFont device editor: load an `.sf2` / `.xi` (or `.wav`) file from local * The SoundFont device editor: load an `.sf2` / `.xi` (or `.wav`) file from local
* storage, preview its waveform, set output volume, and audition it pitched across * storage, preview its waveform, set output volume, and audition it pitched across
* a two-octave keyboard. The extracted sample plays across the whole keyboard from * a two-octave keyboard. The extracted sample plays across the whole keyboard from
* the file's root note (see [com.reactorcoremeltdown.sizzletracker.audio.SoundFontLoader]). * the file's root note (see [space.rcmd.android.sizzle.audio.SoundFontLoader]).
*/ */
@Composable @Composable
fun SoundFontEditor(vm: AppViewModel, slot: ToolboxSlot) { fun SoundFontEditor(vm: AppViewModel, slot: ToolboxSlot) {

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.toolbox package space.rcmd.android.sizzle.ui.toolbox
import android.content.Intent import android.content.Intent
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
@@ -54,14 +54,14 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import com.reactorcoremeltdown.sizzletracker.model.ParamSpec import space.rcmd.android.sizzle.model.ParamSpec
import com.reactorcoremeltdown.sizzletracker.model.ToolboxSlot import space.rcmd.android.sizzle.model.ToolboxSlot
import com.reactorcoremeltdown.sizzletracker.model.ToolboxType import space.rcmd.android.sizzle.model.ToolboxType
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel import space.rcmd.android.sizzle.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.isLandscape import space.rcmd.android.sizzle.ui.isLandscape
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroButton import space.rcmd.android.sizzle.ui.components.RetroButton
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroDropdown import space.rcmd.android.sizzle.ui.components.RetroDropdown
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro import space.rcmd.android.sizzle.ui.theme.LocalRetro
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
/** /**
@@ -104,7 +104,7 @@ fun ToolboxScreen(vm: AppViewModel) {
ToolboxTileGrid(vm, selected, onTapTile, onDoubleTapTile, onLongPressTile, ToolboxTileGrid(vm, selected, onTapTile, onDoubleTapTile, onLongPressTile,
Modifier.weight(1f).fillMaxHeight()) Modifier.weight(1f).fillMaxHeight())
Box(Modifier.width(2.dp).fillMaxHeight().background(c.accent)) Box(Modifier.width(2.dp).fillMaxHeight().background(c.accent))
com.reactorcoremeltdown.sizzletracker.ui.StackedKeyboard(vm, punchIn = false, Modifier.weight(1.3f)) space.rcmd.android.sizzle.ui.StackedKeyboard(vm, punchIn = false, Modifier.weight(1.3f))
} }
} else { } else {
// Portrait: a scrolling grid of square tiles above the keyboard (1.7 : 1). // Portrait: a scrolling grid of square tiles above the keyboard (1.7 : 1).
@@ -126,7 +126,7 @@ fun ToolboxScreen(vm: AppViewModel) {
} }
} }
Box(Modifier.fillMaxWidth().height(2.dp).background(c.accent)) // fixed divider Box(Modifier.fillMaxWidth().height(2.dp).background(c.accent)) // fixed divider
com.reactorcoremeltdown.sizzletracker.ui.StackedKeyboard(vm, punchIn = false, Modifier.weight(1f)) space.rcmd.android.sizzle.ui.StackedKeyboard(vm, punchIn = false, Modifier.weight(1f))
} }
} }
@@ -373,7 +373,7 @@ private val AMBIENCE_SECTIONS = listOf(
* the presets saved for this device type, plus Save (to the app's on-disk preset * the presets saved for this device type, plus Save (to the app's on-disk preset
* library), Import (from a picked text preset or for the Sampler a `.zip` * library), Import (from a picked text preset or for the Sampler a `.zip`
* bundle), and Share (via the system share sheet). Presets are the plain-text * bundle), and Share (via the system share sheet). Presets are the plain-text
* [com.reactorcoremeltdown.sizzletracker.io.PresetIo] format, stored one folder * [space.rcmd.android.sizzle.io.PresetIo] format, stored one folder
* per instrument/effect. * per instrument/effect.
*/ */
@Composable @Composable

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.tracker package space.rcmd.android.sizzle.ui.tracker
import androidx.compose.foundation.Canvas import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background import androidx.compose.foundation.background
@@ -42,12 +42,12 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.rememberTextMeasurer import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.Arrangement as ArrModel import space.rcmd.android.sizzle.model.Arrangement as ArrModel
import com.reactorcoremeltdown.sizzletracker.model.LoopRegion import space.rcmd.android.sizzle.model.LoopRegion
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel import space.rcmd.android.sizzle.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.components.GlyphCache import space.rcmd.android.sizzle.ui.components.GlyphCache
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroButton import space.rcmd.android.sizzle.ui.components.RetroButton
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro import space.rcmd.android.sizzle.ui.theme.LocalRetro
/** /**
* The lower-half arrangement. Layout (spreadsheet-style, like the sizzletracker * The lower-half arrangement. Layout (spreadsheet-style, like the sizzletracker

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.tracker package space.rcmd.android.sizzle.ui.tracker
import androidx.compose.foundation.Canvas import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background import androidx.compose.foundation.background
@@ -23,13 +23,13 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.rememberTextMeasurer import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.Cell import space.rcmd.android.sizzle.model.Cell
import com.reactorcoremeltdown.sizzletracker.model.CellColumn import space.rcmd.android.sizzle.model.CellColumn
import com.reactorcoremeltdown.sizzletracker.model.Pattern import space.rcmd.android.sizzle.model.Pattern
import com.reactorcoremeltdown.sizzletracker.model.Pitch import space.rcmd.android.sizzle.model.Pitch
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel import space.rcmd.android.sizzle.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.components.GlyphCache import space.rcmd.android.sizzle.ui.components.GlyphCache
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro import space.rcmd.android.sizzle.ui.theme.LocalRetro
/** /**
* The demoscene pattern grid, drawn as ONE [Canvas] instead of a tree of ~180 * The demoscene pattern grid, drawn as ONE [Canvas] instead of a tree of ~180

View File

@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.ui.tracker package space.rcmd.android.sizzle.ui.tracker
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.horizontalScroll
@@ -28,12 +28,12 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.reactorcoremeltdown.sizzletracker.model.TimeSignature import space.rcmd.android.sizzle.model.TimeSignature
import com.reactorcoremeltdown.sizzletracker.ui.AppViewModel import space.rcmd.android.sizzle.ui.AppViewModel
import com.reactorcoremeltdown.sizzletracker.ui.isLandscape import space.rcmd.android.sizzle.ui.isLandscape
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroButton import space.rcmd.android.sizzle.ui.components.RetroButton
import com.reactorcoremeltdown.sizzletracker.ui.components.RetroDropdown import space.rcmd.android.sizzle.ui.components.RetroDropdown
import com.reactorcoremeltdown.sizzletracker.ui.theme.LocalRetro import space.rcmd.android.sizzle.ui.theme.LocalRetro
/** /**
* The first tab. Two stacked halves: * The first tab. Two stacked halves:
@@ -54,7 +54,7 @@ fun TrackerScreen(vm: AppViewModel) {
private fun TrackerLower(vm: AppViewModel, modifier: Modifier) { private fun TrackerLower(vm: AppViewModel, modifier: Modifier) {
Box(modifier) { Box(modifier) {
if (vm.punchInMode) { if (vm.punchInMode) {
com.reactorcoremeltdown.sizzletracker.ui.StackedKeyboard(vm, punchIn = true, Modifier.fillMaxSize()) space.rcmd.android.sizzle.ui.StackedKeyboard(vm, punchIn = true, Modifier.fillMaxSize())
} else { } else {
ArrangementRoll(vm) ArrangementRoll(vm)
} }
@@ -188,7 +188,7 @@ private fun PatternButtons(vm: AppViewModel) {
) )
RetroDropdown( RetroDropdown(
label = "SCALE", label = "SCALE",
options = com.reactorcoremeltdown.sizzletracker.model.Scale.entries, options = space.rcmd.android.sizzle.model.Scale.entries,
selected = project.scale, selected = project.scale,
optionLabel = { it.label }, optionLabel = { it.label },
onSelect = { project.scale = it; vm.bumpForToolbar() }, onSelect = { project.scale = it; vm.bumpForToolbar() },
@@ -197,7 +197,7 @@ private fun PatternButtons(vm: AppViewModel) {
label = "ROOT", label = "ROOT",
options = (0..11).toList(), options = (0..11).toList(),
selected = project.rootNote, selected = project.rootNote,
optionLabel = { com.reactorcoremeltdown.sizzletracker.model.Pitch.name(60 + it).dropLast(1) }, optionLabel = { space.rcmd.android.sizzle.model.Pitch.name(60 + it).dropLast(1) },
onSelect = { project.rootNote = it; vm.bumpForToolbar() }, onSelect = { project.rootNote = it; vm.bumpForToolbar() },
) )
} }

View File

@@ -1,12 +1,12 @@
// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown // SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
package com.reactorcoremeltdown.sizzletracker.io package space.rcmd.android.sizzle.io
import com.reactorcoremeltdown.sizzletracker.model.Arrangement import space.rcmd.android.sizzle.model.Arrangement
import com.reactorcoremeltdown.sizzletracker.model.Pitch import space.rcmd.android.sizzle.model.Pitch
import com.reactorcoremeltdown.sizzletracker.model.Project import space.rcmd.android.sizzle.model.Project
import com.reactorcoremeltdown.sizzletracker.model.TimeSignature import space.rcmd.android.sizzle.model.TimeSignature
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue

View File

@@ -84,7 +84,7 @@ Three ideas hold it together:
## 4. Package/file map ## 4. Package/file map
``` ```
com.reactorcoremeltdown.sizzletracker space.rcmd.android.sizzle
├── SizzleApp.kt Application = tiny DI container (Project, InputRouter, AudioEngine) ├── SizzleApp.kt Application = tiny DI container (Project, InputRouter, AudioEngine)
├── MainActivity.kt Hosts Compose UI; forwards HW key/motion events; starts MIDI + service ├── MainActivity.kt Hosts Compose UI; forwards HW key/motion events; starts MIDI + service