Add popout button to sosci

pull/298/head
James H Ball 2025-04-04 17:26:27 +01:00
rodzic ddd2163644
commit 3580ef5fa4
4 zmienionych plików z 48 dodań i 17 usunięć

Wyświetl plik

@ -25,7 +25,7 @@ void AudioBackgroundThreadManager::write(const OsciPoint& point) {
void AudioBackgroundThreadManager::write(const OsciPoint& point, juce::String name) {
juce::SpinLock::ScopedLockType scope(lock);
for (auto& thread : threads) {
if (thread->getThreadName() == name) {
if (thread->getThreadName().contains(name)) {
thread->write(point);
}
}

Wyświetl plik

@ -13,8 +13,19 @@ TextParser::~TextParser() {
void TextParser::parse(juce::String text, juce::Font font) {
lastFont = font;
// Apply formatting markers if the font is bold or italic
juce::String formattedText = text;
if (font.isBold()) {
formattedText = "*" + formattedText + "*";
}
if (font.isItalic()) {
formattedText = "_" + formattedText + "_";
}
// Parse the text with formatting
attributedString = parseFormattedText(text, font);
attributedString = parseFormattedText(formattedText, font);
// Create a TextLayout from the AttributedString
juce::TextLayout layout;

Wyświetl plik

@ -80,7 +80,7 @@ VisualiserComponent::VisualiserComponent(
addAndMakeVisible(fullScreenButton);
fullScreenButton.setTooltip("Toggles fullscreen mode.");
}
if (child == nullptr && parent == nullptr && !visualiserOnly) {
if (child == nullptr && parent == nullptr) {
addAndMakeVisible(popOutButton);
popOutButton.setTooltip("Opens the oscilloscope in a new window.");
}
@ -315,11 +315,13 @@ double VisualiserComponent::getSweepIncrement() {
return 1.0 / (sampleRate * settings.getSweepSeconds());
}
void VisualiserComponent::setPaused(bool paused) {
void VisualiserComponent::setPaused(bool paused, bool affectAudio) {
active = !paused;
setShouldBeRunning(active);
renderingSemaphore.release();
audioPlayer.setPaused(paused);
if (affectAudio) {
audioPlayer.setPaused(paused);
}
repaint();
}
@ -334,7 +336,8 @@ void VisualiserComponent::mouseMove(const juce::MouseEvent& event) {
hideButtonRow = false;
setMouseCursor(juce::MouseCursor::PointingHandCursor);
if (fullScreen) {
// Treat both fullScreen mode and pop-out mode (parent != nullptr) as needing auto-hide controls
if (fullScreen || parent != nullptr) {
if (!getScreenBounds().removeFromBottom(25).contains(event.getScreenX(), event.getScreenY()) && !event.mods.isLeftButtonDown()) {
lastMouseX = event.getScreenX();
lastMouseY = event.getScreenY();
@ -348,7 +351,8 @@ void VisualiserComponent::mouseMove(const juce::MouseEvent& event) {
juce::Timer::callAfterDelay(1000, [this, weakRef, newTimerId, pos, parent]() {
if (weakRef) {
if (parent == nullptr || parent->child == this) {
if (timerId == newTimerId && fullScreen) {
// Check both fullscreen or pop-out mode
if (timerId == newTimerId && (fullScreen || this->parent != nullptr)) {
hideButtonRow = true;
setMouseCursor(juce::MouseCursor::NoCursor);
resized();
@ -545,7 +549,8 @@ void VisualiserComponent::setRecording(bool recording) {
void VisualiserComponent::resized() {
auto area = getLocalBounds();
if (fullScreen && hideButtonRow) {
// Apply hideButtonRow logic to both fullscreen and pop-out modes
if ((fullScreen || parent != nullptr) && hideButtonRow) {
buttonRow = area.removeFromBottom(0);
} else {
buttonRow = area.removeFromBottom(25);
@ -554,7 +559,7 @@ void VisualiserComponent::resized() {
if (parent == nullptr) {
fullScreenButton.setBounds(buttons.removeFromRight(30));
}
if (child == nullptr && parent == nullptr && !visualiserOnly) {
if (child == nullptr && parent == nullptr) {
popOutButton.setBounds(buttons.removeFromRight(30));
}
if (openSettings != nullptr) {
@ -563,12 +568,15 @@ void VisualiserComponent::resized() {
} else {
settingsButton.setVisible(false);
}
if (visualiserOnly && juce::JUCEApplication::isStandaloneApp()) {
if (visualiserOnly && juce::JUCEApplication::isStandaloneApp() && child == nullptr) {
audioInputButton.setBounds(buttons.removeFromRight(30));
}
#if SOSCI_FEATURES
sharedTextureButton.setBounds(buttons.removeFromRight(30));
#endif
record.setBounds(buttons.removeFromRight(25));
if (record.getToggleState()) {
stopwatch.setVisible(true);
@ -576,14 +584,20 @@ void VisualiserComponent::resized() {
} else {
stopwatch.setVisible(false);
}
#if SOSCI_FEATURES
if (child == nullptr && downloading) {
auto bounds = buttons.removeFromRight(160);
ffmpegDownloader.setBounds(bounds.withSizeKeepingCentre(bounds.getWidth() - 10, bounds.getHeight() - 10));
}
#endif
buttons.removeFromRight(10); // padding
audioPlayer.setBounds(buttons);
if (child == nullptr) {
audioPlayer.setBounds(buttons);
}
viewportArea = area;
viewportChanged(viewportArea);
}
@ -603,21 +617,23 @@ void VisualiserComponent::popoutWindow() {
ffmpegFile,
settings,
recordingSettings,
this
this,
visualiserOnly
);
visualiser->settings.setLookAndFeel(&getLookAndFeel());
visualiser->openSettings = openSettings;
visualiser->closeSettings = closeSettings;
// Pop-out visualiser is created with parent set to this component
child = visualiser;
childUpdated();
visualiser->setSize(300, 325);
visualiser->setSize(350, 350);
popout = std::make_unique<VisualiserWindow>("Software Oscilloscope", this);
popout->setContentOwned(visualiser, true);
popout->setUsingNativeTitleBar(true);
popout->setResizable(true, false);
popout->setVisible(true);
popout->centreWithSize(300, 325);
setPaused(true);
popout->centreWithSize(350, 350);
setPaused(true, false);
resized();
}
@ -627,12 +643,14 @@ void VisualiserComponent::childUpdated() {
ffmpegDownloader.setVisible(child == nullptr);
#endif
record.setVisible(child == nullptr);
audioPlayer.setVisible(child == nullptr);
if (child != nullptr) {
audioProcessor.haltRecording = [this] {
setRecording(false);
child->setRecording(false);
};
} else {
audioPlayer.setup();
audioProcessor.haltRecording = [this] {
setRecording(false);
};

Wyświetl plik

@ -60,7 +60,7 @@ public:
int prepareTask(double sampleRate, int samplesPerBlock) override;
void runTask(const std::vector<OsciPoint>& points) override;
void stopTask() override;
void setPaused(bool paused);
void setPaused(bool paused, bool affectAudio = true);
void mouseDrag(const juce::MouseEvent& event) override;
void mouseMove(const juce::MouseEvent& event) override;
void mouseDown(const juce::MouseEvent& event) override;
@ -292,11 +292,13 @@ public:
}
void closeButtonPressed() override {
// local copy of parent so that we can safely delete the child
VisualiserComponent* parent = this->parent;
parent->setPaused(wasPaused);
parent->child = nullptr;
parent->popout.reset();
parent->childUpdated();
parent->resized();
parent->popout.reset();
}
private: