rmx-19/Source/LcdPanel.h

118 lines
4.3 KiB
C
Raw Normal View History

#pragma once
#include <juce_gui_basics/juce_gui_basics.h>
#include "Params.h"
#include "PluginProcessor.h"
class LcdPanel : public juce::Component, public juce::Timer
{
public:
explicit LcdPanel (RMX19AudioProcessor& proc);
~LcdPanel() override;
void paint (juce::Graphics&) override;
void navUp(); void navDown();
void navLeft(); void navRight();
void navEnter(); void navExit();
void applyPatchOnBrowserMove();
void resetToHome();
static bool firstRunEver();
static juce::File uiStateFile();
static constexpr int gridW = 160; // dot-matrix cell resolution
static constexpr int gridH = 64;
2026-09-08 21:57:34 +02:00
// internal supersampling: dots are rasterized as anti-aliased circles at 4x,
// then box-downsampled 2:1 onto the 2px/dot presentation image. Downsampling
// turned off = chunky squares; 2x direct = boxy edges. 4x gives genuine round,
// separated dots that survive the (fractional) uiScale upscale.
static constexpr int subsample = 4;
static constexpr int presentScale = 2; // presentation pixels per logical dot
bool keyTrap (const juce::KeyPress&);
2026-09-08 21:57:34 +02:00
void mouseDown (const juce::MouseEvent&) override;
private:
2026-09-08 21:57:34 +02:00
enum class Screen { Splash, Home, Menu, Patches, Patch, Param, System, Info, Category };
RMX19AudioProcessor& proc;
Screen screen = Screen::Splash;
juce::uint32 splashUntil = 0;
2026-09-08 21:57:34 +02:00
int cursor = 0; // menu / param / system / catCursor (when in Category)
int patchCursor = 0; // patch cursor (global index)
int paramScreenIdx = 0; // which param screen is open
2026-09-08 21:57:34 +02:00
int catCursor = 0; // category browser cursor
std::vector<int> filteredPatches; // patch indices for current category filter
float powerGlow = 0.0f;
int lastVoices = -1;
juce::uint32 lastMidi = 0;
// last-screen persistence: the panel reopens where the user left off
juce::uint32 lastUiWrite = 0;
bool uiDirty = false;
void rememberUiState();
bool restoreUiState();
2026-09-08 21:57:34 +02:00
juce::Image displayImage; // (gridW*subsample)x(gridH*subsample) render target: glass base + content dots
juce::Image presentImage; // (gridW*presentScale)x(gridH*presentScale) box-downsampled for the panel
juce::Image backdrop; // (gridW*subsample)x(gridH*subsample) static 3D glass base (backlight + sheen + vignette + ghost dots)
bool contentDirty = true;
static const juce::uint8* glyphFor (int key);
static const juce::uint8* glyphM (int key);
void rebuild();
void buildBackdrop();
2026-09-08 21:57:34 +02:00
juce::Rectangle<int> lcdImageRect() const;
void drawContent (juce::Graphics&);
void px (juce::Graphics&, int x, int y, float intensity);
void pxText (juce::Graphics&, int x, int y, const juce::String&, float intensity);
void pxTextM (juce::Graphics&, int x, int y, const juce::String&, float intensity);
void drawFilled (juce::Graphics&, int x, int y, int w, int h, float intensity);
void drawHBar (juce::Graphics&, int x, int y, int w, double level, float intensity);
void drawSelBar (juce::Graphics&, int y);
void drawSplash (juce::Graphics&);
void drawHome (juce::Graphics&);
void drawMenu (juce::Graphics&);
2026-09-08 21:57:34 +02:00
void drawCategory (juce::Graphics&);
void drawPatches (juce::Graphics&);
void drawPatchList (juce::Graphics&);
void drawParamScreen (juce::Graphics&);
void drawSystem (juce::Graphics&);
void drawInfo (juce::Graphics&);
void drawFooter (juce::Graphics&);
void selectPatchCyclic (int dir);
void stepParam (prm::Id id, int dir, bool coarse);
void stepDelaySync (int dir);
void setDirty() { contentDirty = true; repaint(); }
void enterScreen (Screen s) { screen = s; cursor = 0; uiDirty = true; setDirty(); }
2026-09-08 21:57:34 +02:00
// open the category/patch browser, positioned on the loaded patch's category
void openPatchBrowser();
void timerCallback() override;
int rowCountForScreen() const;
void moveCursor (int d);
void adjustCurrent (int dir, bool coarse);
void openParamScreen (int idx);
const char* paramScreenTitle (int idx) const;
int paramCountForScreen (int idx) const;
2026-09-08 21:57:34 +02:00
int patchCountForCurrentView() const;
int patchIndexAtCursor (int viewIdx) const;
void buildFilteredPatches (int catIdx);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LcdPanel)
};