Rev 1331 |
Rev 1479 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* levels.cc
* DIN Is Noise is copyright (c) 2006-2020 Jagannathan Sampath
* For more information, please visit http://dinisnoise.org/
*/
#include "main.h"
#include "levels.h"
#include "viewwin.h"
#include "input.h"
#include "console.h"
#include "utils.h"
#include "font.h"
#include "log.h"
#include <fstream>
#include <iostream>
using namespace std;
extern string user_data_dir;
extern int mousex, mousey, wheel, mouseyy, prev_mousey;
extern char BUFFER [];
extern int line_height;
levels::levels (const string& n) {
name = n;
lis = 0;
editing = lmb_clicked = paint = nsel = 0;
wrap = 1;
selection = 0;
load ();
}
levels::~levels () {
save ();
if (selection) delete[] selection;
}
void levels::load () {
string ignore;
int left, bottom;
ifstream file ((user_data_dir + name).c_str(), ios::in);
if (!file) {
dlog << "!!! cant read settings for " << name << ", using defaults. !!!" << endl;
nlev = 10;
elem_width = 10;
height = 100;
left = 0;
bottom = 0;
editable = 0;
saveable = 0;
wrap = 1;
} else {
file >> ignore >> nlev;
lastlev = nlev - 1;
file >> ignore >> left >> bottom;
file >> ignore >> elem_width;
file >> ignore >> height;
file >> ignore >> editable;
file >> ignore >> saveable;
file >> ignore >> wrap;
dlog << "+++ loaded " << name << " +++" << endl;
}
a = 0.7;
a0 = a / 4;
extents (left, bottom, left + nlev * elem_width, bottom + height);
values.resize (nlev);
heights.resize (nlev);
selection = new bool [nlev];
sel_sz = sizeof (bool) * nlev;
memset (selection, 0, sel_sz);
if (saveable) {
int savings;
file >> ignore >> savings;
for (int i = 0; i < savings; ++i) {
float h; file >> h >> selection[i];
heights[i] = h;
values[i] = h * extents.height_1;
}
file >> nsel;
}
editing = edited = 0;
}
void levels::save () {
ofstream file ((user_data_dir+name).c_str(), ios::out);
if (file) {
file << "num_levels " << nlev << endl;
file << "lower_corner " << extents.left << SPC << extents.bottom << endl;
file << "element_width " << elem_width << endl;
file << "height " << height << endl;
file << "editable " << editable << endl;
file << "saveable " << saveable << endl;
file << "wrap " << wrap << endl;
if (saveable) {
file << "savings " << nlev << SPC;
for (int i = 0; i < nlev; ++i) file << heights[i] << SPC << selection[i] << SPC;
file << nsel << endl;
} else {
file << "savings 0" << endl;
}
} else dlog << "!!! couldnt save levels !!!" << endl;
}
int levels::stop_editing () {
if (editing == FINISH) {
editing = 0;
/*if (nsel) {
memset (selection, 0, sel_sz);
nsel = 0;
}*/
return 1;
}
return 0;
}
int levels::handle_input () {
prev_mousey = mousey;
widget::handle_input ();
int hne = hover && !editing;
if (hne) calc_lev ();
if (editable) {
if (lmb) {
if (lmb_clicked == 0) {
if (stop_editing () == 0) {
if (hne) {
if (shift_down()) {
bool& k = selection [lev];
k = !k;
if (k) ++nsel; else --nsel;
} else {
editing = STARTED;
widget::focus = this;
}
}
}
}
lmb_clicked = 1;
} else {
lmb_clicked = 0;
if (editing) { // just mouse mov
if (wheel) {
mousey -= wheel;
warp_mouse (mousex, mousey);
}
if (paint) calc_lev ();
calc_hgt_val ();
int dh = set (lev, val, hgt);
int uml = 0;
if (selection[lev] && !shift_down() ) uml = update_mul_lev (dh);
if (lis && (dh || uml)) lis->changed (*this);
// if ( dh && nsel && !shift_down ()) update_mul_lev (dh);
editing = FINISH;
edited = 1;
} else {
if (widget::focus == this) widget::focus = 0;
}
}
}
return edited;
}
int levels::update_mul_lev (int dh) {
float dv = dh * extents.height_1;
/*float vj [nlev];
int hj [nlev];*/
int ret = 0;
for (int i = 0; i < nlev; ++i) {
if ((i != lev) && selection[i]) {
int& hi = heights[i];
float& vi = values[i];
int hji = hi + dh;
float vji = vi + dv;
if (hji < 0) hji = 0; else if (hji > extents.height) hji = extents.height;
if (vji < 0.0f) vji = 0.0f; else if (vji > 1.0f) vji = 1.0f;
hi = hji;
vi = vji;
ret = 1;
/*if (!inrange (0, hji, extents.height)) return 0;
hj[i] = hji;
vj[i] = vji;*/
}
}
/*ret = 1;
for (int i = 0; i < nlev; ++i) {
if ((i != lev) && selection[i]) {
int& hi = heights[i];
float& vi = values[i];
hi = hj[i];
vi = vj[i];
}
}*/
return ret;
}
void levels::calc_lev () {
lev = (mousex - extents.left) / elem_width;
if (lev > lastlev || lev < 0) lev = -1;
}
void levels::calc_hgt_val () {
hgt = mouseyy - extents.bottom;
clamp<int> (0, hgt, extents.height);
val = hgt * extents.height_1;
}
void levels::clear_hgt_val () {
for (int i = 0; i < nlev; ++i) values[i] = heights[i] = 0;
}
void levels::draw () {
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
int i = 0, x = extents.left, ds = elem_width - 2;
if (extents.left < 0) {
i = -extents.left / elem_width;
x = 0;
}
for (;i < nlev; ++i) {
int l = x + 1, r = x + ds;
glColor4f (clr.r, clr.g, clr.b, a0);
glRecti (l, extents.bottom, r, extents.top);
float dc = selection[i] * 0.5;
glColor4f (clr.r, clr.g + dc, clr.b, a);
glRecti (l, extents.bottom, r, extents.bottom + heights[i]);
x += elem_width;
extern viewport view;
if (x > view.xmax) break;
}
glDisable (GL_BLEND);
sprintf (BUFFER, "%d/%.3f", lev+1, lev > -1? values[lev]:-1);
draw_string (BUFFER, extents.left, extents.bottom - line_height, 0);
}
int levels::change (int i, float dv) {
if (i > -1 && i < nlev) {
float& vi = values[i];
vi += dv;
int result = clamp<float> (0, vi, 1);
heights[i] = (int) (vi * extents.height + 0.5);
return result;
}
return 0;
}
void levels::set_only (int i, float v) {
if (i > -1 && i < nlev) {
clamp<float> (0, v, 1);
values[i] = v;
heights[i] = (int)(v * extents.height + 0.5);
}
}
int levels::set (int i, float v, int h) { // from ui
if (i > -1 && i < nlev) {
int& hi = heights[i];
int dh = h - hi;
hi = h;
float& vi = values[i];
if (vi != v) { // bcos from ui
vi = v;
// if (lis) lis->changed (*this);
}
return dh;
}
return 0;
}
void levels::update () {
if (lis) lis->changed (*this);
}
void levels::chkpos () {
extern viewport view;
if (!view.inside (extents.left, extents.bottom)) extents.lower_corner (0, 0);
}
void levels::reheight () {
for (int i = 0; i < nlev; ++i) {
float v = values[i];
int h = v * height + 0.5;
heights[i] = h;
}
}
int levels::lshift () {
float v0 = values[0];
int h0 = heights[0];
if (wrap == 0) {
if (heights[0]) return 0;
}
for (int i = 0, j = 1; i < lastlev; ++i, ++j) {
values[i] = values[j];
heights[i] = heights[j];
}
if (wrap) {
values[lastlev] = v0;
heights[lastlev] = h0;
} else {
values[lastlev] = heights[lastlev] = 0;
}
return 1;
}
int levels::rshift () {
float vl = values[lastlev];
int hl = heights[lastlev];
if (wrap == 0) {
if (hl) return 0;
}
for (int j = lastlev, i = lastlev - 1; j > 0; --j, --i) {
values[j]=values[i];
heights[j]=heights[i];
}
if (wrap) {
values[0]=vl;
heights[0]=hl;
} else {
values[0]=heights[0]= 0;
}
return 1;
}