mirror of
https://github.com/Boof2015/prism.git
synced 2026-08-12 13:20:53 +02:00
96 lines
3.0 KiB
C++
96 lines
3.0 KiB
C++
#pragma once
|
|
|
|
#include <juce_gui_extra/juce_gui_extra.h>
|
|
#include "PluginProcessor.h"
|
|
#include "ScopeEngine.h"
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
/**
|
|
* Hosts the React webview UI and bridges the reused Prism spectrum DSP to it.
|
|
*
|
|
* Drains stereo audio buffered by the processor, feeds the selected scope engine,
|
|
* and emits frame payloads to the webview after the UI reports readiness. macOS
|
|
* uses display vblank; Windows/Linux use steady message-thread timers to avoid
|
|
* fragile host/browser embedding behavior.
|
|
*/
|
|
class PrismSpectrumEditor : public juce::AudioProcessorEditor
|
|
#if JUCE_WINDOWS || JUCE_LINUX
|
|
, private juce::Timer
|
|
#endif
|
|
{
|
|
public:
|
|
explicit PrismSpectrumEditor(PrismSpectrumProcessor&);
|
|
~PrismSpectrumEditor() override;
|
|
|
|
void resized() override;
|
|
|
|
#if JUCE_WINDOWS || JUCE_LINUX
|
|
void timerCallback() override;
|
|
#endif
|
|
|
|
// Called by the webview event listeners (message thread).
|
|
void onPrismConfig(juce::var payload);
|
|
void onPrismReady();
|
|
|
|
// Scope-specific native config (e.g. the spectrogram's canvas-derived rowCount).
|
|
void onScopeNativeConfig(juce::var payload);
|
|
|
|
// The UI's settings panel opened/closed along the bottom. Grow/shrink the editor
|
|
// height by exactly the panel height so the scope area is unchanged (the window
|
|
// accommodates the panel, like the app). 0 = closed.
|
|
void onSettingsPanel(juce::var payload);
|
|
|
|
// Push the processor's saved settings to the UI (used on ready + on host
|
|
// state restore, to cover either ordering).
|
|
void pushRestoreSettings();
|
|
|
|
// Read the user's Prism app theme + active profile from disk and send them
|
|
// to the UI as defaults (per-instance overrides still win).
|
|
void sendAppDefaults();
|
|
|
|
private:
|
|
void loadUi();
|
|
bool createWebView();
|
|
void loadEmbeddedWebView();
|
|
void showWebViewFallback();
|
|
void startFrameDriver();
|
|
void renderFrame();
|
|
|
|
#if JUCE_LINUX
|
|
void loadNativeSmoke();
|
|
void loadWebSmoke();
|
|
void loadFloatingWebView();
|
|
void showLinuxDiagnosticPlaceholder(const juce::String& text);
|
|
#endif
|
|
|
|
PrismSpectrumProcessor& processorRef;
|
|
|
|
std::unique_ptr<ScopeEngine> engine;
|
|
std::vector<float> drainLeft, drainRight;
|
|
double lastSampleRate = 0.0;
|
|
|
|
// Height (px) the editor is currently grown by for the open settings panel.
|
|
int settingsPanelHeight = 0;
|
|
bool webViewReady = false;
|
|
bool frameDriverStarted = false;
|
|
|
|
// One-time attempt to lift WKWebView's private 60fps cap (macOS).
|
|
bool frameRateUncapped = false;
|
|
int uncapAttempts = 0;
|
|
|
|
std::unique_ptr<juce::WebBrowserComponent> webView;
|
|
#if JUCE_LINUX
|
|
std::unique_ptr<juce::DocumentWindow> floatingWebViewWindow;
|
|
#endif
|
|
juce::Label webViewFallback;
|
|
|
|
// Declared last so it is destroyed first; no vblank callback can fire into a
|
|
// partially-destroyed editor. Windows/Linux use juce::Timer instead.
|
|
#if ! JUCE_WINDOWS && ! JUCE_LINUX
|
|
juce::VBlankAttachment vblank;
|
|
#endif
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PrismSpectrumEditor)
|
|
};
|