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:
@@ -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
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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:
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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]
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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].
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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.
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -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.
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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 {
|
||||||
@@ -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(
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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 —
|
||||||
@@ -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
|
||||||
@@ -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,
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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.
|
||||||
@@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -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) {
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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() },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
│
|
│
|
||||||
|
|||||||
Reference in New Issue
Block a user