Skip to content

Commit b3d3bf0

Browse files
authored
Add files via upload
1 parent a278ad2 commit b3d3bf0

20 files changed

Lines changed: 280238 additions & 161 deletions

AppSettings.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,19 +673,26 @@ struct AppSettings
673673
// Window positions/sizes (persisted as "x y w h" strings, empty = default)
674674
juce::String mainWindowBounds;
675675
juce::String pdlViewBounds;
676+
juce::String slqViewBounds;
676677
juce::String trackMapBounds;
677678
juce::String mixerMapBounds;
678679

679680
// PDL View layout state
680681
bool pdlViewHorizontal = false;
681682
bool pdlViewShowMixer = true;
682683

684+
// SLQ View layout state
685+
bool slqViewHorizontal = false;
686+
683687
// Per-engine settings
684688
std::vector<EngineSettings> engines;
685689

686690
// Which engine tab was selected
687691
int selectedEngine = 0;
688692

693+
// Show Mode lock -- prevents accidental changes during live shows
694+
bool showModeLocked = false;
695+
689696
// Track map (Track ID -> timecode offset mapping)
690697
TrackMap trackMap;
691698

@@ -709,14 +716,17 @@ struct AppSettings
709716
obj->setProperty("preferredSampleRate", preferredSampleRate);
710717
obj->setProperty("preferredBufferSize", preferredBufferSize);
711718
obj->setProperty("selectedEngine", selectedEngine);
719+
obj->setProperty("showModeLocked", showModeLocked);
712720
obj->setProperty("proDJLinkInterface", proDJLinkInterface);
713721

714722
if (mainWindowBounds.isNotEmpty()) obj->setProperty("mainWindowBounds", mainWindowBounds);
715723
if (pdlViewBounds.isNotEmpty()) obj->setProperty("pdlViewBounds", pdlViewBounds);
724+
if (slqViewBounds.isNotEmpty()) obj->setProperty("slqViewBounds", slqViewBounds);
716725
if (trackMapBounds.isNotEmpty()) obj->setProperty("trackMapBounds", trackMapBounds);
717726
if (mixerMapBounds.isNotEmpty()) obj->setProperty("mixerMapBounds", mixerMapBounds);
718727
obj->setProperty("pdlViewHorizontal", pdlViewHorizontal);
719728
obj->setProperty("pdlViewShowMixer", pdlViewShowMixer);
729+
obj->setProperty("slqViewHorizontal", slqViewHorizontal);
720730

721731
juce::Array<juce::var> engineArray;
722732
for (auto& eng : engines)
@@ -761,14 +771,20 @@ struct AppSettings
761771
preferredSampleRate = getDouble("preferredSampleRate", 0.0);
762772
preferredBufferSize = getInt("preferredBufferSize", 0);
763773
selectedEngine = getInt("selectedEngine", 0);
774+
{
775+
auto v = obj->getProperty("showModeLocked");
776+
showModeLocked = v.isVoid() ? false : (bool)v;
777+
}
764778
proDJLinkInterface = getInt("proDJLinkInterface", 0);
765779

766780
mainWindowBounds = getString("mainWindowBounds");
767781
pdlViewBounds = getString("pdlViewBounds");
782+
slqViewBounds = getString("slqViewBounds");
768783
trackMapBounds = getString("trackMapBounds");
769784
mixerMapBounds = getString("mixerMapBounds");
770785
pdlViewHorizontal = getInt("pdlViewHorizontal", 0) != 0;
771786
pdlViewShowMixer = getInt("pdlViewShowMixer", 1) != 0;
787+
slqViewHorizontal = getInt("slqViewHorizontal", 0) != 0;
772788

773789
engines.clear();
774790
auto* engArray = obj->getProperty("engines").getArray();

ArtnetOutput.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,8 @@ class ArtnetOutput : public juce::HighResolutionTimer
300300

301301
packet[10] = 0x00; // ProtVer Hi (big-endian)
302302
packet[11] = 0x0E; // ProtVer Lo = 14 (Art-Net 4 standard)
303-
packet[12] = 0; // Filler1 -- reserved, must be 0 (Art-Net 4 spec §12)
304-
packet[13] = 0; // Filler2 -- reserved, must be 0 (Art-Net 4 spec §12)
303+
packet[12] = 0; // Filler1 -- reserved, must be 0 (Art-Net 4 spec Sec.12)
304+
packet[13] = 0; // Filler2 -- reserved, must be 0 (Art-Net 4 spec Sec.12)
305305

306306
packet[14] = (uint8_t)tc.frames;
307307
packet[15] = (uint8_t)tc.seconds;

CustomLookAndFeel.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ class CustomLookAndFeel : public juce::LookAndFeel_V4
252252
}
253253

254254
// Detect marker patterns:
255-
// " " -> current engine active device (cyan dot)
255+
// " (dot)" -> current engine active device (cyan dot)
256256
// " [ENGINE N]" -> other engine using this device (amber tag)
257257
static const juce::String dotChar = juce::String::charToString(0x25CF);
258258

@@ -304,7 +304,7 @@ class CustomLookAndFeel : public juce::LookAndFeel_V4
304304
if (hasActiveDot && isActive)
305305
{
306306
// Current engine active: draw device name + cyan dot
307-
auto basePart = text.substring(0, text.length() - (dotChar.length() + 1)); // strip " "
307+
auto basePart = text.substring(0, text.length() - (dotChar.length() + 1)); // strip " (dot)"
308308
g.setColour(textBright);
309309
g.drawText(basePart, textArea, juce::Justification::centredLeft, false);
310310

LtcInput.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ class LtcInput : private juce::AudioIODeviceCallback
394394
// Reserve 1 sentinel slot to distinguish full from empty.
395395
// Need freeSlots >= 2 because 1 is the sentinel -- only (freeSlots-1)
396396
// are actually writable. Effective ring capacity is RING_SIZE-1
397-
// (32767 samples 682ms @48kHz), which is plenty for bridging
397+
// (32767 samples ~ 682ms @48kHz), which is plenty for bridging
398398
// the latency between input and AudioThru output callbacks.
399399
int toWrite = (freeSlots >= 2)
400400
? (int)juce::jmin((uint32_t)numSamples, freeSlots - 1)

Main.cpp

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class SuperTimecodeConverterApplication : public juce::JUCEApplication
1111
SuperTimecodeConverterApplication() {}
1212

1313
const juce::String getApplicationName() override { return "Super Timecode Converter"; }
14-
const juce::String getApplicationVersion() override { return "1.5.3"; }
14+
const juce::String getApplicationVersion() override { return "1.6.0"; }
1515
bool moreThanOneInstanceAllowed() override { return false; }
1616

1717
void initialise(const juce::String&) override
@@ -26,7 +26,12 @@ class SuperTimecodeConverterApplication : public juce::JUCEApplication
2626

2727
void systemRequestedQuit() override
2828
{
29-
quit();
29+
// Route through closeButtonPressed so the Show Lock guard applies
30+
// (covers macOS Cmd+Q, dock Quit, etc.)
31+
if (mainWindow != nullptr)
32+
mainWindow->closeButtonPressed();
33+
else
34+
quit();
3035
}
3136

3237
class MainWindow : public juce::DocumentWindow
@@ -70,19 +75,49 @@ class SuperTimecodeConverterApplication : public juce::JUCEApplication
7075
}
7176

7277
void closeButtonPressed() override
78+
{
79+
auto* mc = dynamic_cast<MainComponent*>(getContentComponent());
80+
81+
// If Show Lock is active, confirm before quitting
82+
if (mc != nullptr && mc->isShowModeLocked())
83+
{
84+
auto options = juce::MessageBoxOptions()
85+
.withIconType(juce::MessageBoxIconType::WarningIcon)
86+
.withTitle("Show Lock Active")
87+
.withMessage("Show Lock is active. Closing the application "
88+
"will stop all timecode outputs.\n\n"
89+
"Are you sure you want to quit?")
90+
.withButton("Quit")
91+
.withButton("Cancel");
92+
juce::Component::SafePointer<MainWindow> safeThis(this);
93+
juce::AlertWindow::showAsync(options, [safeThis](int result)
94+
{
95+
if (safeThis == nullptr) return;
96+
if (result == 1)
97+
{
98+
auto* mc2 = dynamic_cast<MainComponent*>(safeThis->getContentComponent());
99+
safeThis->saveWindowBoundsAndQuit(mc2);
100+
}
101+
});
102+
return;
103+
}
104+
105+
saveWindowBoundsAndQuit(mc);
106+
}
107+
108+
private:
109+
void saveWindowBoundsAndQuit(MainComponent* mc)
73110
{
74111
// Save window bounds before quitting
75-
if (auto* mc = dynamic_cast<MainComponent*>(getContentComponent()))
112+
if (mc != nullptr)
76113
{
77114
auto b = getBounds();
78115
mc->saveMainWindowBounds(
79116
juce::String(b.getX()) + " " + juce::String(b.getY()) + " "
80117
+ juce::String(b.getWidth()) + " " + juce::String(b.getHeight()));
81118
}
82-
JUCEApplication::getInstance()->systemRequestedQuit();
119+
JUCEApplication::getInstance()->quit();
83120
}
84-
85-
private:
86121
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainWindow)
87122
};
88123

0 commit comments

Comments
 (0)