Last active
October 21, 2018 06:37
-
-
Save catfact/908fe029c49cf8392cb147c266ee5b1f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// outlets: input index, output index, connection value | |
outlets = 3; | |
sketch.default2d(); | |
// I/O count, should be an argument | |
var num_ins = 4; | |
var num_outs = 4; | |
// mouse state (world coordinates) | |
var wx = 0; | |
var wy = 0; | |
// colors | |
var Color = Object.freeze({ | |
"in_on" : [0.5, 1.0, 0.5, 1.0], | |
"in_off" : [0.7, 0.8, 0.7, 1.0], | |
"in_hover" : [0.8, 1.0, 0.8, 1.0], | |
"out_on" : [1.0, 0.5, 0.5, 1.0], | |
"out_off" : [0.8, 0.7, 0.7, 1.0], | |
"out_hover" : [1.0, 0.8, 0.8, 1.0] | |
}); | |
var in_bounds = []; | |
var out_bounds = []; | |
var patched = []; | |
var in_connected = []; | |
var out_connected= []; | |
var in_hover = []; | |
var out_hover = []; | |
for(i=0; i<num_ins; i++) { | |
patched[i] = []; | |
for(j=0; j<num_outs; j++) { | |
patched[i][j] = false; | |
} | |
} | |
// interaction state | |
var ui_state = { | |
"is_patching": false, | |
"in_anchor": -1, | |
"out_anchor": -1 | |
}; | |
function reset_ui_state() { | |
ui_state.is_patching = false; | |
ui_state.in_anchor = -1; | |
ui_state.out_anchor = -1; | |
} | |
//--------------------------------- | |
// event handlers | |
function onresize(width, height) { | |
set_node_bounds(); | |
} | |
function onidle(x, y) { | |
var pos = sketch.screentoworld(x, y); | |
wx = pos[0]; | |
wy = pos[1]; | |
for(i=0; i<num_ins; i++) { | |
in_hover[i] = check_node_bounds(in_bounds[i], pos); | |
} | |
for(i=0; i<num_outs; i++) { | |
out_hover[i] = check_node_bounds(out_bounds[i], pos); | |
} | |
redraw(); | |
} | |
function onclick(x, y) { | |
var pos = sketch.screentoworld(x, y); | |
for(i=0; i<num_ins; i++) { | |
if (check_node_bounds(in_bounds[i], pos)) { | |
do_input(i); | |
} | |
} | |
for(i=0; i<num_outs; i++) { | |
if(check_node_bounds(out_bounds[i], pos)) { | |
do_output(i); | |
} | |
} | |
} | |
function onidleout() { | |
reset_ui_state(); | |
} | |
//--------------------------------- | |
//--- "controller logic" (ha) | |
function do_input(i) { | |
if(ui_state.is_patching) { | |
if(ui_state.in_anchor != -1) { | |
ui_state.in_anchor = i; | |
} else { | |
if(ui_state.out_anchor != -1) { | |
ui_state.in_anchor = i; | |
do_patch(); | |
} else { | |
// shouldn't get here | |
} | |
} | |
} else { | |
ui_state.is_patching = true; | |
ui_state.in_anchor = i; | |
ui_state.out_anchor = -1; | |
} | |
} | |
function do_output(j) { | |
if(ui_state.is_patching) { | |
if(ui_state.out_anchor != -1) { | |
ui_state.out_anchor = j; | |
} else { | |
if(ui_state.in_anchor != -1) { | |
ui_state.out_anchor = j; | |
do_patch(); | |
} else { | |
// shouldn't get here | |
} | |
} | |
} else { | |
ui_state.is_patching = true; | |
ui_state.in_anchor = -1; | |
ui_state.out_anchor = j; | |
} | |
} | |
function do_patch() { | |
var i = ui_state.in_anchor; | |
var j = ui_state.out_anchor; | |
var val; | |
if (patched[i][j]) { | |
patched[i][j] = false; | |
val = 0; | |
} | |
else { | |
patched[i][j] = true; | |
val = 1; | |
} | |
reset_ui_state(); | |
outlet(2, val); | |
outlet(1, j); | |
outlet(0, i); | |
} | |
//----------------- | |
//--- helpers | |
// calculate bounding boxes for I/O nodes (world coordinates) | |
function set_node_bounds() { | |
var in_w = (2.0 / num_ins); // leaving no space at all, lookin dumb | |
var in_h = 0.2; | |
for (i=0; i<num_ins; i++) { | |
var l = (i * in_w) - 1.0; | |
in_bounds[i] = {"left":l, "right":l+in_w, "top":1, "bottom":1-in_h}; | |
post(in_bounds[i].left, in_bounds[i].right, in_bounds[i].top, in_bounds[i].bottom); | |
in_connected[i] = false; | |
in_hover[i] = false; | |
} | |
var out_w = (2.0 / num_ins); | |
var out_h = 0.2; | |
for (i=0; i<num_outs; i++) { | |
var l = (i * out_w) - 1.0; | |
out_bounds[i] = {"left":l, "right":l+out_w, "top":out_h - 1, "bottom":-1.0}; | |
out_connected[i] = false; | |
out_hover[i] = false; | |
} | |
} | |
function check_node_bounds(b, pos) { | |
var x = pos[0]; | |
var y = pos[1]; | |
return ((x >= b.left) && (x <= b.right) && (y <= b.top) && (y >= b.bottom)); | |
} | |
function get_in_coords(i) { | |
var b = in_bounds[i]; | |
return [b.left + (b.right - b.left) / 2, b.bottom]; | |
} | |
function get_out_coords(j) { | |
var b = out_bounds[j]; | |
return [b.left + (b.right - b.left) / 2, b.top]; | |
} | |
//------------------------ | |
//--- drawing | |
function redraw() { | |
with(sketch) { | |
glclearcolor([1.0, 1.0, 1.0, 1.0]); | |
glclear(); | |
// draw input nodes | |
for(i=0; i<num_ins; i++) { | |
var b = in_bounds[i]; | |
// choose appropriate color based on input state | |
if(in_hover[i]) { | |
glcolor(Color.in_hover); | |
} else { | |
if(in_connected[i]) { | |
glcolor(Color.in_on); | |
} else { | |
glcolor(Color.in_off); | |
} | |
} | |
// draw filled quad | |
quad(b.left, b.top, 0, b.right, b.top, 0, b.right, b.bottom, 0, b.left, b.bottom, 0); | |
// draw black bounding box | |
glcolor(0.0, 0.0, 0.0, 1.0); | |
framequad(b.left, b.top, 0, b.right, b.top, 0, b.right, b.bottom, 0, b.left, b.bottom, 0); | |
} | |
// draw output nodes | |
for(i=0; i<num_ins; i++) { | |
var b = out_bounds[i]; | |
// choose appropriate color based on input state | |
if(out_hover[i]) { | |
glcolor(Color.out_hover); | |
} else { | |
if(out_connected[i]) { | |
glcolor(Color.out_on); | |
} else { | |
glcolor(Color.out_off); | |
} | |
} | |
// draw filled quad | |
quad(b.left, b.top, 0, b.right, b.top, 0, b.right, b.bottom, 0, b.left, b.bottom, 0); | |
// draw black bounding box | |
glcolor(0.0, 0.0, 0.0, 1.0); | |
framequad(b.left, b.top, 0, b.right, b.top, 0, b.right, b.bottom, 0, b.left, b.bottom, 0); | |
} | |
// draw existing patch cables | |
for(i=0; i<num_ins; i++) { | |
for(j=0; j<num_outs; j++) { | |
if(patched[i][j]) { | |
var a = get_in_coords(i); | |
var b = get_out_coords(j); | |
moveto(a[0], a[1]); | |
lineto(b[0], b[1]); | |
} | |
} | |
} | |
// draw current patch cable | |
if(ui_state.is_patching) { | |
var a, b; | |
if(ui_state.in_anchor != -1) { | |
a = get_in_coords(ui_state.in_anchor); | |
b = [wx, wy]; | |
} else { | |
a = [wx, wy]; | |
b = get_out_coords(ui_state.out_anchor); | |
} | |
moveto(a[0], a[1]); | |
lineto(b[0], b[1]); | |
} | |
} | |
refresh(); | |
} | |
set_node_bounds(); | |
redraw(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"patcher" : { | |
"fileversion" : 1, | |
"appversion" : { | |
"major" : 8, | |
"minor" : 0, | |
"revision" : 0, | |
"architecture" : "x64", | |
"modernui" : 1 | |
} | |
, | |
"classnamespace" : "box", | |
"rect" : [ -1782.0, -38.0, 396.0, 701.0 ], | |
"bglocked" : 0, | |
"openinpresentation" : 0, | |
"default_fontsize" : 12.0, | |
"default_fontface" : 0, | |
"default_fontname" : "Arial", | |
"gridonopen" : 1, | |
"gridsize" : [ 15.0, 15.0 ], | |
"gridsnaponopen" : 1, | |
"objectsnaponopen" : 1, | |
"statusbarvisible" : 2, | |
"toolbarvisible" : 1, | |
"lefttoolbarpinned" : 0, | |
"toptoolbarpinned" : 0, | |
"righttoolbarpinned" : 0, | |
"bottomtoolbarpinned" : 0, | |
"toolbars_unpinned_last_save" : 0, | |
"tallnewobj" : 0, | |
"boxanimatetime" : 200, | |
"enablehscroll" : 1, | |
"enablevscroll" : 1, | |
"devicewidth" : 0.0, | |
"description" : "", | |
"digest" : "", | |
"tags" : "", | |
"style" : "", | |
"subpatcher_template" : "", | |
"boxes" : [ { | |
"box" : { | |
"id" : "obj-15", | |
"maxclass" : "number", | |
"numinlets" : 1, | |
"numoutlets" : 2, | |
"outlettype" : [ "", "bang" ], | |
"parameter_enable" : 0, | |
"patching_rect" : [ 147.0, 269.0, 50.0, 22.0 ] | |
} | |
} | |
, { | |
"box" : { | |
"id" : "obj-14", | |
"maxclass" : "number", | |
"numinlets" : 1, | |
"numoutlets" : 2, | |
"outlettype" : [ "", "bang" ], | |
"parameter_enable" : 0, | |
"patching_rect" : [ 88.0, 269.0, 50.0, 22.0 ] | |
} | |
} | |
, { | |
"box" : { | |
"id" : "obj-12", | |
"maxclass" : "newobj", | |
"numinlets" : 3, | |
"numoutlets" : 1, | |
"outlettype" : [ "" ], | |
"patching_rect" : [ 29.0, 331.0, 64.0, 22.0 ], | |
"text" : "pack 0 0 0" | |
} | |
} | |
, { | |
"box" : { | |
"columns" : 4, | |
"id" : "obj-8", | |
"maxclass" : "matrixctrl", | |
"numinlets" : 1, | |
"numoutlets" : 2, | |
"outlettype" : [ "list", "list" ], | |
"parameter_enable" : 0, | |
"patching_rect" : [ 29.0, 373.0, 102.0, 101.0 ] | |
} | |
} | |
, { | |
"box" : { | |
"id" : "obj-1", | |
"maxclass" : "number", | |
"numinlets" : 1, | |
"numoutlets" : 2, | |
"outlettype" : [ "", "bang" ], | |
"parameter_enable" : 0, | |
"patching_rect" : [ 29.0, 269.0, 50.0, 22.0 ] | |
} | |
} | |
, { | |
"box" : { | |
"id" : "obj-6", | |
"maxclass" : "message", | |
"numinlets" : 2, | |
"numoutlets" : 1, | |
"outlettype" : [ "" ], | |
"patching_rect" : [ 29.0, 15.0, 35.0, 22.0 ], | |
"text" : "open" | |
} | |
} | |
, { | |
"box" : { | |
"filename" : "mouseover_ui.js", | |
"id" : "obj-2", | |
"maxclass" : "jsui", | |
"numinlets" : 1, | |
"numoutlets" : 3, | |
"outlettype" : [ "", "", "" ], | |
"parameter_enable" : 0, | |
"patching_rect" : [ 29.0, 58.0, 211.0, 196.0 ] | |
} | |
} | |
], | |
"lines" : [ { | |
"patchline" : { | |
"destination" : [ "obj-12", 0 ], | |
"source" : [ "obj-1", 0 ] | |
} | |
} | |
, { | |
"patchline" : { | |
"destination" : [ "obj-8", 0 ], | |
"source" : [ "obj-12", 0 ] | |
} | |
} | |
, { | |
"patchline" : { | |
"destination" : [ "obj-12", 1 ], | |
"source" : [ "obj-14", 0 ] | |
} | |
} | |
, { | |
"patchline" : { | |
"destination" : [ "obj-12", 2 ], | |
"source" : [ "obj-15", 0 ] | |
} | |
} | |
, { | |
"patchline" : { | |
"destination" : [ "obj-1", 0 ], | |
"source" : [ "obj-2", 0 ] | |
} | |
} | |
, { | |
"patchline" : { | |
"destination" : [ "obj-14", 0 ], | |
"source" : [ "obj-2", 1 ] | |
} | |
} | |
, { | |
"patchline" : { | |
"destination" : [ "obj-15", 0 ], | |
"source" : [ "obj-2", 2 ] | |
} | |
} | |
, { | |
"patchline" : { | |
"destination" : [ "obj-2", 0 ], | |
"source" : [ "obj-6", 0 ] | |
} | |
} | |
], | |
"dependency_cache" : [ { | |
"name" : "mouseover_ui.js", | |
"bootpath" : "~/max", | |
"patcherrelativepath" : ".", | |
"type" : "TEXT", | |
"implicit" : 1 | |
} | |
], | |
"autosave" : 0 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment