Switch to using VCV nanovg; Hook mouse events; Add resize handle
This commit is contained in:
parent
d6dcdfff55
commit
ee3f3771a4
9 changed files with 379 additions and 52 deletions
6
Makefile
6
Makefile
|
@ -8,6 +8,8 @@ include dpf/Makefile.base.mk
|
||||||
|
|
||||||
all: dgl plugins gen
|
all: dgl plugins gen
|
||||||
|
|
||||||
|
SKIP_NANOVG = true
|
||||||
|
|
||||||
# --------------------------------------------------------------
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
dgl:
|
dgl:
|
||||||
|
@ -40,9 +42,13 @@ clean:
|
||||||
rm -rf plugins/CVCRack/Rack/dep/include
|
rm -rf plugins/CVCRack/Rack/dep/include
|
||||||
rm -rf plugins/CVCRack/Rack/dep/lib
|
rm -rf plugins/CVCRack/Rack/dep/lib
|
||||||
rm -rf plugins/CVCRack/Rack/dep/share
|
rm -rf plugins/CVCRack/Rack/dep/share
|
||||||
|
rm -rf plugins/CVCRack/Rack/dep/curl-7.66.0
|
||||||
rm -rf plugins/CVCRack/Rack/dep/glew-2.1.0
|
rm -rf plugins/CVCRack/Rack/dep/glew-2.1.0
|
||||||
rm -rf plugins/CVCRack/Rack/dep/jansson-2.12
|
rm -rf plugins/CVCRack/Rack/dep/jansson-2.12
|
||||||
|
rm -rf plugins/CVCRack/Rack/dep/libarchive-3.4.3
|
||||||
|
rm -rf plugins/CVCRack/Rack/dep/openssl-1.1.1d
|
||||||
rm -rf plugins/CVCRack/Rack/dep/speexdsp-SpeexDSP-1.2rc3
|
rm -rf plugins/CVCRack/Rack/dep/speexdsp-SpeexDSP-1.2rc3
|
||||||
|
rm -rf plugins/CVCRack/Rack/dep/zstd-1.4.5
|
||||||
|
|
||||||
# --------------------------------------------------------------
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
|
2
dpf
2
dpf
|
@ -1 +1 @@
|
||||||
Subproject commit 23f89562acbd637a23b9f0333877939ad26c0595
|
Subproject commit c17c260d08613ab46e13dc578104c74b5713a435
|
|
@ -25,6 +25,9 @@
|
||||||
#include <settings.hpp>
|
#include <settings.hpp>
|
||||||
#include <system.hpp>
|
#include <system.hpp>
|
||||||
|
|
||||||
|
#include <ui/common.hpp>
|
||||||
|
#include <window/Window.hpp>
|
||||||
|
|
||||||
#include <osdialog.h>
|
#include <osdialog.h>
|
||||||
|
|
||||||
#include "DistrhoPlugin.hpp"
|
#include "DistrhoPlugin.hpp"
|
||||||
|
@ -53,6 +56,7 @@ struct Initializer {
|
||||||
|
|
||||||
// Load settings
|
// Load settings
|
||||||
settings::init();
|
settings::init();
|
||||||
|
#if 0
|
||||||
try {
|
try {
|
||||||
settings::load();
|
settings::load();
|
||||||
}
|
}
|
||||||
|
@ -66,6 +70,7 @@ struct Initializer {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check existence of the system res/ directory
|
// Check existence of the system res/ directory
|
||||||
std::string resDir = asset::system("res");
|
std::string resDir = asset::system("res");
|
||||||
|
@ -88,12 +93,18 @@ struct Initializer {
|
||||||
plugin::init();
|
plugin::init();
|
||||||
library::init();
|
library::init();
|
||||||
// discord::init();
|
// discord::init();
|
||||||
|
|
||||||
|
ui::init();
|
||||||
|
window::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
~Initializer()
|
~Initializer()
|
||||||
{
|
{
|
||||||
using namespace rack;
|
using namespace rack;
|
||||||
|
|
||||||
|
window::destroy();
|
||||||
|
ui::destroy();
|
||||||
|
|
||||||
// discord::destroy();
|
// discord::destroy();
|
||||||
library::destroy();
|
library::destroy();
|
||||||
midi::destroy();
|
midi::destroy();
|
||||||
|
@ -104,9 +115,9 @@ struct Initializer {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static Initializer& getInitializerInstance()
|
static const Initializer& getInitializerInstance()
|
||||||
{
|
{
|
||||||
static Initializer init;
|
static const Initializer init;
|
||||||
return init;
|
return init;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <window/Window.hpp>
|
#include <window/Window.hpp>
|
||||||
|
|
||||||
#include "DistrhoUI.hpp"
|
#include "DistrhoUI.hpp"
|
||||||
|
#include "ResizeHandle.hpp"
|
||||||
|
|
||||||
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window) { return nullptr; }
|
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window) { return nullptr; }
|
||||||
GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char*) {}
|
GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char*) {}
|
||||||
|
@ -32,6 +33,10 @@ GLFWAPI int glfwGetKeyScancode(int key) { return 0; }
|
||||||
namespace rack {
|
namespace rack {
|
||||||
namespace window {
|
namespace window {
|
||||||
DISTRHO_NAMESPACE::UI* lastUI = nullptr;
|
DISTRHO_NAMESPACE::UI* lastUI = nullptr;
|
||||||
|
|
||||||
|
void mouseButtonCallback(Window* win, int button, int action, int mods);
|
||||||
|
void cursorPosCallback(Window* win, double xpos, double ypos);
|
||||||
|
void scrollCallback(Window* win, double x, double y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,35 +44,33 @@ START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
struct Initializer {
|
struct Initializer2 {
|
||||||
Initializer()
|
Initializer2()
|
||||||
{
|
{
|
||||||
using namespace rack;
|
using namespace rack;
|
||||||
|
|
||||||
ui::init();
|
|
||||||
window::init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~Initializer()
|
~Initializer2()
|
||||||
{
|
{
|
||||||
using namespace rack;
|
using namespace rack;
|
||||||
|
|
||||||
window::destroy();
|
|
||||||
ui::destroy();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static Initializer& getInitializerInstance()
|
static const Initializer2& getInitializer2Instance()
|
||||||
{
|
{
|
||||||
static Initializer init;
|
static const Initializer2 init;
|
||||||
return init;
|
return init;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CVCRackUI : public UI
|
class CVCRackUI : public UI
|
||||||
{
|
{
|
||||||
|
ResizeHandle fResizeHandle;
|
||||||
public:
|
public:
|
||||||
CVCRackUI()
|
CVCRackUI()
|
||||||
: UI(1280, 720)
|
: UI(1280, 720),
|
||||||
|
fResizeHandle(this)
|
||||||
{
|
{
|
||||||
using namespace rack;
|
using namespace rack;
|
||||||
|
|
||||||
|
@ -97,11 +100,16 @@ public:
|
||||||
contextSet(NULL);
|
contextSet(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onNanoDisplay() override
|
void onDisplay() override
|
||||||
{
|
{
|
||||||
APP->window->step();
|
APP->window->step();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uiIdle() override
|
||||||
|
{
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* --------------------------------------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------------------------------------
|
||||||
* DSP/Plugin Callbacks */
|
* DSP/Plugin Callbacks */
|
||||||
|
@ -116,6 +124,61 @@ protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool onMouse(const MouseEvent& ev) override
|
||||||
|
{
|
||||||
|
int button;
|
||||||
|
int mods = 0;
|
||||||
|
int action = ev.press;
|
||||||
|
|
||||||
|
if (ev.mod & kModifierControl)
|
||||||
|
mods |= GLFW_MOD_CONTROL;
|
||||||
|
if (ev.mod & kModifierShift)
|
||||||
|
mods |= GLFW_MOD_SHIFT;
|
||||||
|
if (ev.mod & kModifierAlt)
|
||||||
|
mods |= GLFW_MOD_ALT;
|
||||||
|
|
||||||
|
switch (ev.button)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
button = GLFW_MOUSE_BUTTON_MIDDLE;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
button = GLFW_MOUSE_BUTTON_LEFT;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
button = GLFW_MOUSE_BUTTON_RIGHT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
button = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseButtonCallback(APP->window, button, action, mods);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool onMotion(const MotionEvent& ev) override
|
||||||
|
{
|
||||||
|
cursorPosCallback(APP->window, ev.pos.getX(), ev.pos.getY());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool onScroll(const ScrollEvent& ev) override
|
||||||
|
{
|
||||||
|
scrollCallback(APP->window, ev.delta.getX(), ev.delta.getY());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void onResize(const ResizeEvent& ev) override
|
||||||
|
{
|
||||||
|
UI::onResize(ev);
|
||||||
|
// APP->window->setSize(rack::math::Vec(ev.size.getWidth(), ev.size.getHeight()));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO uiFocus
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
Set our UI class as non-copyable and add a leak detector just in case.
|
Set our UI class as non-copyable and add a leak detector just in case.
|
||||||
|
@ -128,7 +191,7 @@ private:
|
||||||
|
|
||||||
UI* createUI()
|
UI* createUI()
|
||||||
{
|
{
|
||||||
getInitializerInstance();
|
getInitializer2Instance();
|
||||||
return new CVCRackUI();
|
return new CVCRackUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#define DISTRHO_PLUGIN_BRAND "DISTRHO"
|
#define DISTRHO_PLUGIN_BRAND "DISTRHO"
|
||||||
#define DISTRHO_PLUGIN_NAME "CVCRack"
|
#define DISTRHO_PLUGIN_NAME "CVCRack"
|
||||||
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/plugins/glBars"
|
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/plugins/CVCRack"
|
||||||
|
|
||||||
#define DISTRHO_PLUGIN_HAS_UI 1
|
#define DISTRHO_PLUGIN_HAS_UI 1
|
||||||
#define DISTRHO_PLUGIN_NUM_INPUTS 2
|
#define DISTRHO_PLUGIN_NUM_INPUTS 2
|
||||||
|
@ -30,8 +30,8 @@
|
||||||
// #define DISTRHO_PLUGIN_VST3_CATEGORIES "Fx|Analyzer"
|
// #define DISTRHO_PLUGIN_VST3_CATEGORIES "Fx|Analyzer"
|
||||||
// #define DISTRHO_PLUGIN_HAS_EMBED_UI 1
|
// #define DISTRHO_PLUGIN_HAS_EMBED_UI 1
|
||||||
// #define DISTRHO_PLUGIN_HAS_EXTERNAL_UI 1
|
// #define DISTRHO_PLUGIN_HAS_EXTERNAL_UI 1
|
||||||
#define DISTRHO_UI_USE_NANOVG 1
|
// #define DISTRHO_UI_USE_NANOVG 1
|
||||||
#define DISTRHO_UI_USER_RESIZABLE 1
|
#define DISTRHO_UI_USER_RESIZABLE 0
|
||||||
|
|
||||||
enum Parameters {
|
enum Parameters {
|
||||||
kParameterCount
|
kParameterCount
|
||||||
|
|
|
@ -17,13 +17,13 @@ FILES_DSP = \
|
||||||
|
|
||||||
FILES_UI = \
|
FILES_UI = \
|
||||||
CVCRackUI.cpp \
|
CVCRackUI.cpp \
|
||||||
dep.cpp \
|
|
||||||
Window.cpp
|
Window.cpp
|
||||||
|
|
||||||
# --------------------------------------------------------------
|
# --------------------------------------------------------------
|
||||||
# Import base definitions
|
# Import base definitions
|
||||||
|
|
||||||
# UI_TYPE = external
|
# UI_TYPE = external
|
||||||
|
SKIP_NANOVG = true
|
||||||
include ../../dpf/Makefile.base.mk
|
include ../../dpf/Makefile.base.mk
|
||||||
|
|
||||||
# --------------------------------------------------------------
|
# --------------------------------------------------------------
|
||||||
|
@ -33,6 +33,7 @@ FILES_DSP += Rack/dep/pffft/pffft.c
|
||||||
FILES_DSP += Rack/dep/pffft/fftpack.c
|
FILES_DSP += Rack/dep/pffft/fftpack.c
|
||||||
|
|
||||||
FILES_UI += Rack/dep/oui-blendish/blendish.c
|
FILES_UI += Rack/dep/oui-blendish/blendish.c
|
||||||
|
FILES_UI += Rack/dep/nanovg/src/nanovg.c
|
||||||
|
|
||||||
# FIXME dont use this
|
# FIXME dont use this
|
||||||
FILES_UI += Rack/dep/osdialog/osdialog.c
|
FILES_UI += Rack/dep/osdialog/osdialog.c
|
||||||
|
@ -46,7 +47,7 @@ endif
|
||||||
|
|
||||||
FILES_DSP += $(wildcard Rack/src/*.c)
|
FILES_DSP += $(wildcard Rack/src/*.c)
|
||||||
FILES_DSP += $(wildcard Rack/src/*/*.c)
|
FILES_DSP += $(wildcard Rack/src/*/*.c)
|
||||||
FILES_DSP += $(filter-out Rack/src/dep.cpp Rack/src/gamepad.cpp Rack/src/rtaudio.cpp Rack/src/rtmidi.cpp, $(wildcard Rack/src/*.cpp))
|
FILES_DSP += $(filter-out Rack/src/gamepad.cpp Rack/src/rtaudio.cpp Rack/src/rtmidi.cpp, $(wildcard Rack/src/*.cpp))
|
||||||
FILES_DSP += $(filter-out Rack/src/window/Window.cpp, $(wildcard Rack/src/*/*.cpp))
|
FILES_DSP += $(filter-out Rack/src/window/Window.cpp, $(wildcard Rack/src/*/*.cpp))
|
||||||
|
|
||||||
EXTRA_LIBS = Rack/dep/lib/libcrypto.a
|
EXTRA_LIBS = Rack/dep/lib/libcrypto.a
|
||||||
|
@ -85,14 +86,14 @@ Rack/dep/lib/libcrypto.a: Rack/dep/lib/libssl.a
|
||||||
# Extra flags for VCV stuff
|
# Extra flags for VCV stuff
|
||||||
|
|
||||||
BASE_FLAGS += -D_APP_VERSION=2.git.0
|
BASE_FLAGS += -D_APP_VERSION=2.git.0
|
||||||
BASE_FLAGS += -I$(DPF_PATH)/dgl/src/nanovg
|
# BASE_FLAGS += -I$(DPF_PATH)/dgl/src/nanovg
|
||||||
BASE_FLAGS += -IRack/include
|
BASE_FLAGS += -IRack/include
|
||||||
BASE_FLAGS += -IRack/dep/include
|
BASE_FLAGS += -IRack/dep/include
|
||||||
BASE_FLAGS += -IRack/dep/filesystem/include
|
BASE_FLAGS += -IRack/dep/filesystem/include
|
||||||
BASE_FLAGS += -IRack/dep/fuzzysearchdatabase/src
|
BASE_FLAGS += -IRack/dep/fuzzysearchdatabase/src
|
||||||
BASE_FLAGS += -IRack/dep/glfw/deps
|
BASE_FLAGS += -IRack/dep/glfw/deps
|
||||||
BASE_FLAGS += -IRack/dep/glfw/include
|
BASE_FLAGS += -IRack/dep/glfw/include
|
||||||
# BASE_FLAGS += -IRack/dep/nanovg/src
|
BASE_FLAGS += -IRack/dep/nanovg/src
|
||||||
BASE_FLAGS += -IRack/dep/nanosvg/src
|
BASE_FLAGS += -IRack/dep/nanosvg/src
|
||||||
BASE_FLAGS += -IRack/dep/osdialog
|
BASE_FLAGS += -IRack/dep/osdialog
|
||||||
BASE_FLAGS += -IRack/dep/oui-blendish
|
BASE_FLAGS += -IRack/dep/oui-blendish
|
||||||
|
|
185
plugins/CVCRack/ResizeHandle.hpp
Normal file
185
plugins/CVCRack/ResizeHandle.hpp
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
/*
|
||||||
|
* Resize handle for DPF
|
||||||
|
* Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any purpose with
|
||||||
|
* or without fee is hereby granted, provided that the above copyright notice and this
|
||||||
|
* permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
|
||||||
|
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
|
||||||
|
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "TopLevelWidget.hpp"
|
||||||
|
#include "../dgl/Color.hpp"
|
||||||
|
|
||||||
|
START_NAMESPACE_DGL
|
||||||
|
|
||||||
|
/** Resize handle for DPF windows, will sit on bottom-right. */
|
||||||
|
class ResizeHandle : public TopLevelWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Constructor for placing this handle on top of a window. */
|
||||||
|
explicit ResizeHandle(Window& window)
|
||||||
|
: TopLevelWidget(window),
|
||||||
|
handleSize(16),
|
||||||
|
resizing(false)
|
||||||
|
{
|
||||||
|
resetArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Overloaded constructor, will fetch the window from an existing top-level widget. */
|
||||||
|
explicit ResizeHandle(TopLevelWidget* const tlw)
|
||||||
|
: TopLevelWidget(tlw->getWindow()),
|
||||||
|
handleSize(16),
|
||||||
|
resizing(false)
|
||||||
|
{
|
||||||
|
resetArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the handle size, minimum 16. */
|
||||||
|
void setHandleSize(const uint size)
|
||||||
|
{
|
||||||
|
handleSize = std::max(16u, size);
|
||||||
|
resetArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void onDisplay() override
|
||||||
|
{
|
||||||
|
const GraphicsContext& context(getGraphicsContext());
|
||||||
|
const double lineWidth = 1.0 * getScaleFactor();
|
||||||
|
|
||||||
|
#ifdef DGL_OPENGL
|
||||||
|
glUseProgram(0);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// draw white lines, 1px wide
|
||||||
|
Color(1.0f, 1.0f, 1.0f).setFor(context);
|
||||||
|
l1.draw(context, lineWidth);
|
||||||
|
l2.draw(context, lineWidth);
|
||||||
|
l3.draw(context, lineWidth);
|
||||||
|
|
||||||
|
// draw black lines, offset by 1px and 1px wide
|
||||||
|
Color(0.0f, 0.0f, 0.0f).setFor(context);
|
||||||
|
Line<double> l1b(l1), l2b(l2), l3b(l3);
|
||||||
|
l1b.moveBy(lineWidth, lineWidth);
|
||||||
|
l2b.moveBy(lineWidth, lineWidth);
|
||||||
|
l3b.moveBy(lineWidth, lineWidth);
|
||||||
|
l1b.draw(context, lineWidth);
|
||||||
|
l2b.draw(context, lineWidth);
|
||||||
|
l3b.draw(context, lineWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool onMouse(const MouseEvent& ev) override
|
||||||
|
{
|
||||||
|
if (ev.button != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (ev.press && area.contains(ev.pos))
|
||||||
|
{
|
||||||
|
resizing = true;
|
||||||
|
resizingSize = Size<double>(getWidth(), getHeight());
|
||||||
|
lastResizePoint = ev.pos;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resizing && ! ev.press)
|
||||||
|
{
|
||||||
|
resizing = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool onMotion(const MotionEvent& ev) override
|
||||||
|
{
|
||||||
|
if (! resizing)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const Size<double> offset(ev.pos.getX() - lastResizePoint.getX(),
|
||||||
|
ev.pos.getY() - lastResizePoint.getY());
|
||||||
|
|
||||||
|
resizingSize += offset;
|
||||||
|
lastResizePoint = ev.pos;
|
||||||
|
|
||||||
|
// TODO min width, min height
|
||||||
|
const uint minWidth = 16;
|
||||||
|
const uint minHeight = 16;
|
||||||
|
|
||||||
|
if (resizingSize.getWidth() < minWidth)
|
||||||
|
resizingSize.setWidth(minWidth);
|
||||||
|
if (resizingSize.getWidth() > 16384)
|
||||||
|
resizingSize.setWidth(16384);
|
||||||
|
if (resizingSize.getHeight() < minHeight)
|
||||||
|
resizingSize.setHeight(minHeight);
|
||||||
|
if (resizingSize.getHeight() > 16384)
|
||||||
|
resizingSize.setHeight(16384);
|
||||||
|
|
||||||
|
setSize(resizingSize.getWidth(), resizingSize.getHeight());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onResize(const ResizeEvent& ev) override
|
||||||
|
{
|
||||||
|
TopLevelWidget::onResize(ev);
|
||||||
|
resetArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Rectangle<uint> area;
|
||||||
|
Line<double> l1, l2, l3;
|
||||||
|
uint handleSize;
|
||||||
|
|
||||||
|
// event handling state
|
||||||
|
bool resizing;
|
||||||
|
Point<double> lastResizePoint;
|
||||||
|
Size<double> resizingSize;
|
||||||
|
|
||||||
|
void resetArea()
|
||||||
|
{
|
||||||
|
const double scaleFactor = getScaleFactor();
|
||||||
|
const uint margin = 0.0 * scaleFactor;
|
||||||
|
const uint size = handleSize * scaleFactor;
|
||||||
|
|
||||||
|
area = Rectangle<uint>(getWidth() - size - margin,
|
||||||
|
getHeight() - size - margin,
|
||||||
|
size, size);
|
||||||
|
|
||||||
|
recreateLines(area.getX(), area.getY(), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void recreateLines(const uint x, const uint y, const uint size)
|
||||||
|
{
|
||||||
|
uint linesize = size;
|
||||||
|
uint offset = 0;
|
||||||
|
|
||||||
|
// 1st line, full diagonal size
|
||||||
|
l1.setStartPos(x + size, y);
|
||||||
|
l1.setEndPos(x, y + size);
|
||||||
|
|
||||||
|
// 2nd line, bit more to the right and down, cropped
|
||||||
|
offset += size / 3;
|
||||||
|
linesize -= size / 3;
|
||||||
|
l2.setStartPos(x + linesize + offset, y + offset);
|
||||||
|
l2.setEndPos(x + offset, y + linesize + offset);
|
||||||
|
|
||||||
|
// 3rd line, even more right and down
|
||||||
|
offset += size / 3;
|
||||||
|
linesize -= size / 3;
|
||||||
|
l3.setStartPos(x + linesize + offset, y + offset);
|
||||||
|
l3.setEndPos(x + offset, y + linesize + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ResizeHandle)
|
||||||
|
};
|
||||||
|
|
||||||
|
END_NAMESPACE_DGL
|
|
@ -68,6 +68,7 @@ std::shared_ptr<Image> Image::load(const std::string& filename) {
|
||||||
|
|
||||||
struct Window::Internal {
|
struct Window::Internal {
|
||||||
DISTRHO_NAMESPACE::UI* ui;
|
DISTRHO_NAMESPACE::UI* ui;
|
||||||
|
math::Vec size;
|
||||||
|
|
||||||
std::string lastWindowTitle;
|
std::string lastWindowTitle;
|
||||||
|
|
||||||
|
@ -94,11 +95,18 @@ struct Window::Internal {
|
||||||
Window::Window() {
|
Window::Window() {
|
||||||
internal = new Internal;
|
internal = new Internal;
|
||||||
internal->ui = lastUI;
|
internal->ui = lastUI;
|
||||||
|
internal->size = minWindowSize;
|
||||||
vg = lastUI->getContext();
|
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
// Set up GLEW
|
||||||
|
glewExperimental = GL_TRUE;
|
||||||
|
err = glewInit();
|
||||||
|
if (err != GLEW_OK) {
|
||||||
|
osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Could not initialize GLEW. Does your graphics card support OpenGL 2.0 or greater? If so, make sure you have the latest graphics drivers installed.");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
const GLubyte* vendor = glGetString(GL_VENDOR);
|
const GLubyte* vendor = glGetString(GL_VENDOR);
|
||||||
const GLubyte* renderer = glGetString(GL_RENDERER);
|
const GLubyte* renderer = glGetString(GL_RENDERER);
|
||||||
const GLubyte* version = glGetString(GL_VERSION);
|
const GLubyte* version = glGetString(GL_VERSION);
|
||||||
|
@ -109,6 +117,21 @@ Window::Window() {
|
||||||
// GLEW generates GL error because it calls glGetString(GL_EXTENSIONS), we'll consume it here.
|
// GLEW generates GL error because it calls glGetString(GL_EXTENSIONS), we'll consume it here.
|
||||||
glGetError();
|
glGetError();
|
||||||
|
|
||||||
|
// Set up NanoVG
|
||||||
|
int nvgFlags = NVG_ANTIALIAS;
|
||||||
|
#if defined NANOVG_GL2
|
||||||
|
vg = nvgCreateGL2(nvgFlags);
|
||||||
|
fbVg = nvgCreateSharedGL2(vg, nvgFlags);
|
||||||
|
#elif defined NANOVG_GL3
|
||||||
|
vg = nvgCreateGL3(nvgFlags);
|
||||||
|
#elif defined NANOVG_GLES2
|
||||||
|
vg = nvgCreateGLES2(nvgFlags);
|
||||||
|
#endif
|
||||||
|
if (!vg) {
|
||||||
|
osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Could not initialize NanoVG. Does your graphics card support OpenGL 2.0 or greater? If so, make sure you have the latest graphics drivers installed.");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// Load default Blendish font
|
// Load default Blendish font
|
||||||
uiFont = loadFont(asset::system("res/fonts/DejaVuSans.ttf"));
|
uiFont = loadFont(asset::system("res/fonts/DejaVuSans.ttf"));
|
||||||
bndSetFont(uiFont->handle);
|
bndSetFont(uiFont->handle);
|
||||||
|
@ -132,17 +155,26 @@ Window::~Window() {
|
||||||
|
|
||||||
// nvgDeleteClone(fbVg);
|
// nvgDeleteClone(fbVg);
|
||||||
|
|
||||||
|
#if defined NANOVG_GL2
|
||||||
|
nvgDeleteGL2(vg);
|
||||||
|
nvgDeleteGL2(fbVg);
|
||||||
|
#elif defined NANOVG_GL3
|
||||||
|
nvgDeleteGL3(vg);
|
||||||
|
#elif defined NANOVG_GLES2
|
||||||
|
nvgDeleteGLES2(vg);
|
||||||
|
#endif
|
||||||
|
|
||||||
delete internal;
|
delete internal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
math::Vec Window::getSize() {
|
math::Vec Window::getSize() {
|
||||||
return math::Vec(1280, 720);
|
return internal->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Window::setSize(math::Vec size) {
|
void Window::setSize(math::Vec size) {
|
||||||
size = size.max(minWindowSize);
|
internal->size = size.max(minWindowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -163,14 +195,12 @@ void Window::step() {
|
||||||
nvgReset(vg);
|
nvgReset(vg);
|
||||||
|
|
||||||
bndSetFont(uiFont->handle);
|
bndSetFont(uiFont->handle);
|
||||||
nvgFillColor(vg, nvgRGBf(1, 1, 1));
|
|
||||||
nvgStrokeColor(vg, nvgRGBf(1, 1, 1));
|
|
||||||
|
|
||||||
// Poll events
|
// Poll events
|
||||||
// Save and restore context because event handler set their own context based on which window they originate from.
|
// Save and restore context because event handler set their own context based on which window they originate from.
|
||||||
Context* context = contextGet();
|
// Context* context = contextGet();
|
||||||
// glfwPollEvents();
|
// glfwPollEvents();
|
||||||
contextSet(context);
|
// contextSet(context);
|
||||||
|
|
||||||
// Set window title
|
// Set window title
|
||||||
std::string windowTitle = APP_NAME + " " + APP_EDITION_NAME + " " + APP_VERSION;
|
std::string windowTitle = APP_NAME + " " + APP_EDITION_NAME + " " + APP_VERSION;
|
||||||
|
@ -223,9 +253,9 @@ void Window::step() {
|
||||||
APP->scene->draw(args);
|
APP->scene->draw(args);
|
||||||
t3 = system::getTime();
|
t3 = system::getTime();
|
||||||
|
|
||||||
// glViewport(0, -winHeight, fbWidth, fbHeight);
|
glViewport(0, 0, fbWidth, fbHeight);
|
||||||
// glClearColor(0.0, 0.0, 0.0, 1.0);
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||||
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
nvgEndFrame(vg);
|
nvgEndFrame(vg);
|
||||||
t4 = system::getTime();
|
t4 = system::getTime();
|
||||||
}
|
}
|
||||||
|
@ -370,6 +400,56 @@ bool& Window::fbDirtyOnSubpixelChange() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mouseButtonCallback(Window* win, int button, int action, int mods) {
|
||||||
|
/*
|
||||||
|
#if defined ARCH_MAC
|
||||||
|
// Remap Ctrl-left click to right click on Mac
|
||||||
|
if (button == GLFW_MOUSE_BUTTON_LEFT && (mods & RACK_MOD_MASK) == GLFW_MOD_CONTROL) {
|
||||||
|
button = GLFW_MOUSE_BUTTON_RIGHT;
|
||||||
|
mods &= ~GLFW_MOD_CONTROL;
|
||||||
|
}
|
||||||
|
// Remap Ctrl-shift-left click to middle click on Mac
|
||||||
|
if (button == GLFW_MOUSE_BUTTON_LEFT && (mods & RACK_MOD_MASK) == (GLFW_MOD_CONTROL | GLFW_MOD_SHIFT)) {
|
||||||
|
button = GLFW_MOUSE_BUTTON_MIDDLE;
|
||||||
|
mods &= ~(GLFW_MOD_CONTROL | GLFW_MOD_SHIFT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
APP->event->handleButton(win->internal->lastMousePos, button, action, mods);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cursorPosCallback(Window* win, double xpos, double ypos) {
|
||||||
|
math::Vec mousePos = math::Vec(xpos, ypos).div(win->pixelRatio / win->windowRatio).round();
|
||||||
|
math::Vec mouseDelta = mousePos.minus(win->internal->lastMousePos);
|
||||||
|
|
||||||
|
// Workaround for GLFW warping mouse to a different position when the cursor is locked or unlocked.
|
||||||
|
if (win->internal->ignoreNextMouseDelta) {
|
||||||
|
win->internal->ignoreNextMouseDelta = false;
|
||||||
|
mouseDelta = math::Vec();
|
||||||
|
}
|
||||||
|
|
||||||
|
win->internal->lastMousePos = mousePos;
|
||||||
|
|
||||||
|
APP->event->handleHover(mousePos, mouseDelta);
|
||||||
|
|
||||||
|
// Keyboard/mouse MIDI driver
|
||||||
|
math::Vec scaledPos(xpos / win->internal->ui->getWidth(), ypos / win->internal->ui->getHeight());
|
||||||
|
keyboard::mouseMove(scaledPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scrollCallback(Window* win, double x, double y) {
|
||||||
|
math::Vec scrollDelta = math::Vec(x, y);
|
||||||
|
#if defined ARCH_MAC
|
||||||
|
scrollDelta = scrollDelta.mult(10.0);
|
||||||
|
#else
|
||||||
|
scrollDelta = scrollDelta.mult(50.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
APP->event->handleScroll(win->internal->lastMousePos, scrollDelta);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
// This source file compiles those annoying implementation-in-header libraries
|
|
||||||
|
|
||||||
#include <common.hpp> // for fopen_u8
|
|
||||||
|
|
||||||
#define GLEW_STATIC
|
|
||||||
#define GLEW_NO_GLU
|
|
||||||
#include <GL/glew.h>
|
|
||||||
|
|
||||||
#include <nanovg.h>
|
|
||||||
|
|
||||||
#define BLENDISH_IMPLEMENTATION
|
|
||||||
#include <blendish.h>
|
|
||||||
|
|
||||||
#define NANOSVG_IMPLEMENTATION
|
|
||||||
#define NANOSVG_ALL_COLOR_KEYWORDS
|
|
||||||
#include <nanosvg.h>
|
|
||||||
|
|
||||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
|
||||||
#include <stb_image_write.h>
|
|
Loading…
Add table
Add a link
Reference in a new issue