Rev 1823 |
Rev 1826 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* gravity.cc
* DIN Is Noise is copyright (c) 2006-2021 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/
#include "gravity.h"
#include "font.h"
#include "vector2d.h"
#include "drone.h"
#include "console.h"
#include "din.h"
#include <fstream>
using namespace std;
extern int mousex, mouseyy;
#define NUDGEDOWN(W) W.set_pos (W.extents.left, W.extents.bottom - 3);
gravity_t::gravity_t () {
mouse_slider_listener::name = "Gravity";
handlesize = 5;
strength = 0;
hitt = NOTHING;
lmb_clicked = 0;
tracked_drone = 0;
forcetrack = 0;
mag0 = 50;
mag = 0;
keep_size = 0;
button* bt [] = {&zero, &reset, &keepsize, &mouse, &dron, &changesize, &mod.yes, &mod.edit};
const char* txt [] = {"0", "Reset", "Keep size", "Mouse", "Drone", "Change size", "Modulate", "Edit"};
for (int i = 0; i < 8; ++i) bt[i]->set_text (txt[i]);
arrow_button* ab [] = {&left, &right, &up, &down};
int dirr [] = {arrow_button::left, arrow_button::right, arrow_button::up, arrow_button::down};
for (int i = 0, j = 1; i < 4; ++i, ++j) {
arrow_button* abi = ab[i];
abi->id = j;
abi->set_dir (dirr[i]);
abi->set_listener(this);
}
LISTEN(fold,this)
LISTEN(zero,this)
LISTEN(reset,this)
LISTEN(changesize,this)
LISTEN(mouse,&ml)
mod.depth.set ("Depth", 0.1f, 0.0f, 1.0f, &mod.dl, 0);
mod.depth.set_value (1.0f);
mod.bpm.set ("BPM", 1, 0, MILLIONF, &mod.bl, 0);
mod.bpm.set_value (45.0f);
#ifdef __WIDGET_MOVE__
{
widget* w[] = {&mod.yes, &mod.depth, &mod.bpm, &mod.edit, 0};
for (widget** p = w; *p != 0; ++p) (*p)->set_moveable(1);
makehier (w);
}
#endif
}
int gravity_t::handle_input () {
HANDLEINPUT(fold)
else if (fold.dir == arrow_button::down) {
widget* w [] = {&zero, &reset, &left, &right, &up, &down, &keepsize, &mouse, &dron, &changesize, &mod.yes, &mod.depth, &mod.bpm, &mod.edit, 0};
for (widget** p = w; *p != 0; ++p) if ((*p)->handle_input ()) break;
}
if (is_lmb (this)) {
if (lmb_clicked == 0) {
lmb_clicked = 1;
if (hitt != NOTHING) {
hitt = NEXT_TO_NOTHING;
} else {
if (hit (tip, mousex, mouseyy)) {
hitt = TIP; // edit tip
is_lmb.tie = this;
} else
if (hit (base, mousex, mouseyy)) {
hitt = BASE; // edit base
is_lmb.tie = this;
}
}
}
} else {
if (hitt == NOTHING) {
}
else
if (hitt == NEXT_TO_NOTHING) {
stop_editing ();
} else if (hitt == TIP) { // update tip
set (tip, mousex, mouseyy);
} else if (hitt == BASE) { // update base
set (tip, mousex + base2tip.x, mouseyy + base2tip.y, 0);
set (base, mousex, mouseyy, 0);
calcui ();
}
lmb_clicked = 0;
}
return hitt;
}
void gravity_t::draw () {
fold.draw ();
if (fold.dir == arrow_button::down) {
widget* w [] = {&zero, &reset, &left, &right, &up, &down, &keepsize, &mouse, &dron, &changesize, &mod.yes, &mod.depth, &mod.bpm, &mod.edit, 0};
for (widget** p = w; *p != 0; ++p) (*p)->draw ();
}
glColor3f (1, 0.6, 0.5);
draw_string ("Gravity", textpos.x, textpos.y);
glVertexPointer (2, GL_INT, 0, gl_base);
glDrawArrays (GL_LINE_LOOP, 0, 4);
glVertexPointer (2, GL_FLOAT, 0, gl_arrow);
glDrawArrays (GL_LINES, 0, 6);
}
void gravity_t::calc (int calc_mag) {
direction (base2tip, base, tip);
perpendicular (p_base2tip, base2tip);
bottomleft (base.x - handlesize, base.y - handlesize);
topright (base.x + handlesize, base.y + handlesize);
gx = strength * base2tip.x; gy = strength * base2tip.y;
gl_base[0]=bottomleft.x; gl_base[1]=bottomleft.y;
gl_base[2]=topright.x; gl_base[3]=gl_base[1];
gl_base[4]=gl_base[2];gl_base[5]=topright.y;
gl_base[6]=gl_base[0];gl_base[7]=gl_base[5];
int cap = 0;
int da = 0;
make_arrow (gl_arrow, 0, cap, da, base.x, base.y, base2tip.x, base2tip.y, p_base2tip.x, p_base2tip.y, 0.6f, 0.2f);
if (calc_mag) mag = magnitude (base2tip);
}
void gravity_t::calcui () {
fold.set_pos (topright.x + 5, bottomleft.y);
textpos (fold.extents.right + 5, bottomleft.y - 3);
button* bt [] = {&zero, &left, &right, &up, &down, &mouse, &dron, 0};
int xx = textpos.x, yy = textpos.y - line_height;
int ds = 10;
for (button** p = bt; *p != 0; ++p) {
button* bti = *p;
bti->set_pos (xx, yy);
xx = bti->extents.right + ds;
}
/*for (int i = 0; i < 7; ++i) {
button* bti = bt[i];
bti->set_pos (xx, yy);
xx = bti->extents.right + ds;
}*/
NUDGEDOWN (zero);
NUDGEDOWN (mouse);
NUDGEDOWN (dron);
reset.set_pos (textpos.x, zero.extents.bottom - line_height);
keepsize.set_pos (reset.extents.right + ds, reset.extents.bottom);
{
widget* w[] = {&changesize, &mod.yes, &mod.depth, &mod.bpm, &mod.edit, 0};
int lh = line_height, wy = reset.extents.bottom;
for (widget** p = w; *p != 0; ++p) {
widget& pi = **p;
pi.set_pos (textpos.x, wy -= lh);
}
}
}
void gravity_t::set (point<int>& what, int mx, int my, int calc_mag) {
what.x = mx;
what.y = my;
calc (calc_mag);
}
int gravity_t::hit (const point<int>& what, int mx, int my) {
double m = magnitude (what.x, what.y, mx, my);
if (m <= handlesize) return 1; else return 0;
}
void gravity_t::load (ifstream& file) {
string ignore;
int bx, by, tx, ty; file >> ignore >> bx >> by >> tx >> ty;
set (base, bx, by);
set (tip, tx, ty);
file >> strength >> visible >> keep_size >> maos >> dronn;
}
void gravity_t::save (ofstream& file) {
file << "gravity " << base.x << spc << base.y << spc << tip.x << spc << tip.y << spc << strength << spc << visible << spc << keep_size << spc << mouse.state << spc << dron.state << endl;
mod.crv.save ("gravmod.crv");
}
void gravity_t::doreset (int ks) {
keep_size = ks;
if (!keep_size) mag = mag0;
preset (down.id);
}
void gravity_t::preset (int id) {
if (!id) {
mag = 0;
} else {
if (mag == 0) mag = mag0;
}
int xx [] = {base.x, int (base.x - mag), int (base.x + mag), base.x, base.x};
int yy [] = {base.y, base.y, base.y, int(base.y + mag), int(base.y - mag)};
tip.x = int (xx [id]);
tip.y = int (yy [id]);
calc (0);
}
void gravity_t::track (int vx, int vy) {
unit_vector (btux, btuy, base.x, base.y, vx, vy);
vx = base.x + mag * btux;
vy = base.y + mag * btuy;
set (tip, vx, vy, 0);
forcetrack = 0;
}
int gravity_t::stop_editing () {
if (hitt != NOTHING) {
hitt = NOTHING;
is_lmb.clear (this);
return 1;
}
return 0;
}
void gravity_t::clicked (button& b) {
if (&b == &fold) {
if (fold.dir == arrow_button::right) {
fold.set_dir(arrow_button::down);
} else {
fold.set_dir(arrow_button::right);
}
} else {
if (&b == &reset) {
doreset (keepsize.state);
} else if (&b == &changesize) {
unit_vector<double> (btux, btuy, base2tip.x, base2tip.y);
mouse_slider0.add (this);
activate_mouse_slider ();
} else {
preset (b.id);
}
}
}
void gravity_t::moused (int dir, double scl) {
mag += (sign(dir) * scl);
updmag (mag);
}
void gravity_t::updmag (double m) {
mag = m;
if (mag < 0) mag = 0;
tip.x = base.x + mag * btux;
tip.y = base.y + mag * btuy;
#define BUTDONTCALCMAG 0
calc (BUTDONTCALCMAG);
}
int gravity_t::unfolded () {return fold.dir == arrow_button::down;}
CLICKED_CHECKBUTTON (gravity_t, mousel) {
if (cb.state) din0.dinfo.gravity.track (mousex, mouseyy);
}
void gravity_t::modulate () {
if (mod.yes.state) updmag (mod.eval());
}
float gravity_t::modulatet::eval () {
double now = ui_clk ();
double dt = now - t;
params.calc (dt);
t = now;
return ((1 + params.result) * params.initial);
}
CLICKED_CHECKBUTTON (gravity_t::modulatet, yesl) {
if (cb.state) {
gravity_t& gravity = din0.dinfo.gravity;
mod_params& params = din0.dinfo.gravity.mod.params;
params.initial = gravity.mag;
unit_vector<double> (gravity.btux, gravity.btuy, gravity.base2tip.x, gravity.base2tip.y);
params.depth = gravity.mod.depth();
params.bv.set_bpm (gravity.mod.bpm());
params.bv.now = 0.0f;
gravity.mod.t = ui_clk ();
}
}
CLICKED_BUTTON (gravity_t::modulatet, editl) {
uis.load_editor (&din0.dinfo.gravity.mod.ed);
}
VALUE_CHANGED (gravity_t::modulatet, depthl) {
gravity_t& gravity = din0.dinfo.gravity;
mod_params& params = din0.dinfo.gravity.mod.params;
params.depth = gravity.mod.depth();
}
VALUE_CHANGED (gravity_t::modulatet, bpml) {
gravity_t& gravity = din0.dinfo.gravity;
mod_params& params = din0.dinfo.gravity.mod.params;
params.bv.set_bpm (gravity.mod.bpm());
}
void gravity_t::modulatet::curvel::edited (curve_editor* e, int i) {
beat2value& bv = din0.dinfo.gravity.mod.params.bv;
bv.sol (bv.crv);
}