@@ -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 | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
@@ -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 { | |||||
Initializer() | |||||
struct Initializer2 { | |||||
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_USER_RESIZABLE 1 | |||||
// #define DISTRHO_UI_USE_NANOVG 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 | ||||
@@ -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; | ||||
vg = lastUI->getContext(); | |||||
internal->size = minWindowSize; | |||||
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); | |||||
// glClearColor(0.0, 0.0, 0.0, 1.0); | |||||
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | |||||
glViewport(0, 0, fbWidth, fbHeight); | |||||
glClearColor(0.0, 0.0, 0.0, 1.0); | |||||
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> |