Pixel-Composer/scripts/curveBox/curveBox.gml
2023-09-19 12:53:24 +02:00

242 lines
6.7 KiB
Plaintext

function curveBox(_onModify) : widget() constructor {
onModify = _onModify;
curve_surface = surface_create(1, 1);
node_dragging = -1;
node_drag_typ = -1;
miny = 0;
maxy = 1;
static get_x = function(val, _x, _w) { return _x + _w * val; }
static get_y = function(val, _y, _h) { return _y + _h * (1 - (val - miny) / (maxy - miny)); }
static register = function() {}
static drawParam = function(params) {
return draw(params.x, params.y, params.w, params.h, params.data, params.m);
}
static draw = function(_x, _y, _w, _h, _data, _m) {
x = _x;
y = _y;
w = _w;
h = _h;
if(!is_array(_data) || array_length(_data) == 0) return 0;
if(is_array(_data[0])) return 0;
var points = array_length(_data) / 6;
curve_surface = surface_verify(curve_surface, _w, _h);
if(node_dragging != -1) { #region editing
if(node_drag_typ == 0) {
var node_point = (node_dragging - 2) / 6;
if(node_point > 0 && node_point < points - 1) {
var _mx = (_m[0] - _x) / _w;
_mx = clamp(_mx, 0, 1);
var bfx = _data[node_dragging - 6];
var afx = _data[node_dragging + 6];
if(_mx == bfx) node_dragging -= 6;
else if(_mx == afx) node_dragging += 6;
else _data[node_dragging + 0] = _mx;
}
var _my = 1 - (_m[1] - _y) / _h;
_my = clamp(_my * (maxy - miny) + miny, 0, 1);
_data[node_dragging + 1] = _my;
//sort by x
var _xindex = [];
var _pindex = [];
for( var i = 0; i < points; i++ ) {
var ind = i * 6;
var _x0 = _data[ind + 2];
array_push(_xindex, _x0);
array_push(_pindex, _x0);
}
array_sort(_xindex, true);
if(node_point > 0 && node_point < points - 1) {
var sorted = [];
for( var i = 0; i < points; i++ ) {
var prog = _xindex[i];
var ind = array_find(_pindex, prog);
array_push(sorted, _data[ind * 6 + 0]);
array_push(sorted, _data[ind * 6 + 1]);
array_push(sorted, _data[ind * 6 + 2]);
array_push(sorted, _data[ind * 6 + 3]);
array_push(sorted, _data[ind * 6 + 4]);
array_push(sorted, _data[ind * 6 + 5]);
}
if(onModify(sorted))
UNDO_HOLDING = true;
} else if(onModify(_data))
UNDO_HOLDING = true;
} else {
var _px = _data[node_dragging + 0];
var _py = _data[node_dragging + 1];
var _mx = (_m[0] - _x) / _w;
_mx = clamp(_mx, 0, 1);
_data[node_dragging - 2] = (_px - _mx) * node_drag_typ;
_data[node_dragging + 2] = (_mx - _px) * node_drag_typ;
var _my = 1 - (_m[1] - _y) / _h;
_my = _my * (maxy - miny) + miny;
_data[node_dragging - 1] = clamp(_py - _my, -1, 1) * node_drag_typ;
_data[node_dragging + 3] = clamp(_my - _py, -1, 1) * node_drag_typ;
if(onModify(_data))
UNDO_HOLDING = true;
}
if(mouse_release(mb_left)) {
node_dragging = -1;
node_drag_typ = -1;
UNDO_HOLDING = false;
}
} #endregion
var node_hovering = -1;
var node_hover_typ = -1;
var point_insert = 1;
var _x1 = 0;
var msx = _m[0] - _x;
var msy = _m[1] - _y;
#region ==== draw ====
surface_set_target(curve_surface);
DRAW_CLEAR
draw_set_color(COLORS.widget_curve_line);
draw_set_alpha(0.75);
var y0 = _h - _h * (0 - miny) / (maxy - miny);
draw_line(0, y0, _w, y0);
var y1 = _h - _h * (1 - miny) / (maxy - miny);
draw_line(0, y1, _w, y1);
draw_set_alpha(1);
for( var i = 0; i < points; i++ ) {
var ind = i * 6;
var _x0 = _data[ind + 2];
var _y0 = _data[ind + 3];
var bx0 = _x0 + _data[ind + 0];
var by0 = _y0 + _data[ind + 1];
var ax0 = _x0 + _data[ind + 4];
var ay0 = _y0 + _data[ind + 5];
bx0 = get_x(bx0, 0, _w);
by0 = get_y(by0, 0, _h);
_x0 = get_x(_x0, 0, _w);
_y0 = get_y(_y0, 0, _h);
ax0 = get_x(ax0, 0, _w);
ay0 = get_y(ay0, 0, _h);
draw_set_color(COLORS.widget_curve_line);
if(i > 0) { //draw pre line
draw_line(bx0, by0, _x0, _y0);
draw_circle_prec(bx0, by0, 3, false);
if(hover && point_in_circle(msx, msy, bx0, by0, 10)) {
draw_circle_prec(bx0, by0, 5, false);
node_hovering = ind + 2;
node_hover_typ = -1;
}
}
if(i < points - 1) { //draw post line
draw_line(ax0, ay0, _x0, _y0);
draw_circle_prec(ax0, ay0, 3, false);
if(hover && point_in_circle(msx, msy, ax0, ay0, 10)) {
draw_circle_prec(ax0, ay0, 5, false);
node_hovering = ind + 2;
node_hover_typ = 1;
}
}
draw_set_color(COLORS._main_accent);
draw_circle_prec(_x0, _y0, 3, false);
if(hover && point_in_circle(msx, msy, _x0, _y0, 10)) {
draw_circle_prec(_x0, _y0, 5, false);
node_hovering = ind + 2;
node_hover_typ = 0;
}
if(msx >= _x1 && msy <= _x0)
point_insert = i;
_x1 = _x0;
}
draw_set_color(COLORS._main_accent);
draw_curve(0, 0, _w, -_h, _data, miny, maxy);
surface_reset_target();
#endregion
#region ==== buttons ====
var bx = _x + _w - ui(6 + 24);
var by = _y + _h - ui(6 + 24);
if(buttonInstant(THEME.button_hide, bx, by, ui(24), ui(24), _m, active, hover,, THEME.add) == 2) {
miny = 0;
maxy = 1;
}
bx -= ui(24 + 4);
if(buttonInstant(THEME.button_hide, bx, by, ui(24), ui(24), _m, active, hover,, THEME.minus) == 2) {
miny = -1;
maxy = 2;
}
#endregion
if(hover) { #region
if(point_in_rectangle(_m[0], _m[1], _x + _w - ui(6 + 24 * 2 + 4), _y + _h - ui(6 + 24), _x + _w + ui(5), _y + _h + ui(5))) {
} else if(point_in_rectangle(msx, msy, -ui(5), -ui(5), _w + ui(5), _h + ui(5))) {
if(mouse_press(mb_left, active)) {
if(node_hovering == -1) {
var _ind = point_insert * 6;
var _px = (_m[0] - _x) / _w;
var _py = 1 - (_m[1] - _y) / _h;
array_insert(_data, _ind + 0, -0.1);
array_insert(_data, _ind + 1, 0);
array_insert(_data, _ind + 2, _px);
array_insert(_data, _ind + 3, _py);
array_insert(_data, _ind + 4, 0.1);
array_insert(_data, _ind + 5, 0);
if(onModify(_data))
UNDO_HOLDING = true;
node_dragging = _ind + 2;
node_drag_typ = 0;
} else {
node_dragging = node_hovering;
node_drag_typ = node_hover_typ;
}
} else if(mouse_press(mb_right, active)) {
var node_point = (node_hovering - 2) / 6;
if(node_hover_typ == 0 && node_point > 0 && node_point < points - 1) {
array_delete(_data, node_point * 6, 6);
if(onModify(_data))
UNDO_HOLDING = true;
}
}
}
} #endregion
draw_surface(curve_surface, _x, _y);
draw_set_color(COLORS.widget_curve_outline);
draw_rectangle(_x, _y, _x + _w, _y + _h, true);
resetFocus();
return h;
}
}