|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- /*
- ZynAddSubFX - a software synthesizer
-
- Fl_Osc_Tree.H - OSC Based Tree
- Copyright (C) 2016 Mark McCurry
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- */
- #pragma once
- #include <rtosc/ports.h>
- #include "Fl_Osc_Interface.h"
- #include <FL/Fl_Tree.H>
-
- class Fl_Osc_Tree: public Fl_Tree
- {
- public:
- Fl_Osc_Tree(int X, int Y, int W, int H, const char *L=0)
- :Fl_Tree(X,Y,W,H,L)
- {
- root_label("");
- add("nil");
- add("/nil/nil");
- close(first());
- callback(Fl_Osc_Tree::cb, NULL);
- }
-
- void sprout(std::string s)
- {
- if(s[s.length()-1] == '/') {
- attach(s);
- attach(s+"nil");
- close(s.c_str());
- } else
- attach(s);
- }
-
- void attach(std::string s)
- {
- if(!find_item(s.c_str()))
- add(s.c_str());
- }
-
- static void cb(Fl_Widget *w, void*)
- {
- using namespace rtosc;
- Fl_Osc_Tree *t=(Fl_Osc_Tree*)w;
- int reason = t->callback_reason();
-
- char pathname[1024];
- t->item_pathname(pathname, sizeof(pathname), t->callback_item());
-
-
- if(reason==1) {
- char *colon = index(pathname, ':');
- if(colon) {
- *colon = 0;
- t->osc->writeValue("/learn", string(pathname));
- }
- }
-
- if(reason==3) //Populate fields
- {
- const Ports &p = *Fl_Osc_Tree::subtree_lookup(t->root_ports,pathname+1);
- printf("ok, I got the tree\n");
- if(auto *i = t->find_item((std::string(pathname)+"/"+"nil").c_str()))
- t->remove(i);
- for(const Port &port : p) {
- printf("handling '%s'\n", port.name);
- const bool subnodes = index(port.name, '/');
- const bool enumerated = index(port.name, '#');
- const string path = std::string(pathname)+"/"+port.name;
- if(!enumerated) {
- t->sprout(path);
- } else {
- char tmpa[1024];
- char tmpb[1024];
- strncpy(tmpa, path.c_str(), 1024);
- char *pound = index(tmpa, '#');
- int N = atoi(pound+1);
- *pound = 0;
- char terminal = subnodes ? '/' : '\0';
-
- for(int i = 0; i < N; ++i) {
- snprintf(tmpb, 1024, "%s%d%c",
- tmpa, i, terminal);
- t->sprout(tmpb);
- }
- }
- }
-
- }
- }
-
- static const rtosc::Ports *subtree_lookup(const rtosc::Ports *p, std::string s)
- {
- using namespace rtosc;
- if(s=="")
- return p;
-
- if(s[s.length()-1] != '/')
- s += '/';
-
- for(const Port &port : *p) {
- const char *name = port.name;
- if(!index(name, '/'))//only accept objects that will have subports
- continue;
- if(rtosc_match(name, s.c_str(), NULL)) {
- return subtree_lookup(port.ports,
- s.substr(index(s.c_str(), '/')-s.c_str()+1));
- }
- }
-
- //TODO else case
- return p;
- }
-
- rtosc::Ports *root_ports;
- Fl_Osc_Interface *osc;
- };
|