#define _BSD_SOURCE 1 #include /* for usleep */ #include #include #include #include #include #include #include #include #include #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; }