pplugins/ptap/ptapui.cpp

300 lines
6.5 KiB
C++

#define _BSD_SOURCE 1
#include <unistd.h> /* for usleep */
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <lv2.h>
#include <lv2/lv2plug.in/ns/extensions/ui/ui.h>
#include <pugl/pugl.h>
#include <limits.h>
#include "../pui/pui.h"
#define TAPS 6
/*struct PTapUI : PTextures {
PuglView *view;
pthread_t thread;
LV2UI_Write_Function write;
LV2UI_Controller controller;
int width;
int height;
bool exit;
int mx;
int my;
int mb;
int mm;
Widget *active;
Container *widget;
void InitWidgets();
};*/
struct PTapUI : PUi {
pthread_t thread;
LV2UI_Write_Function write;
LV2UI_Controller controller;
int width;
int height;
bool exit;
virtual ~PTapUI() {}
void InitWidgets();
/* virtual */ void ParameterChanged(const Widget *w);
};
void PTapUI::InitWidgets()
{
widget = new Container();
widget->tex = this;
widget->back = true;
widget->colour = Colour(1, 1, 1, 1);
widget->w = this->width;
widget->h = this->height;
int padding = 4;
int c_w = (this->width - padding * 3) * 0.5f;
int c_h = (this->height - padding * 5) * 0.25f;
int slide_w = 25;
int slide_h = c_h - 25;
for (int i = 0; i < TAPS + 2; i++) {
Container *c = new Container();
c->x = (i & 1) * (c_w + padding) + padding;
c->y = (i >> 1) * (c_h + padding) + padding;
c->w = c_w;
c->h = c_h;
/*
Container *c3 = new Container();
if (i >= TAPS) c3->colour = Colour(1, 1, 1, 0.2f);
// c3->colour = Colour(0, 0, 0, 0.2f);
// c3->x = c2->x + c2->w + padding;
c3->x = c->x;
c3->y = c->y + 25;
c3->w = slide_w * 2;
c3->h = slide_h;
c->children.push_back(c3);
*/
Container *c2 = new Container();
if (i >= TAPS) c2->colour = Colour(1, 1, 1, 0.2f);
c2->x = c->x;
// c2->x = c3->x + c3->w + padding;
c2->y = c->y + 25;
c2->w = slide_w * TAPS;
c2->h = slide_h;
c->children.push_back(c2);
Container *c3 = new Container();
if (i >= TAPS) c3->colour = Colour(1, 1, 1, 0.2f);
// c3->colour = Colour(0, 0, 0, 0.2f);
c3->x = c2->x + c2->w + padding;
c3->y = c->y + 25;
c3->w = slide_w * 2;
c3->h = slide_h;
c->children.push_back(c3);
Container *c4 = new Container();
if (i >= TAPS) c4->colour = Colour(1, 1, 1, 0.2f);
c4->x = c3->x + c3->w + padding;
// c4->x = c2->x + c2->w + padding;
c4->y = c->y + 25;
c4->w = slide_w;
c4->h = slide_h;
c->children.push_back(c4);
for (int j = 0; j < TAPS; j++) {
Slider *slider = new VSlider();
slider->tex = this;
slider->big = false;
if (i == j) {
slider->colour = Colour(.5f, .7f, 1, 1);
} else {
slider->colour = Colour(.6f, .6f, .6f, 1);
}
slider->x = c2->x + j * slide_w;//(j & 1) * slide_w;
slider->y = c2->y;// + (j >> 1) * slide_h;
slider->w = slide_w;
slider->h = c2->h;
slider->min = -1.f;
slider->max = 1.f;
slider->port = (i * 10) + 4 + j;
// slider->Pad(padding, padding);
c2->children.push_back(slider);
}
for (int j = 0; j < 2; j++) {
Slider *slider = new VSlider();
slider->tex = this;
slider->big = false;
slider->x = c3->x + j * slide_w;//(j & 1) * slide_w;
slider->y = c3->y;// + (j >> 1) * slide_h;
slider->w = slide_w;
slider->h = c3->h;
slider->min = -1.f;
slider->max = 1.f;
slider->port = (i * 10) + 4 + TAPS + j;
// slider->Pad(padding, padding);
c3->children.push_back(slider);
}
for (int j = 0; j < 1; j++) {
Slider *slider = new VSlider();
slider->tex = this;
slider->big = i >= TAPS;
slider->colour = Colour(1, .2f, .2f, 1);
slider->x = c4->x + j * slide_w;//(j & 1) * slide_w;
slider->y = c4->y;// + (j >> 1) * slide_h;
slider->w = slide_w;
slider->h = c4->h;
slider->min = -1.f;
slider->max = 1.f;
slider->port = (i * 10) + 4 + TAPS + 2 + j;
// slider->Pad(padding, padding);
c4->children.push_back(slider);
}
if (i < TAPS) {
Container *c5 = new Container();
c5->x = c4->x + c4->w + padding;
c5->y = c->y + 25;
c5->w = c->w - (c5->x - c->x);
c5->h = slide_h;
c->children.push_back(c5);
Knob *k = new Knob();
k->tex = this;
k->x = c5->x;
k->y = c5->y;
k->w = c5->w;
k->h = c5->h;
k->min = 0.f;
k->max = 10.f;
k->port = (i * 10) + 4 + 9;
// k->Pad(padding, padding);
c5->children.push_back(k);
}
this->widget->children.push_back(c);
}
}
static void *ui_thread(void *ptr)
{
PTapUI *pui = (PTapUI *)ptr;
while (!pui->exit) {
usleep(1000000 / 25);
puglProcessEvents(pui->view);
}
return NULL;
}
void PTapUI::ParameterChanged(const Widget *w)
{
if (w->port == UINT_MAX) return;
this->write(this->controller, w->port, sizeof w->value, 0, &w->value);
}
static LV2UI_Handle ptapui_instantiate(
const LV2UI_Descriptor *descriptor,
const char *plugin_uri,
const char *bundle_path,
LV2UI_Write_Function write_function,
LV2UI_Controller controller,
LV2UI_Widget *widget,
const LV2_Feature *const *host_features)
{
PuglNativeWindow parent = 0;
LV2UI_Resize *resize = NULL;
for (; host_features && *host_features; host_features++) {
if (!strcmp((*host_features)->URI, LV2_UI__parent)) {
parent = (PuglNativeWindow)(*host_features)->data;
} else if (!strcmp((*host_features)->URI, LV2_UI__resize)) {
resize = (LV2UI_Resize *)(*host_features)->data;
}
}
if (!parent) {
fprintf(stderr, "error: ptapui: No parent window provided.\n");
return NULL;
}
PTapUI *pui = new PTapUI();
pui->write = write_function;
pui->controller = controller;
pui->width = 700;
pui->height = 660;
pui->exit = false;
pui->InitWidgets();
pui->view = puglCreate(parent, "PTap", pui->width, pui->height, true);
puglSetHandle(pui->view, pui);
pui->SetFunc();
if (resize) {
resize->ui_resize(resize->handle, pui->width, pui->height);
}
pthread_create(&pui->thread, NULL, ui_thread, pui);
*widget = (void*)puglGetNativeWindow(pui->view);
return pui;
}
static void ptapui_cleanup(LV2UI_Handle ui)
{
PTapUI *pui = (PTapUI *)ui;
pui->exit = true;
pthread_join(pui->thread, NULL);
puglDestroy(pui->view);
delete pui;
}
static void ptapui_port_event(
LV2UI_Handle ui,
uint32_t port_index,
uint32_t buffer_size,
uint32_t format,
const void *buffer)
{
PUi *pui = (PUi *)ui;
Widget *w = pui->widget->GetWidget(port_index);
if (!w) return;
w->SetValue(*((float *)buffer));
pui->Repaint();
}
static const void *ptapui_extension_data(const char *uri)
{
return NULL;
}
static const LV2UI_Descriptor s_lv2uidescriptor =
{
"urn:fuzzle:ptap#X11UI",
&ptapui_instantiate,
&ptapui_cleanup,
&ptapui_port_event,
&ptapui_extension_data,
};
const LV2UI_Descriptor *lv2ui_descriptor(uint32_t index)
{
if (index == 0) {
return &s_lv2uidescriptor;
}
return NULL;
}