(root)/wip/src/point_modulator.cc - Rev 1169
Rev 1166 |
Rev 1174 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* point_modulator.cc
* DIN Is Noise is copyright (c) 2006-2019 Jagannathan Sampath
* For more information, please visit http://dinisnoise.org/
*/
#include "point_modulator.h"
#include "ui_list.h"
#include "console.h"
#include "audio.h"
#include <map>
using namespace std;
#define NUM_WIDGETS 12
#define NUM_WIDGETS_1 (NUM_WIDGETS - 1)
#define DECLARE_WIDGET_ARRAY_wa widget* wa [] = {&title, &all, &none, &invert, &play, &kill, &plus, &fold, &x.depth, &x.bpm, &y.depth, &y.bpm};
extern audio_out aout;
void point_modulator::setup (curve_editor* _ed) {
ed = _ed;
DECLARE_WIDGET_ARRAY_wa
const char* texts [] = {"Point Modulator", "All", "None", "Invert"};
for (int i = 0; i < 4; ++i) {
label* l = dynamic_cast<label*>(wa[i]);
l->set_text (texts[i]);
}
for (int i = 1; i < 8; ++i) dynamic_cast<button*>(wa[i])->set_listener (this);
make_family (&title, &wa[1], NUM_WIDGETS_1);
/*make_hierarchy (&wa[1], 3);
make_hierarchy (&wa[4], 2);*/
for (int i = 4; i < 7; ++i) {
button* wi = dynamic_cast<button*>(wa [i]);
wi->set_size (16);
}
title.set_moveable (1);
title.movlis = this;
/*for (int i = 0; i < NUM_WIDGETS; ++i) {
widget* wi = wa[i];
wi->set_moveable (1);
}*/
fold.set_dir (arrow_button::down);
play.set_dir (arrow_button::right);
widget_load ("d_point_modulator", wa, NUM_WIDGETS);
x.depth.set_text ("X depth");
x.depth.set_value (0);
x.depth.set_delta (ed->obj_chunk.x);
x.depth.set_listener (this);
x.bpm.set_text ("X BPM");
x.bpm.set_delta (1);
x.bpm.set_value (0);
x.bpm.set_listener (this);
y.depth.set_text ("Y depth");
y.depth.set_value (0);
y.depth.set_delta (ed->obj_chunk.y);
y.depth.set_listener (this);
y.bpm.set_text ("Y BPM");
y.bpm.set_delta (1);
y.bpm.set_value (0);
y.bpm.set_listener (this);
folded = 0;
moved ();
}
extern multi_curve ran_mod_width_crv, ran_mod_height_crv;
mod_dat::mod_dat (hit_t& h, state_button* _sb, float _bpm) : hit (h), sb (_sb), mod (&ran_mod_width_crv, &ran_mod_height_crv), init (h.get()) {
mod.active = 1;
mod.am.bv.set_bpm (_bpm, aout.samples_per_channel);
mod.fm.bv.set_bpm (_bpm, aout.samples_per_channel);
}
state_button* point_modulator::add (hit_t& h) {
#ifdef __EVALUATION__
if (nlst == 1) {
cons << RED << "Can add more point modulators in the Licensed Version of DIN Is Noise" << eol;
return 0;
}
#endif
on_lst (_desel);
state_button* sb = new state_button;
sb->set_pos (sbx, sby);
sbx += state_button::SIZE2;
title.add_child (sb);
const float bpm = 10;
mod_dat md (h, sb, bpm);
lst.push_back (md);
++nlst;
sb->set_state (1);
return sb;
}
point_modulator::point_modulator () {
++ref;
}
point_modulator::~point_modulator () {
for (list<mod_dat>::iterator i = lst.begin (), j = lst.end(); i != j; ++i) {
mod_dat& md = *i;
state_button* sb = md.sb;
delete sb;
}
if (--ref == 0) {
DECLARE_WIDGET_ARRAY_wa
widget_save ("d_point_modulator", wa, NUM_WIDGETS);
}
}
int point_modulator::handle_input () {
if (folded == 0) {
for (list<mod_dat>::iterator i = lst.begin (), j = lst.end(); i != j; ++i) {
state_button* sb = (*i).sb;
if (sb->handle_input()) return 1;
}
DECLARE_WIDGET_ARRAY_wa
for (int i = 0; i < NUM_WIDGETS; ++i) {
widget* wi = wa[i];
if (wi->handle_input()) return 1;
}
} else {
if (fold.handle_input ()) return 1;
else return title.handle_input ();
}
return 0;
}
/*void point_modulator::remove () {
int p = nlst;
for (list<mod_dat>::iterator i = lst.begin (), j = lst.end(); i != j;) {
mod_dat& md = *i;
state_button* sb = md.sb;
if (sb->state) {
title.remove_child (sb);
delete sb;
i = lst.erase (i);
j = lst.end ();
--nlst;
} else ++i;
}
rearrange ();
int q = p - nlst;
if (q) cons << RED << "Removed " << q << " point modulations" << eol;
}*/
void point_modulator::remove (const hit_t& h) {
int p = nlst;
for (list<mod_dat>::iterator i = lst.begin (), j = lst.end(); i != j;) {
mod_dat& md = *i;
state_button* sb = md.sb;
int s = 0; if (h()) s = md.hit.matched_id (h); else s = sb->state;
if (s) {
title.remove_child (sb);
delete sb;
i = lst.erase (i);
j = lst.end ();
--nlst;
} else ++i;
}
rearrange ();
int q = p - nlst;
if (q) cons << RED << "Removed " << q << " point modulations" << eol;
}
void point_modulator::rearrange () {
int sx = title.extents.left;
for (list<mod_dat>::iterator i = lst.begin (), j = lst.end(); i != j; ++i) {
mod_dat& md = *i;
state_button* sb = md.sb;
sb->set_pos (sx, sby);
sx += state_button::SIZE2;
}
sbx = sx;
}
void point_modulator::on_lst (const op_cap& op) {
for (list<mod_dat>::iterator i = lst.begin (), j = lst.end(); i != j; ++i) {
mod_dat& md = *i;
state_button* sb = md.sb;
sb->set_state (op (sb->state));
}
}
void point_modulator::changed (field& f) {
if (&f == &x.depth.f_value) {
for (list<mod_dat>::iterator i = lst.begin (), j = lst.end(); i != j; ++i) {
mod_dat& md = *i;
if (md.sb->state) {
md.mod.fm.depth += x.depth.dir_delta();
}
}
} else if (&f == &y.depth.f_value) {
for (list<mod_dat>::iterator i = lst.begin (), j = lst.end(); i != j; ++i) {
mod_dat& md = *i;
if (md.sb->state) {
md.mod.am.depth += y.depth.dir_delta();
}
}
} else if (&f == &x.bpm.f_value) {
for (list<mod_dat>::iterator i = lst.begin (), j = lst.end(); i != j; ++i) {
mod_dat& md = *i;
if (md.sb->state) {
md.mod.fm.bv.set_bpm (md.mod.fm.bv.bpm + x.bpm.dir_delta(), aout.samples_per_channel);
}
}
} else if (&f == &y.bpm.f_value) {
for (list<mod_dat>::iterator i = lst.begin (), j = lst.end(); i != j; ++i) {
mod_dat& md = *i;
if (md.sb->state) {
md.mod.am.bv.set_bpm (md.mod.am.bv.bpm + y.bpm.dir_delta(), aout.samples_per_channel);
}
}
}
}
void point_modulator::bg () {
map<multi_curve*, int> eval;
for (list<mod_dat>::iterator i = lst.begin (), j = lst.end(); i != j; ++i) {
mod_dat& md = *i;
modulator& mod = md.mod;
if (mod.active) {
mod.calc ();
ed->move (md.hit, md.init.x + mod.fm.result, md.init.y + mod.am.result, 0);
eval[md.hit.crv] = md.hit.crv_id;
}
}
for (map<multi_curve*, int>::iterator i = eval.begin (), j = eval.end (); i != j; ++i) {
pair<multi_curve*, int> e = *i;
curve_info& ci = ed->curveinfo [e.second];
multi_curve* crv = e.first;
crv->evaluate ();
ci.lisner->edited (ed, e.second);
}
}
void point_modulator::clicked (button& b) {
if (&b == &plus) {
CRVED->modulate_point ();
} else if (&b == &kill) {
remove ();
} else if (&b == &play) {
for (list<mod_dat>::iterator i = lst.begin (), j = lst.end(); i != j; ++i) {
mod_dat& md = *i;
modulator& mod = md.mod;
if (md.sb->state) mod.active = !mod.active;
}
} else if (&b == &all) {
on_lst (_sel);
} else if (&b == &invert) {
on_lst (_togg);
} else if (&b == &none) {
on_lst (_desel);
} else if (&b == &fold) {
if (fold.dir == arrow_button::down) {
title.hide (widget::only_children);
fold.show ();
fold.set_dir (arrow_button::right);
folded = 1;
} else {
title.show ();
fold.set_dir (arrow_button::down);
folded = 0;
}
}
}
void point_modulator::draw () {
if (folded == 0) {
DECLARE_WIDGET_ARRAY_wa
for (int i = 0; i < NUM_WIDGETS; ++i) {
widget* wi = wa[i];
if (wi->visible) wi->draw ();
}
for (list<mod_dat>::iterator i = lst.begin (), j = lst.end(); i != j; ++i) {
mod_dat& md = *i;
state_button* sb = md.sb;
if (sb->visible) sb->draw ();
}
glEnable (GL_LINE_STIPPLE);
glLineStipple (1, 0xf00f);
for (list<mod_dat>::iterator i = lst.begin (), j = lst.end(); i != j; ++i) {
mod_dat& md = *i;
state_button* sb = md.sb;
const point<float>& p = md.hit.get ();
int vx, vy; ed->obj2view (p.x, p.y, vx, vy);
if (sb->state) glColor3f (0, 1, 0); else glColor3f (1, 0, 0);
glBegin (GL_LINES);
glVertex2i (vx, vy);
glVertex2i (sb->extents.midx, sb->extents.midy);
glEnd ();
}
glDisable (GL_LINE_STIPPLE);
} else {
fold.draw ();
title.draw ();
}
}
void point_modulator::moved () {
sbx = title.extents.left + nlst * state_button::SIZE2;
sby = title.extents.bottom - title.extents.height;
}