Special trickery to allow browser preview of framebuffer panels
Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
parent
da190c9bfc
commit
54bc763d0d
9 changed files with 196 additions and 74 deletions
|
@ -497,15 +497,7 @@ struct HostMIDICC : Module {
|
|||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
struct CardinalMIDILearnPJ301MPort : PJ301MPort {
|
||||
void onDragStart(const DragStartEvent& e) override {
|
||||
PJ301MPort::onDragStart(e);
|
||||
}
|
||||
void onDragEnd(const DragEndEvent& e) override {
|
||||
PJ301MPort::onDragEnd(e);
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef HEADLESS
|
||||
/**
|
||||
* Based on VCVRack's CcChoice as defined in src/core/plugin.hpp
|
||||
* Copyright (C) 2016-2021 VCV.
|
||||
|
@ -523,7 +515,14 @@ struct CardinalCcChoice : CardinalLedDisplayChoice {
|
|||
CardinalCcChoice(HostMIDICC* const m, const int i)
|
||||
: CardinalLedDisplayChoice(),
|
||||
module(m),
|
||||
id(i) {}
|
||||
id(i)
|
||||
{
|
||||
// Module browser setup
|
||||
if (m == nullptr)
|
||||
{
|
||||
text = string::f("%d", i+1);
|
||||
}
|
||||
}
|
||||
|
||||
void step() override
|
||||
{
|
||||
|
@ -691,14 +690,14 @@ struct HostMIDICCWidget : ModuleWidget {
|
|||
{
|
||||
const float x = startX_In + int(i / 6) * padding;
|
||||
const float y = startY + int(i % 6) * padding;
|
||||
addInput(createInput<CardinalMIDILearnPJ301MPort>(Vec(x, y), module, i));
|
||||
addInput(createInput<PJ301MPort>(Vec(x, y), module, i));
|
||||
}
|
||||
|
||||
for (int i=0; i<18; ++i)
|
||||
{
|
||||
const float x = startX_Out + int(i / 6) * padding;
|
||||
const float y = startY + int(i % 6) * padding;
|
||||
addOutput(createOutput<CardinalMIDILearnPJ301MPort>(Vec(x, y), module, i));
|
||||
addOutput(createOutput<PJ301MPort>(Vec(x, y), module, i));
|
||||
}
|
||||
|
||||
CCGridDisplay* const display = createWidget<CCGridDisplay>(Vec(startX_In - 3.0f, 70.0f));
|
||||
|
@ -775,6 +774,9 @@ struct HostMIDICCWidget : ModuleWidget {
|
|||
menu->addChild(outputChannelItem);
|
||||
}
|
||||
};
|
||||
#else
|
||||
typedef ModuleWidget HostMIDICCWidget;
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -404,15 +404,7 @@ struct HostMIDIGate : Module {
|
|||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
struct CardinalMIDILearnPJ301MPort : PJ301MPort {
|
||||
void onDragStart(const DragStartEvent& e) override {
|
||||
PJ301MPort::onDragStart(e);
|
||||
}
|
||||
void onDragEnd(const DragEndEvent& e) override {
|
||||
PJ301MPort::onDragEnd(e);
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef HEADLESS
|
||||
/**
|
||||
* Based on VCVRack's NoteChoice as defined in src/core/plugin.hpp
|
||||
* Copyright (C) 2016-2021 VCV.
|
||||
|
@ -605,14 +597,14 @@ struct HostMIDIGateWidget : ModuleWidget {
|
|||
{
|
||||
const float x = startX_In + int(i / 6) * padding;
|
||||
const float y = startY + int(i % 6) * padding;
|
||||
addInput(createInput<CardinalMIDILearnPJ301MPort>(Vec(x, y), module, i));
|
||||
addInput(createInput<PJ301MPort>(Vec(x, y), module, i));
|
||||
}
|
||||
|
||||
for (int i=0; i<18; ++i)
|
||||
{
|
||||
const float x = startX_Out + int(i / 6) * padding;
|
||||
const float y = startY + int(i % 6) * padding;
|
||||
addOutput(createOutput<CardinalMIDILearnPJ301MPort>(Vec(x, y), module, i));
|
||||
addOutput(createOutput<PJ301MPort>(Vec(x, y), module, i));
|
||||
}
|
||||
|
||||
NoteGridDisplay* const display = createWidget<NoteGridDisplay>(Vec(startX_In - 3.0f, 70.0f));
|
||||
|
@ -696,6 +688,9 @@ struct HostMIDIGateWidget : ModuleWidget {
|
|||
));
|
||||
}
|
||||
};
|
||||
#else
|
||||
typedef ModuleWidget HostMIDIGateWidget;
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -90,10 +90,10 @@ struct HostMIDIMap : Module {
|
|||
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
|
||||
|
||||
for (int id = 0; id < MAX_MIDI_CONTROL; ++id)
|
||||
// {
|
||||
// paramHandles[id].color = nvgRGB(0xff, 0xff, 0x40);
|
||||
{
|
||||
paramHandles[id].color = nvgRGBf(0.76f, 0.11f, 0.22f);
|
||||
pcontext->engine->addParamHandle(¶mHandles[id]);
|
||||
// }
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_MIDI_CONTROL; i++)
|
||||
valueFilters[i].setTau(1 / 30.f);
|
||||
|
@ -460,18 +460,27 @@ struct HostMIDIMap : Module {
|
|||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
struct MIDIMapChoice : CardinalLedDisplayChoice {
|
||||
#ifndef HEADLESS
|
||||
struct CardinalMIDIMapChoice : CardinalLedDisplayChoice {
|
||||
HostMIDIMap* const module;
|
||||
const int id;
|
||||
int disableLearnFrames = -1;
|
||||
ParamWidget* lastTouchedParam = nullptr;
|
||||
|
||||
MIDIMapChoice(HostMIDIMap* const m, const int i)
|
||||
CardinalMIDIMapChoice(HostMIDIMap* const m, const int i)
|
||||
: CardinalLedDisplayChoice(),
|
||||
module(m),
|
||||
id(i)
|
||||
{
|
||||
alignTextCenter = false;
|
||||
|
||||
// Module browser setup
|
||||
if (m == nullptr)
|
||||
{
|
||||
bgColor = nvgRGB(0, 0, 0);
|
||||
color.a = 0.75f;
|
||||
text = "Click here to map";
|
||||
}
|
||||
}
|
||||
|
||||
void draw(const DrawArgs& args) override
|
||||
|
@ -489,7 +498,7 @@ struct MIDIMapChoice : CardinalLedDisplayChoice {
|
|||
|
||||
void step() override
|
||||
{
|
||||
if (!module)
|
||||
if (module == nullptr)
|
||||
return;
|
||||
|
||||
// Set bgColor and selected state
|
||||
|
@ -609,7 +618,7 @@ struct MIDIMapChoice : CardinalLedDisplayChoice {
|
|||
struct HostMIDIMapDisplay : Widget {
|
||||
HostMIDIMap* module;
|
||||
ScrollWidget* scroll;
|
||||
MIDIMapChoice* choices[MAX_MIDI_CONTROL];
|
||||
CardinalMIDIMapChoice* choices[MAX_MIDI_CONTROL];
|
||||
LedDisplaySeparator* separators[MAX_MIDI_CONTROL];
|
||||
|
||||
void drawLayer(const DrawArgs& args, int layer) override
|
||||
|
@ -634,13 +643,15 @@ struct HostMIDIMapDisplay : Widget {
|
|||
{
|
||||
LedDisplaySeparator* separator = createWidget<LedDisplaySeparator>(Vec(0.0f, posY));
|
||||
separator->box.size = Vec(box.size.x, 1.0f);
|
||||
separator->visible = false;
|
||||
scroll->container->addChild(separator);
|
||||
separators[id] = separator;
|
||||
}
|
||||
|
||||
MIDIMapChoice* const choice = new MIDIMapChoice(module, id);
|
||||
CardinalMIDIMapChoice* const choice = new CardinalMIDIMapChoice(module, id);
|
||||
choice->box.pos = Vec(0.0f, posY);
|
||||
choice->box.size = Vec(box.size.x, 20.0f);
|
||||
choice->visible = id == 0;
|
||||
scroll->container->addChild(choice);
|
||||
choices[id] = choice;
|
||||
|
||||
|
@ -722,6 +733,9 @@ struct HostMIDIMapWidget : ModuleWidget {
|
|||
menu->addChild(inputChannelItem);
|
||||
}
|
||||
};
|
||||
#else
|
||||
typedef ModuleWidget HostMIDIMapWidget;
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -745,25 +745,33 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread {
|
|||
: ImGuiWidget(),
|
||||
module(m)
|
||||
{
|
||||
if (module->fCarlaHostHandle == nullptr)
|
||||
{
|
||||
fDrawingState = kDrawingErrorInit;
|
||||
fIdleState = kIdleNothing;
|
||||
fPopupError = "Ildaeil backend failed to init properly, cannot continue.";
|
||||
return;
|
||||
}
|
||||
|
||||
std::strcpy(fPluginSearchString, "Search...");
|
||||
|
||||
if (checkIfPluginIsLoaded())
|
||||
fIdleState = kIdleInitPluginAlreadyLoaded;
|
||||
if (m != nullptr)
|
||||
{
|
||||
if (m->fCarlaHostHandle == nullptr)
|
||||
{
|
||||
fDrawingState = kDrawingErrorInit;
|
||||
fIdleState = kIdleNothing;
|
||||
fPopupError = "Ildaeil backend failed to init properly, cannot continue.";
|
||||
return;
|
||||
}
|
||||
|
||||
module->fUI = this;
|
||||
if (checkIfPluginIsLoaded())
|
||||
fIdleState = kIdleInitPluginAlreadyLoaded;
|
||||
|
||||
m->fUI = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
fDrawingState = kDrawingPluginList;
|
||||
fIdleState = kIdleNothing;
|
||||
}
|
||||
}
|
||||
|
||||
~IldaeilWidget() override
|
||||
{
|
||||
if (module->fCarlaHostHandle != nullptr)
|
||||
if (module != nullptr && module->fCarlaHostHandle != nullptr)
|
||||
{
|
||||
if (idleCallbackActive)
|
||||
{
|
||||
|
@ -1009,6 +1017,9 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread {
|
|||
|
||||
void widgetCreated()
|
||||
{
|
||||
if (module == nullptr)
|
||||
return;
|
||||
|
||||
if (const CarlaHostHandle handle = module->fCarlaHostHandle)
|
||||
{
|
||||
const CardinalPluginContext* const pcontext = module->pcontext;
|
||||
|
@ -1031,6 +1042,9 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread {
|
|||
|
||||
void widgetDestroyed()
|
||||
{
|
||||
if (module == nullptr)
|
||||
return;
|
||||
|
||||
if (const CarlaHostHandle handle = module->fCarlaHostHandle)
|
||||
{
|
||||
const CardinalPluginContext* const pcontext = module->pcontext;
|
||||
|
@ -1532,7 +1546,7 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread {
|
|||
if (ImGui::Button("Load Plugin"))
|
||||
fIdleState = kIdleLoadSelectedPlugin;
|
||||
|
||||
if (fPluginType != PLUGIN_INTERNAL && module->canUseBridges)
|
||||
if (fPluginType != PLUGIN_INTERNAL && (module == nullptr || module->canUseBridges))
|
||||
{
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Run in bridge mode", &fPluginWillRunInBridgeMode);
|
||||
|
@ -1657,7 +1671,7 @@ struct IldaeilModuleWidget : ModuleWidget {
|
|||
setModule(module);
|
||||
setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Ildaeil.svg")));
|
||||
|
||||
if (module != nullptr && module->pcontext != nullptr)
|
||||
if (module == nullptr || module->pcontext != nullptr)
|
||||
{
|
||||
ildaeilWidget = new IldaeilWidget(module);
|
||||
ildaeilWidget->box.pos = Vec(2 * RACK_GRID_WIDTH, 0);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Dear ImGui for DPF, converted to VCV
|
||||
* Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
|
||||
* Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
|
||||
* Copyright (C) 2021 Jean Pierre Cimalando <jp-dev@inbox.ru>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any purpose with
|
||||
|
@ -145,7 +145,7 @@ float ImGuiWidget::getScaleFactor() const noexcept
|
|||
|
||||
void ImGuiWidget::onContextCreate(const ContextCreateEvent& e)
|
||||
{
|
||||
OpenGlWidget::onContextCreate(e);
|
||||
OpenGlWidgetWithBrowserPreview::onContextCreate(e);
|
||||
DISTRHO_SAFE_ASSERT_RETURN(!imData->created,);
|
||||
|
||||
ImGui::SetCurrentContext(imData->context);
|
||||
|
@ -162,7 +162,7 @@ void ImGuiWidget::onContextDestroy(const ContextDestroyEvent& e)
|
|||
imData->created = false;
|
||||
}
|
||||
|
||||
OpenGlWidget::onContextDestroy(e);
|
||||
OpenGlWidgetWithBrowserPreview::onContextDestroy(e);
|
||||
}
|
||||
|
||||
void ImGuiWidget::setAsCurrentContext()
|
||||
|
@ -307,13 +307,39 @@ void ImGuiWidget::onSelectText(const SelectTextEvent& e)
|
|||
}
|
||||
|
||||
void ImGuiWidget::drawFramebuffer()
|
||||
{
|
||||
const float scaleFactor = APP->window->pixelRatio;
|
||||
|
||||
drawFramebufferCommon(getFramebufferSize(), scaleFactor);
|
||||
}
|
||||
|
||||
void ImGuiWidget::drawFramebufferForBrowserPreview()
|
||||
{
|
||||
if (imData->created)
|
||||
{
|
||||
ImGui::SetCurrentContext(imData->context);
|
||||
ImGui_ImplOpenGL2_Shutdown();
|
||||
ImGui::DestroyContext(imData->context);
|
||||
|
||||
imData->created = false;
|
||||
imData->fontGenerated = false;
|
||||
imData->originalScaleFactor = 0.0f;
|
||||
imData->scaleFactor = 0.0f;
|
||||
}
|
||||
|
||||
imData->context = ImGui::CreateContext();
|
||||
ImGui::SetCurrentContext(imData->context);
|
||||
ImGui_ImplOpenGL2_Init();
|
||||
imData->created = true;
|
||||
|
||||
drawFramebufferCommon(box.size.mult(oversample), oversample);
|
||||
}
|
||||
|
||||
void ImGuiWidget::drawFramebufferCommon(const Vec& fbSize, const float scaleFactor)
|
||||
{
|
||||
ImGui::SetCurrentContext(imData->context);
|
||||
ImGuiIO& io(ImGui::GetIO());
|
||||
|
||||
const math::Vec fbSize = getFramebufferSize();
|
||||
const float scaleFactor = APP->window->pixelRatio;
|
||||
|
||||
if (d_isNotEqual(imData->scaleFactor, scaleFactor))
|
||||
{
|
||||
imData->scaleFactor = scaleFactor;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Dear ImGui for DPF, converted to VCV
|
||||
* Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
|
||||
* Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
|
||||
* Copyright (C) 2021 Jean Pierre Cimalando <jp-dev@inbox.ru>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any purpose with
|
||||
|
@ -20,7 +20,7 @@
|
|||
#include "plugin.hpp"
|
||||
#include "DearImGui/imgui.h"
|
||||
|
||||
struct ImGuiWidget : OpenGlWidget {
|
||||
struct ImGuiWidget : OpenGlWidgetWithBrowserPreview {
|
||||
struct PrivateData;
|
||||
PrivateData* const imData;
|
||||
|
||||
|
@ -50,4 +50,6 @@ protected:
|
|||
|
||||
private:
|
||||
void drawFramebuffer() override;
|
||||
void drawFramebufferForBrowserPreview() override;
|
||||
void drawFramebufferCommon(const Vec& fbSize, float scaleFactor);
|
||||
};
|
||||
|
|
|
@ -326,21 +326,24 @@ struct TextEditorModuleWidget : ModuleWidget {
|
|||
addChild(rightHandle = new ModuleResizeHandle(module, this, true));
|
||||
addChild(new ModuleResizeHandle(module, this, false));
|
||||
|
||||
box.size = Vec(RACK_GRID_WIDTH * (module != nullptr ? module->width : DEFAULT_WIDTH), RACK_GRID_HEIGHT);
|
||||
|
||||
textEditorModule = module;
|
||||
textEditorWidget = new ImGuiTextEditor();
|
||||
textEditorWidget->box.pos = Vec(RACK_GRID_WIDTH, 0);
|
||||
textEditorWidget->box.size = Vec(box.size.x - 2 * RACK_GRID_WIDTH, box.size.y);
|
||||
addChild(textEditorWidget);
|
||||
|
||||
if (module != nullptr)
|
||||
{
|
||||
box.size = Vec(RACK_GRID_WIDTH * module->width, RACK_GRID_HEIGHT);
|
||||
textEditorModule = module;
|
||||
textEditorWidget = new ImGuiTextEditor();
|
||||
textEditorWidget->setFileWithKnownText(module->file, module->text);
|
||||
textEditorWidget->setLanguageDefinition(module->lang);
|
||||
textEditorWidget->box.pos = Vec(RACK_GRID_WIDTH, 0);
|
||||
textEditorWidget->box.size = Vec((module->width - 2) * RACK_GRID_WIDTH, box.size.y);
|
||||
addChild(textEditorWidget);
|
||||
textEditorWidget->setFileWithKnownText(module->file, module->text);
|
||||
module->widgetPtr = textEditorWidget;
|
||||
}
|
||||
else
|
||||
{
|
||||
box.size = Vec(RACK_GRID_WIDTH * DEFAULT_WIDTH, RACK_GRID_HEIGHT);
|
||||
textEditorWidget->setLanguageDefinition(DEFAULT_LANG);
|
||||
textEditorWidget->setText(DEFAULT_TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,13 +61,13 @@ struct glBarsModule : Module {
|
|||
};
|
||||
|
||||
#ifndef HEADLESS
|
||||
struct glBarsRendererWidget : OpenGlWidget {
|
||||
struct glBarsRendererWidget : OpenGlWidgetWithBrowserPreview {
|
||||
glBarsModule* const glBars;
|
||||
|
||||
glBarsRendererWidget(glBarsModule* const module)
|
||||
: glBars(module)
|
||||
{
|
||||
if (APP->window->pixelRatio < 2.0f)
|
||||
if (glBars != nullptr && APP->window->pixelRatio < 2.0f)
|
||||
oversample = 2.0f;
|
||||
}
|
||||
|
||||
|
@ -75,22 +75,34 @@ struct glBarsRendererWidget : OpenGlWidget {
|
|||
{
|
||||
}
|
||||
|
||||
void drawLayer(const DrawArgs& args, int layer) override
|
||||
void drawLayer(const DrawArgs& args, const int layer) override
|
||||
{
|
||||
if (layer != 1)
|
||||
return;
|
||||
|
||||
OpenGlWidget::draw(args);
|
||||
OpenGlWidgetWithBrowserPreview::draw(args);
|
||||
}
|
||||
|
||||
void drawFramebuffer() override {
|
||||
math::Vec fbSize = getFramebufferSize();
|
||||
void drawFramebuffer() override
|
||||
{
|
||||
DISTRHO_SAFE_ASSERT_RETURN(glBars != nullptr,);
|
||||
|
||||
drawFramebuffer(glBars->state, getFramebufferSize());
|
||||
}
|
||||
|
||||
void drawFramebufferForBrowserPreview() override
|
||||
{
|
||||
glBarsState state;
|
||||
drawFramebuffer(state, box.size);
|
||||
}
|
||||
|
||||
void drawFramebuffer(glBarsState& state, const Vec& fbSize)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glViewport(0.0, -100, fbSize.x * oversample, fbSize.y * oversample);
|
||||
glViewport(0.0, -50 * oversample, fbSize.x * oversample, fbSize.y * oversample);
|
||||
glFrustum(-1, 1, -1, 1, 1.5, 10);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
|
@ -99,7 +111,7 @@ struct glBarsRendererWidget : OpenGlWidget {
|
|||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glBars->state.Render();
|
||||
state.Render();
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
|
@ -107,18 +119,17 @@ struct glBarsRendererWidget : OpenGlWidget {
|
|||
glEnable(GL_BLEND);
|
||||
}
|
||||
|
||||
void step() override {
|
||||
void step() override
|
||||
{
|
||||
OpenGlWidget::step();
|
||||
|
||||
oversample = APP->window->pixelRatio < 2.0f ? 2.0f : 1.0f;
|
||||
if (glBars != nullptr)
|
||||
oversample = APP->window->pixelRatio < 2.0f ? 2.0f : 1.0f;
|
||||
}
|
||||
};
|
||||
|
||||
struct glBarsWidget : ModuleWidget {
|
||||
glBarsRendererWidget* const glBarsRenderer;
|
||||
|
||||
glBarsWidget(glBarsModule* const module)
|
||||
: glBarsRenderer(new glBarsRendererWidget(module))
|
||||
{
|
||||
setModule(module);
|
||||
setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/glBars.svg")));
|
||||
|
@ -131,6 +142,7 @@ struct glBarsWidget : ModuleWidget {
|
|||
addInput(createInput<PJ301MPort>(Vec(135.0f, 20.0f), module, glBarsModule::IN1_INPUT));
|
||||
|
||||
const float size = mm2px(127.0f);
|
||||
glBarsRendererWidget* const glBarsRenderer = new glBarsRendererWidget(module);
|
||||
glBarsRenderer->box.pos = Vec((box.size.x - size) * 0.5f, (box.size.y - size) * 0.5f);
|
||||
glBarsRenderer->box.size = Vec(size, size);
|
||||
addChild(glBarsRenderer);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
using namespace rack;
|
||||
|
||||
#ifndef HEADLESS
|
||||
struct CardinalLedDisplayChoice : LedDisplayChoice {
|
||||
bool alignTextCenter = true;
|
||||
|
||||
|
@ -60,6 +61,59 @@ struct CardinalLedDisplayChoice : LedDisplayChoice {
|
|||
}
|
||||
};
|
||||
|
||||
struct OpenGlWidgetWithBrowserPreview : OpenGlWidget {
|
||||
NVGLUframebuffer* fb = nullptr;
|
||||
|
||||
void draw(const DrawArgs& args) override
|
||||
{
|
||||
if (args.fb == nullptr)
|
||||
return OpenGlWidget::draw(args);
|
||||
|
||||
// set oversample to current scale
|
||||
float trans[6];
|
||||
nvgCurrentTransform(args.vg, trans);
|
||||
oversample = std::max(1.0f, trans[0]);
|
||||
|
||||
// recreate framebuffer
|
||||
deleteFramebuffer();
|
||||
fb = nvgluCreateFramebuffer(args.vg, box.size.x * oversample, box.size.y * oversample, 0);
|
||||
DISTRHO_SAFE_ASSERT_RETURN(fb != nullptr,);
|
||||
|
||||
// draw our special framebuffer
|
||||
nvgluBindFramebuffer(fb);
|
||||
drawFramebufferForBrowserPreview();
|
||||
|
||||
// reset to regular framebuffer
|
||||
nvgluBindFramebuffer(args.fb);
|
||||
|
||||
// render image generated by our framebuffer
|
||||
nvgBeginPath(args.vg);
|
||||
nvgRect(args.vg, 0.0f, 0.0f, box.size.x, box.size.y);
|
||||
NVGpaint paint = nvgImagePattern(args.vg,
|
||||
0.0f, 0.0f, box.size.x, box.size.y,
|
||||
0.0f, fb->image, 1.0f);
|
||||
nvgFillPaint(args.vg, paint);
|
||||
nvgFill(args.vg);
|
||||
}
|
||||
|
||||
void onContextDestroy(const ContextDestroyEvent& e) override
|
||||
{
|
||||
deleteFramebuffer();
|
||||
OpenGlWidget::onContextDestroy(e);
|
||||
}
|
||||
|
||||
void deleteFramebuffer()
|
||||
{
|
||||
if (fb == nullptr)
|
||||
return;
|
||||
nvgluDeleteFramebuffer(fb);
|
||||
fb = nullptr;
|
||||
}
|
||||
|
||||
virtual void drawFramebufferForBrowserPreview() = 0;
|
||||
};
|
||||
#endif
|
||||
|
||||
extern Plugin* pluginInstance;
|
||||
|
||||
extern Model* modelAudioFile;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue