- [Graph Panel] Add node alignment options to toolbar.

This commit is contained in:
Tanasart 2024-07-03 16:34:05 +07:00
parent dae83926ce
commit 94853648c7
8 changed files with 219 additions and 88 deletions

View file

@ -161,7 +161,7 @@ event_inherited();
draw_text(mtx + ui(8), mty + mth / 2, tg); draw_text(mtx + ui(8), mty + mth / 2, tg);
mtx += mtw + ui(8); mtx += mtw + ui(4);
} }
hh += mth + ui(8); hh += mth + ui(8);
@ -295,7 +295,7 @@ event_inherited();
name_height = max(name_height, string_height_ext(_name, -1, grid_width) + ui(8)); name_height = max(name_height, string_height_ext(_name, -1, grid_width) + ui(8));
draw_text_ext_add(tx, ty - ui(2), _name, -1, grid_width); draw_text_ext_add(tx, ty - ui(2), _name, -1, grid_width);
if(++_cur_col >= col || i == node_count - 1) { if(++_cur_col >= col) {
if(name_height) { if(name_height) {
var hght = grid_heigh + name_height + grid_line; var hght = grid_heigh + name_height + grid_line;
hh += hght; hh += hght;
@ -308,6 +308,12 @@ event_inherited();
} }
if(name_height) {
var hght = grid_heigh + name_height + grid_line;
hh += hght;
yy += hght;
}
if(_group_label) { if(_group_label) {
var len = array_length(group_labels); var len = array_length(group_labels);
if(len) { if(len) {

View file

@ -239,7 +239,7 @@ function gradientObject(color = c_black) constructor { #region
var _grad_time = _grad[1]; var _grad_time = _grad[1];
shader_set_i("gradient_blend", type); shader_set_i("gradient_blend", type);
shader_set_f("gradient_color", _grad_color); shader_set_f_array("gradient_color", _grad_color, GRADIENT_LIMIT * 4);
shader_set_f("gradient_time", _grad_time); shader_set_f("gradient_time", _grad_time);
shader_set_i("gradient_keys", array_length(keys)); shader_set_i("gradient_keys", array_length(keys));
} #endregion } #endregion

View file

@ -109,3 +109,73 @@ function node_vdistribute(nodeList) {
ds_priority_destroy(nodes); ds_priority_destroy(nodes);
} }
function node_hdistribute_dist(nodeList, anchor, distance = 0) {
var amo = array_length(nodeList);
var nodes = ds_priority_create();
var x0 = 999999;
var x1 = -999999;
for( var i = 0; i < amo; i++ ) {
var _x = nodeList[i].x + nodeList[i].w / 2;
x0 = min(x0, _x);
x1 = max(x1, _x);
ds_priority_add(nodes, nodeList[i], _x);
}
var ar = array_create(ds_priority_size(nodes));
for( var i = 0; i < amo; i++ )
ar[i] = ds_priority_delete_min(nodes);
ds_priority_destroy(nodes);
var an_ind = array_find(ar, anchor);
var an_ind_x = anchor.x + anchor.w + distance;
for (var i = an_ind + 1, n = array_length(ar); i < n; i++) {
ar[i].x = an_ind_x;
an_ind_x += ar[i].w + distance;
}
var an_ind_x = anchor.x - distance;
for (var i = an_ind - 1; i >= 0; i--) {
ar[i].x = an_ind_x - ar[i].w;
an_ind_x -= ar[i].w + distance;
}
}
function node_vdistribute_dist(nodeList, anchor, distance = 0) {
var amo = array_length(nodeList);
var nodes = ds_priority_create();
var y0 = 999999;
var y1 = -999999;
for( var i = 0; i < amo; i++ ) {
var _y = nodeList[i].y + nodeList[i].h / 2;
y0 = min(y0, _y);
y1 = max(y1, _y);
ds_priority_add(nodes, nodeList[i], _y);
}
var ar = array_create(ds_priority_size(nodes));
for( var i = 0; i < amo; i++ )
ar[i] = ds_priority_delete_min(nodes);
ds_priority_destroy(nodes);
var an_ind = array_find(ar, anchor);
var an_ind_y = anchor.y + anchor.h + distance;
for (var i = an_ind + 1, n = array_length(ar); i < n; i++) {
ar[i].y = an_ind_y;
an_ind_y += ar[i].h + distance;
}
var an_ind_y = anchor.y - distance;
for (var i = an_ind - 1; i >= 0; i--) {
ar[i].y = an_ind_y - ar[i].h;
an_ind_y -= ar[i].h + distance;
}
}

View file

@ -119,6 +119,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
badgeInspect = 0; badgeInspect = 0;
active_draw_index = -1; active_draw_index = -1;
active_draw_anchor = false;
draw_droppable = false; draw_droppable = false;
@ -1691,6 +1692,10 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
if(active_draw_index > -1) { if(active_draw_index > -1) {
draw_sprite_stretched_ext(bg_sel_spr, 0, xx, yy, round(w * _s), round(h * _s), active_draw_index > 1? COLORS.node_border_file_drop : COLORS._main_accent, 1); draw_sprite_stretched_ext(bg_sel_spr, 0, xx, yy, round(w * _s), round(h * _s), active_draw_index > 1? COLORS.node_border_file_drop : COLORS._main_accent, 1);
if(active_draw_anchor) draw_sprite_stretched_add(bg_sel_spr, 0, xx, yy, round(w * _s), round(h * _s), COLORS._main_accent, 0.5);
active_draw_anchor = false;
active_draw_index = -1; active_draw_index = -1;
} }

View file

@ -248,6 +248,7 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor {
selection_block = 0; selection_block = 0;
nodes_selecting = []; nodes_selecting = [];
nodes_selecting_jun = []; nodes_selecting_jun = [];
nodes_select_anchor = noone;
nodes_select_drag = 0; nodes_select_drag = 0;
nodes_select_frame = 0; nodes_select_frame = 0;
nodes_select_mx = 0; nodes_select_mx = 0;
@ -390,50 +391,64 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor {
#region ++++ toolbars ++++ #region ++++ toolbars ++++
tooltip_center = new tooltipHotkey(__txtx("panel_graph_center_to_nodes", "Center to nodes"), "Graph", "Focus content"); tooltip_center = new tooltipHotkey(__txtx("panel_graph_center_to_nodes", "Center to nodes"), "Graph", "Focus content");
toolbars = [ toolbars_general = [
[ [
THEME.icon_preview_export, THEME.icon_preview_export,
function() { return 0; }, function() /*=>*/ {return 0}, function() /*=>*/ {return __txtx("panel_graph_export_image", "Export graph as image")},
function() { return __txtx("panel_graph_export_image", "Export graph as image"); }, function(param) /*=>*/ { dialogPanelCall(new Panel_Graph_Export_Image(self)); }
function() { dialogPanelCall(new Panel_Graph_Export_Image(self)); }
], ],
[ [
THEME.icon_center_canvas, THEME.icon_center_canvas,
function() { return 0; }, function() /*=>*/ {return 0}, function() /*=>*/ {return tooltip_center},
function() { return tooltip_center; }, function(param) /*=>*/ { toCenterNode(); }
function() { toCenterNode(); }
], ],
[ [
THEME.icon_minimap, THEME.icon_minimap,
function() { return minimap_show; }, function() /*=>*/ {return minimap_show}, function() /*=>*/ {return minimap_show? __txtx("panel_graph_minimap_enabled", "Minimap enabled") : __txtx("panel_graph_minimap_disabled", "Minimap disabled")},
function() { return minimap_show? __txtx("panel_graph_minimap_enabled", "Minimap enabled") : __txtx("panel_graph_minimap_disabled", "Minimap disabled"); }, function(param) /*=>*/ { minimap_show = !minimap_show; }
function() { minimap_show = !minimap_show; }
], ],
[ [
THEME.icon_curve_connection, THEME.icon_curve_connection,
function() { return PREFERENCES.curve_connection_line; }, function() /*=>*/ {return PREFERENCES.curve_connection_line}, function() /*=>*/ {return __txtx("panel_graph_connection_line", "Connection render settings")},
function() { return __txtx("panel_graph_connection_line", "Connection render settings"); }, function(param) /*=>*/ { dialogPanelCall(new Panel_Graph_Connection_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); }
function(param) {
dialogPanelCall(new Panel_Graph_Connection_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left });
}
], ],
[ [
THEME.icon_grid_setting, THEME.icon_grid_setting,
function() { return 0; }, function() /*=>*/ {return 0}, function() /*=>*/ {return __txtx("grid_title", "Grid settings")},
function() { return __txtx("grid_title", "Grid settings"); }, function(param) /*=>*/ { dialogPanelCall(new Panel_Graph_Grid_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); }
function(param) {
dialogPanelCall(new Panel_Graph_Grid_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left });
}
], ],
[ [
THEME.icon_visibility, THEME.icon_visibility,
function() { return 0; }, function() /*=>*/ {return 0}, function() /*=>*/ {return __txtx("graph_visibility_title", "Visibility settings")},
function() { return __txtx("graph_visibility_title", "Visibility settings"); }, function(param) /*=>*/ { dialogPanelCall(new Panel_Graph_View_Setting(self, display_parameter), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); }
function(param) {
dialogPanelCall(new Panel_Graph_View_Setting(self, display_parameter), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left });
}
], ],
]; ];
toolbars_halign = [
[ THEME.object_halign, function() /*=>*/ {return 2}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_halign(nodes_selecting, fa_right); } ],
[ THEME.object_halign, function() /*=>*/ {return 1}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_halign(nodes_selecting, fa_center); } ],
[ THEME.object_halign, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_halign(nodes_selecting, fa_left); } ],
];
toolbars_valign = [
[ THEME.object_valign, function() /*=>*/ {return 2}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_valign(nodes_selecting, fa_top); } ],
[ THEME.object_valign, function() /*=>*/ {return 1}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_valign(nodes_selecting, fa_middle); } ],
[ THEME.object_valign, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_valign(nodes_selecting, fa_bottom); } ],
];
toolbars_distrib = [
[ THEME.obj_distribute_h, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_hdistribute(nodes_selecting); } ],
[ THEME.obj_distribute_v, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_vdistribute(nodes_selecting); } ],
];
distribution_spacing = 0;
toolbars_distrib_space = [
[ THEME.obj_distribute_h, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_hdistribute_dist(nodes_selecting, nodes_select_anchor, distribution_spacing); } ],
[ THEME.obj_distribute_v, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_vdistribute_dist(nodes_selecting, nodes_select_anchor, distribution_spacing); } ],
[ new textBox(TEXTBOX_INPUT.number, function(val) { distribution_spacing = value_snap(val, 4); } ).setSlidable(1).setPadding(4), function() /*=>*/ {return distribution_spacing} ],
];
toolbars = [ toolbars_general ];
#endregion #endregion
//// =========== Get Set =========== //// =========== Get Set ===========
@ -1080,6 +1095,8 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor {
#region ++++++++++++ interaction ++++++++++++ #region ++++++++++++ interaction ++++++++++++
if(mouse_on_graph && pHOVER) { if(mouse_on_graph && pHOVER) {
if(mouse_press(mb_left, _focus)) nodes_select_anchor = noone;
#region select #region select
if(NODE_DROPPER_TARGET != noone && node_hovering) { if(NODE_DROPPER_TARGET != noone && node_hovering) {
node_hovering.draw_droppable = true; node_hovering.draw_droppable = true;
@ -1142,6 +1159,8 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor {
} }
if(!hover_selected) if(!hover_selected)
nodes_selecting = [ node_hovering ]; nodes_selecting = [ node_hovering ];
nodes_select_anchor = nodes_select_anchor == node_hovering? noone : node_hovering;
} }
if(WIDGET_CURRENT) WIDGET_CURRENT.deactivate(); if(WIDGET_CURRENT) WIDGET_CURRENT.deactivate();
@ -1283,6 +1302,8 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor {
if(!_node) continue; if(!_node) continue;
_node.drawActive(gr_x, gr_y, graph_s); _node.drawActive(gr_x, gr_y, graph_s);
} }
if(nodes_select_anchor) nodes_select_anchor.active_draw_anchor = true;
#endregion #endregion
printIf(log, $"Draw active: {get_timer() - t}"); t = get_timer(); printIf(log, $"Draw active: {get_timer() - t}"); t = get_timer();
@ -1671,8 +1692,7 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor {
else if(!key_mod_press(CTRL) && node_hovering != noone) { else if(!key_mod_press(CTRL) && node_hovering != noone) {
if(value_dragging.connect_type == JUNCTION_CONNECT.input) { if(value_dragging.connect_type == JUNCTION_CONNECT.input) {
target = node_hovering.getOutput(my, value_dragging); target = node_hovering.getOutput(my, value_dragging);
if(target != noone) if(target != noone) node_hovering.active_draw_index = 1;
node_hovering.active_draw_index = 1;
} else { } else {
target = node_hovering.getInput(my, value_dragging, 0); target = node_hovering.getInput(my, value_dragging, 0);
@ -1840,9 +1860,11 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor {
draw_set_alpha(i < array_length(node_context) - 1? 0.33 : 1); draw_set_alpha(i < array_length(node_context) - 1? 0.33 : 1);
draw_text(xx, tbh, tt); draw_text(xx, tbh, tt);
draw_set_alpha(1); draw_set_alpha(1);
xx += tw;
xx += ui(32); xx += tw + ui(32);
} }
return xx;
} #endregion } #endregion
function drawToolBar() { #region function drawToolBar() { #region
@ -1853,25 +1875,57 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor {
mouse_on_graph = false; mouse_on_graph = false;
draw_sprite_stretched(THEME.toolbar, 0, 0, ty, w, h); draw_sprite_stretched(THEME.toolbar, 0, 0, ty, w, h);
drawContext(); var cont_x = drawContext();
var tbx = w - toolbar_height / 2; var tbx = w - ui(6);
var tby = ty + toolbar_height / 2; var tby = ty + toolbar_height / 2;
var _m = [ mx, my ];
for( var i = 0, n = array_length(toolbars); i < n; i++ ) { for( var i = 0, n = array_length(toolbars); i < n; i++ ) {
var tb = toolbars[i]; var tbs = toolbars[i];
var tbSpr = tb[0];
for (var j = 0, m = array_length(tbs); j < m; j++) {
var tb = tbs[j];
var tbObj = tb[0];
if(is_instanceof(tbObj, widget)) {
tbObj.setFocusHover(pFOCUS, pHOVER);
var _wdw = ui(32);
var _wdx = tbx - _wdw;
if(_wdx < cont_x) break;
var _param = new widgetParam(_wdx, ty + ui(8), _wdw, toolbar_height - ui(16), tb[1](), {}, _m, x, y);
_param.font = f_p3;
tbObj.color = COLORS._main_text_sub;
tbObj.drawParam(_param);
tbx -= _wdw + ui(4);
} else {
var tbInd = tb[1](); var tbInd = tb[1]();
var tbTooltip = tb[2](); var tbTooltip = tb[2]();
var b = buttonInstant(THEME.button_hide, tbx - ui(14), tby - ui(14), ui(28), ui(28), [mx, my], pFOCUS, pHOVER, tbTooltip, tbSpr, tbInd); var bs = ui(28);
if(b == 2) tb[3]( { x: x + tbx - ui(14), y: y + tby - ui(14) } ); if(tbx - (bs + ui(4)) < cont_x) break;
tbx -= ui(32); var b = buttonInstant(THEME.button_hide, tbx - bs, tby - bs / 2, bs, bs, _m, pFOCUS, pHOVER, tbTooltip, tbObj, tbInd);
if(b == 2) tb[3]( { x: x + tbx - bs, y: y + tby - bs / 2 } );
tbx -= bs + ui(4);
} }
}
tbx -= ui(2);
draw_set_color(COLORS.panel_toolbar_separator); draw_set_color(COLORS.panel_toolbar_separator);
draw_line_width(tbx + ui(12), tby - toolbar_height / 2 + ui(8), tbx + ui(12), tby + toolbar_height / 2 - ui(8), 2); draw_line_width(tbx, tby - toolbar_height / 2 + ui(8), tbx, tby + toolbar_height / 2 - ui(8), 2);
if(tbx < cont_x) break;
tbx -= ui(6);
}
} #endregion } #endregion
function drawMinimap() { #region function drawMinimap() { #region
@ -2018,6 +2072,14 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor {
dragGraph(); dragGraph();
toolbars = [ toolbars_general ];
if(array_length(nodes_selecting) > 1) {
if(array_exists(nodes_selecting, nodes_select_anchor))
array_push(toolbars, toolbars_halign, toolbars_valign, toolbars_distrib_space);
else
array_push(toolbars, toolbars_halign, toolbars_valign, toolbars_distrib);
}
graph_cx = (w / 2) / graph_s - graph_x; graph_cx = (w / 2) / graph_s - graph_x;
graph_cy = (h / 2) / graph_s - graph_y; graph_cy = (h / 2) / graph_s - graph_y;
@ -2045,13 +2107,10 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor {
drawViewControl(); drawViewControl();
if(pFOCUS && !view_hovering) if(pFOCUS && !view_hovering) array_foreach(nodes_selecting, function(node) { node.focusStep(); });
array_foreach(nodes_selecting, function(node) { node.focusStep(); });
if(UPDATE == RENDER_TYPE.full) if(UPDATE == RENDER_TYPE.full) draw_text(w - ui(8), ui(28), __txtx("panel_graph_rendering", "Rendering") + "...");
draw_text(w - ui(8), ui(28), __txtx("panel_graph_rendering", "Rendering") + "..."); else if(UPDATE == RENDER_TYPE.partial) draw_text(w - ui(8), ui(28), __txtx("panel_graph_rendering_partial", "Rendering partial") + "...");
else if(UPDATE == RENDER_TYPE.partial)
draw_text(w - ui(8), ui(28), __txtx("panel_graph_rendering_partial", "Rendering partial") + "...");
graph_dragging_key = false; graph_dragging_key = false;
graph_zooming_key = false; graph_zooming_key = false;

View file

@ -31,6 +31,14 @@ function shader_set_2(uniform, v) { INLINE var shader = shader_current(); shader
function shader_set_3(uniform, v) { INLINE var shader = shader_current(); shader_set_uniform_f(shader_get_uniform(shader, uniform), aGetF(v, 0), aGetF(v, 1), aGetF(v, 2)); } function shader_set_3(uniform, v) { INLINE var shader = shader_current(); shader_set_uniform_f(shader_get_uniform(shader, uniform), aGetF(v, 0), aGetF(v, 1), aGetF(v, 2)); }
function shader_set_4(uniform, v) { INLINE var shader = shader_current(); shader_set_uniform_f(shader_get_uniform(shader, uniform), aGetF(v, 0), aGetF(v, 1), aGetF(v, 2), aGetF(v, 3)); } function shader_set_4(uniform, v) { INLINE var shader = shader_current(); shader_set_uniform_f(shader_get_uniform(shader, uniform), aGetF(v, 0), aGetF(v, 1), aGetF(v, 2), aGetF(v, 3)); }
function shader_set_f_array(uniform, value, max_length = 128) {
var shader = shader_current();
if(shader == -1) return;
if(array_empty(value)) return;
shader_set_uniform_f_array_safe(shader_get_uniform(shader, uniform), value, max_length);
}
function shader_set_f(uniform, value) { #region function shader_set_f(uniform, value) { #region
INLINE INLINE

View file

@ -98,25 +98,11 @@ function textBox(_input, _onModify) : textInput(_input, _onModify) constructor {
return self; return self;
} #endregion } #endregion
static setFont = function(font) { #region static setFont = function(font) { self.font = font; return self; }
self.font = font; static setLabel = function(label) { self.label = label; return self; }
return self; static setPrecision = function(precision) { self.precision = precision; return self; }
} #endregion static setPadding = function(padding) { self.padding = padding; return self; }
static setEmpty = function() { no_empty = false; return self; }
static setLabel = function(label) { #region
self.label = label;
return self;
} #endregion
static setPrecision = function(precision) { #region
self.precision = precision;
return self;
} #endregion
static setEmpty = function() { #region
no_empty = false;
return self;
} #endregion
static activate = function() { #region static activate = function() { #region
WIDGET_CURRENT = self; WIDGET_CURRENT = self;

View file

@ -121,15 +121,13 @@ uniform int uniAsp;
return texture2D( gradient_map, samplePos ); return texture2D( gradient_map, samplePos );
} }
vec4 col = vec4(0.);
for(int i = 0; i < GRADIENT_LIMIT; i++) { for(int i = 0; i < GRADIENT_LIMIT; i++) {
if(gradient_time[i] == prog) { if(gradient_time[i] == prog) {
col = gradient_color[i]; return gradient_color[i];
break;
} else if(gradient_time[i] > prog) { } else if(gradient_time[i] > prog) {
if(i == 0) if(i == 0)
col = gradient_color[i]; return gradient_color[i];
else { else {
float t = (prog - gradient_time[i - 1]) / (gradient_time[i] - gradient_time[i - 1]); float t = (prog - gradient_time[i - 1]) / (gradient_time[i] - gradient_time[i - 1]);
vec3 c0 = gradient_color[i - 1].rgb; vec3 c0 = gradient_color[i - 1].rgb;
@ -137,29 +135,28 @@ uniform int uniAsp;
float a = mix(gradient_color[i - 1].a, gradient_color[i].a, t); float a = mix(gradient_color[i - 1].a, gradient_color[i].a, t);
if(gradient_blend == 0) if(gradient_blend == 0)
col = vec4(mix(c0, c1, t), a); return vec4(mix(c0, c1, t), a);
else if(gradient_blend == 1) else if(gradient_blend == 1)
col = gradient_color[i - 1]; return gradient_color[i - 1];
else if(gradient_blend == 2) else if(gradient_blend == 2)
col = vec4(hsvMix(c0, c1, t), a); return vec4(hsvMix(c0, c1, t), a);
else if(gradient_blend == 3) else if(gradient_blend == 3)
col = vec4(oklabMax(c0, c1, t), a); return vec4(oklabMax(c0, c1, t), a);
else if(gradient_blend == 4) else if(gradient_blend == 4)
col = vec4(rgbMix(c0, c1, t), a); return vec4(rgbMix(c0, c1, t), a);
} }
break; break;
} }
if(i >= gradient_keys - 1) {
col = gradient_color[gradient_keys - 1];
break;
}
}
return col; if(i >= gradient_keys - 1)
return gradient_color[gradient_keys - 1];
}
return gradient_color[gradient_keys - 1];
} #endregion } #endregion
#endregion //////////////////////////////////// GRADIENT //////////////////////////////////// #endregion //////////////////////////////////// GRADIENT ////////////////////////////////////