Commit 8b30e378 authored by Jonathan Wilkes's avatar Jonathan Wilkes
Browse files

Merge branch 'scrollbars-n-arrays' into plots-fitting-gops

parents bedfb40a e2e65133
......@@ -124,7 +124,8 @@ mark.console_find_highlighted {
/* selected connection between objects */
.cord.signal.selected_line,
.cord.control.selected_line {
.cord.control.selected_line,
#newcord {
stroke: #cc9933;
}
......
......@@ -20,6 +20,13 @@ body {
font-family: "DejaVu Sans Mono";
}
/* delete the default scrollbars, and let's make our own */
body::-webkit-scrollbar {
width: 0px;
height: 0px;
background: transparent;
}
.noselect {
-webkit-touch-callout: none;
-webkit-user-select: none;
......@@ -228,9 +235,10 @@ mark.console_find_highlighted {
stroke: #565;
}
/* selected connection between objects */
/* selected connection between objects, or a new cord not yet connected */
.cord.signal.selected_line,
.cord.control.selected_line {
.cord.control.selected_line,
#newcord {
stroke: #e87216;
}
......@@ -387,7 +395,7 @@ text {
#patchsvg.editmode .comment .border {
stroke: #aaa;
stroke-dasharray: 8 4;
stroke-dasharray: 3 2;
}
/* A little hack for special case of [cnv].
......@@ -425,21 +433,22 @@ text {
/* text inside selected objects */
:not(.gop).selected text {
fill: blue;
fill: #e87216;
}
/* for an object that didn't create */
.obj .border.broken_border {
fill: #f7f7f7;
fill: #f7d7d7;
stroke: #f00;
stroke-dasharray: 3 2;
stroke-width: 2;
stroke-dasharray: 6 2;
}
/* control inlet */
.xlet_control {
stroke: #777;
fill: white;
// stroke-width: 1;
stroke-width: 1;
}
/* signal inlet */
......@@ -458,7 +467,7 @@ text {
/* text label for an iemgui */
.iemgui_label_selected {
fill: blue;
fill: #e87216;
}
/* test of xlet hover animation... this should
......@@ -474,19 +483,26 @@ text {
rx: 1;
ry: 1;
}
100% {
stroke-width: 20;
stroke-opacity: 0.2;
rx: 50;
ry: 50;
33% {
stroke-width: 12;
stroke-opacity: 1;
rx: 1;
ry: 1;
}
66% {
stroke-width: 5;
stroke-opacity: 1;
rx: 1;
ry: 1;
}
}
/* can't remember why this was tagged !important */
.xlet_selected {
stroke: orange !important;
fill: orange;
-webkit-animation: fizzle 0.4s linear 1;
stroke: #e87216;
fill: #e87216;
stroke-width: 5;
-webkit-animation: fizzle 0.4s ease-in 1;
}
#canvas_find {
......
......@@ -135,7 +135,8 @@ mark.console_find_highlighted {
/* selected connection between objects */
.cord.signal.selected_line,
.cord.control.selected_line {
.cord.control.selected_line,
#newcord {
stroke: blue;
}
......
......@@ -128,7 +128,8 @@ mark.console_find_highlighted {
/* selected connection between objects */
.cord.signal.selected_line,
.cord.control.selected_line {
.cord.control.selected_line,
#newcord {
stroke: #268bd2;
}
......
......@@ -128,7 +128,8 @@ mark.console_find_highlighted {
/* selected connection between objects */
.cord.signal.selected_line,
.cord.control.selected_line {
.cord.control.selected_line,
#newcord {
stroke: #b58900;
}
......
......@@ -125,7 +125,8 @@ mark.console_find_highlighted {
/* selected connection between objects */
.cord.signal.selected_line,
.cord.control.selected_line {
.cord.control.selected_line,
#newcord {
stroke: #53b83b;
}
......
......@@ -125,7 +125,8 @@ mark.console_find_highlighted {
/* selected connection between objects */
.cord.signal.selected_line,
.cord.control.selected_line {
.cord.control.selected_line,
#newcord {
stroke: blue;
}
......
......@@ -408,7 +408,8 @@ function nw_create_window(cid, type, width, height, xpos, ypos, attr_array) {
// the window. Ideally we would just get rid of the canvas menu
// altogether to simplify things. But we'd have to add some kind of
// widget for the "Put" menu.
height: height + 23,
// ico@vt.edu: on 0.46.2 this is now 25, go figure...
height: height + 25,
x: xpos,
y: ypos
}, function (new_win) {
......
......@@ -76,6 +76,8 @@
</button>
</div>
</dialog>
<div id="hscroll" style="background-color: #00000044; position: fixed; left: 2px; bottom: 2px; border-radius: 0px; width: 10px; height: 5px; visibility: hidden;"></div>
<div id="vscroll" style="background-color: #00000044; position: fixed; right: 2px; top: 2px; border-radius: 0px; width: 5px; height: 10px; visibility: hidden;"></div>
<script type="text/javascript" src="./pd_canvas.js"></script>
</body>
</html>
......@@ -233,6 +233,13 @@ var canvas_events = (function() {
return false;
},
mousedown: function(evt) {
// ico@vt.edu capture middle click for a different type of scroll
// currently disabled due to problem with scrollBy and zoom
/*if (evt.which == 2)
{
evt.stopPropagation();
evt.preventDefault();
}*/
var target_id, resize_type;
if (target_is_scrollbar(evt)) {
return;
......@@ -521,6 +528,64 @@ var canvas_events = (function() {
}
canvas_events[canvas_events.get_previous_state()]();
},
hscroll_mouseup: function(evt) {
canvas_events[canvas_events.get_previous_state()]();
},
hscroll_mousemove: function(evt) {
if (evt.movementX != 0) {
//console.log("move: " + e.movementX);
var hscroll = document.getElementById("hscroll");
var svg_elem = document.getElementById("patchsvg");
var min_width = document.body.clientWidth + 3;
var width = svg_elem.getAttribute('width');
var xScrollSize;
xScrollSize = hscroll.offsetWidth;
var xTranslate = evt.movementX *
((width - min_width)/(min_width - xScrollSize)) *
(evt.movementX > 0 ? 1 : 0.75);
if (xTranslate > 0 && xTranslate < 1) {
xTranslate = 1;
}
if (xTranslate < 0 && xTranslate > -1) {
xTranslate = -1;
}
//console.log(xTranslate);
window.scrollBy(xTranslate, 0);
}
},
vscroll_mouseup: function(evt) {
canvas_events[canvas_events.get_previous_state()]();
},
vscroll_mousemove: function(evt) {
if (evt.movementY != 0) {
//console.log("move: " + e.movementY);
var vscroll = document.getElementById("vscroll");
var svg_elem = document.getElementById("patchsvg");
var min_height = document.body.clientHeight + 3;
var height = svg_elem.getAttribute('height');
var yScrollSize;
yScrollSize = vscroll.offsetHeight;
var yTranslate = evt.movementY *
((height - min_height)/(min_height - yScrollSize)) *
(evt.movementY > 0 ? 2 : 1.5);
if (yTranslate > 0 && yTranslate < 1) {
yTranslate = 1;
}
if (yTranslate < 0 && yTranslate > -1) {
yTranslate = -1;
}
//console.log(yTranslate);
window.scrollBy(0, yTranslate);
}
},
dropdown_menu_keydown: function(evt) {
var select_elem = document.querySelector("#dropdown_list"),
li;
......@@ -729,6 +794,16 @@ var canvas_events = (function() {
document.addEventListener("mouseup",
events.iemgui_label_mouseup, false);
},
hscroll_drag: function() {
canvas_events.none();
document.addEventListener("mouseup", events.hscroll_mouseup, false);
document.addEventListener("mousemove", events.hscroll_mousemove, false);
},
vscroll_drag: function() {
canvas_events.none();
document.addEventListener("mouseup", events.vscroll_mouseup, false);
document.addEventListener("mousemove", events.vscroll_mousemove, false);
},
text: function() {
canvas_events.none();
......@@ -770,6 +845,9 @@ var canvas_events = (function() {
document.addEventListener("keydown", events.find_keydown, false);
state = "search";
},
update_scrollbars: function() {
pdgui.gui_update_scrollbars(name);
},
register: function(n) {
name = n;
},
......@@ -887,6 +965,13 @@ var canvas_events = (function() {
console.log("tried to save something");
}, false
);
// add listener for the scrollbars
document.getElementById("hscroll").
addEventListener("mousedown", canvas_events.hscroll_drag, false);
document.getElementById("vscroll").
addEventListener("mousedown", canvas_events.vscroll_drag, false);
// Whoa-- huge workaround! Right now we're getting
// the popup menu the way Pd Vanilla does it:
// 1) send a mouse(down) message to Pd
......@@ -1030,15 +1115,16 @@ var canvas_events = (function() {
gui.Window.get().on("maximize", function() {
pdgui.gui_canvas_get_scroll(name);
});
gui.Window.get().on("unmaximize", function() {
gui.Window.get().on("restore", function() {
pdgui.gui_canvas_get_scroll(name);
});
gui.Window.get().on("resize", function() {
pdgui.post("resize");
pdgui.gui_canvas_get_scroll(name);
});
gui.Window.get().on("focus", function() {
nw_window_focus_callback(name);
});
});
gui.Window.get().on("blur", function() {
nw_window_blur_callback(name);
});
......@@ -1047,6 +1133,12 @@ var canvas_events = (function() {
pdgui.pdsend(name, "setbounds", x, y,
x + w.width, y + w.height);
});
// map onscroll event
document.addEventListener("scroll", function() {
pdgui.gui_update_scrollbars(name);
});
// set minimum window size
gui.Window.get().setMinimumSize(150, 100);
}
......@@ -1514,6 +1606,7 @@ function nw_create_patch_window_menus(gui, w, name) {
click: function() {
var win = gui.Window.get();
win.toggleFullscreen();
pdgui.gui_canvas_get_scroll(name);
}
});
......
This diff is collapsed.
......@@ -987,8 +987,8 @@ void iemgui_label_draw_new(t_iemgui *x)
{
char col[8];
t_canvas *canvas=glist_getcanvas(x->x_glist);
int x1=text_xpix(&x->x_obj, x->x_glist)+x->legacy_x;
int y1=text_ypix(&x->x_obj, x->x_glist)+x->legacy_y;
int x1=text_xpix(&x->x_obj, x->x_glist) + (sys_legacy ? x->legacy_x : 0);
int y1=text_ypix(&x->x_obj, x->x_glist) + (sys_legacy ? x->legacy_y : 0);
iemgui_getrect_legacy_label(x, &x1, &y1);
sprintf(col, "#%6.6x", x->x_lcol);
gui_vmess("gui_iemgui_label_new", "xxiissssi",
......@@ -1018,8 +1018,8 @@ void iemgui_label_draw_move(t_iemgui *x)
gui_vmess("gui_iemgui_label_coords", "xxii",
canvas,
x,
x->x_ldx + x->legacy_x,
x->x_ldy + x->legacy_y);
x->x_ldx + (sys_legacy ? x->legacy_x : 0),
x->x_ldy + (sys_legacy ? x->legacy_y : 0));
}
void iemgui_label_draw_config(t_iemgui *x)
......
......@@ -713,16 +713,38 @@ void canvas_args_to_string(char *namebuf, t_canvas *x)
strcpy(namebuf, " (");
for (i = 0; i < env->ce_argc; i++)
{
if (strlen(namebuf) > MAXPDSTRING/2 - 5)
if (strlen(namebuf) > MAXPDSTRING / 2 - 5)
break;
if (i != 0)
strcat(namebuf, " ");
atom_string(&env->ce_argv[i], namebuf + strlen(namebuf),
MAXPDSTRING/2);
atom_string(&env->ce_argv[i], namebuf + strlen(namebuf),
MAXPDSTRING / 2);
}
strcat(namebuf, ")");
}
else namebuf[0] = 0;
else
{
namebuf[0] = 0;
t_gobj *g = NULL;
t_garray *a = NULL;
t_symbol *arrayname;
int found = 0, res;
for (g = x->gl_list; g; g = g->g_next)
{
if (pd_class(&g->g_pd) == garray_class)
{
res = garray_getname((t_garray *)g, &arrayname);
if (found)
{
strcat(namebuf, " ");
}
strcat(namebuf, arrayname->s_name);
found++;
//post("found=%d %s %s", found, arrayname->s_name, namebuf);
}
}
}
}
void canvas_reflecttitle(t_canvas *x)
......@@ -1314,8 +1336,8 @@ static void canvas_relocate(t_canvas *x, t_symbol *canvasgeom,
< 4 ||
sscanf(topgeom->s_name, "%dx%d+%d+%d", &tw, &th, &txpix, &typix) < 4)
bug("canvas_relocate");
/* for some reason this is initially called with cw=ch=1 so
we just suppress that here. */
/* for some reason this is initially called with cw=ch=1 so
we just suppress that here. */
if (cw > 5 && ch > 5)
canvas_dosetbounds(x, txpix, typix,
txpix + cw, typix + ch);
......@@ -1325,24 +1347,44 @@ static void canvas_relocate(t_canvas *x, t_symbol *canvasgeom,
t_array *a = NULL;
int num_elem = 0;
//int found_garray = 0;
for (g = x->gl_list; g; g = g->g_next)
{
//fprintf(stderr, "searching\n");
//post("searching");
//for subpatch garrays
if (pd_class(&g->g_pd) == garray_class)
{
//fprintf(stderr,"found ya\n");
//post("found ya");
ga = (t_garray *)g;
if (ga)
{
a = garray_getarray(ga);
num_elem = a->a_n;
garray_fittograph(ga, num_elem, 1);
//found_garray = 1;
}
}
}
canvas_checkconfig(x);
// ico@vt.edu:
// Here we update only scrollbars to avoid race condition
// caused by doing gui_canvas_get_scroll which in turn
// calls canvas_relocate to ensure garrays in subpatches
// are properly updated when those windows are resized.
// given that the scroll update will happen likely faster
// than the return value from the backend, we do this to
// get rid of the stale scrollbars, e.g. when making the
// window smaller (at first the scrollbars are there because
// the garray has not been redrawn yet, and then we update
// scrollbars once again here below.
//if (found_garray == 1) {
//post("found garray");
gui_vmess("do_getscroll", "xi", x, 0);
//}
}
void canvas_popabstraction(t_canvas *x)
......
......@@ -172,7 +172,7 @@ static void canvas_nlet_conf (t_canvas *x, int type) {
void canvas_getscroll (t_canvas *x) {
//sys_vgui("pdtk_canvas_getscroll .x%lx.c\n",(long)x);
gui_vmess("gui_canvas_get_scroll", "x", x);
gui_vmess("gui_canvas_get_overriding_scroll", "x", x);
}
/* ---------------- generic widget behavior ------------------------- */
......@@ -2299,7 +2299,11 @@ static void canvas_rightclick(t_canvas *x, int xpos, int ypos, t_gobj *y_sel)
otherwise they end-up being dirty without visible notification
besides, why would one mess with their properties without
seeing what is inside them? CURRENTLY DISABLED */
//post("canvas_rightclick %d", (y && pd_class(&y->g_pd) == garray_class ? 1 : 0));
canprop = (!y || (y && class_getpropertiesfn(pd_class(&y->g_pd)))
// ico@vt.edu: the following ensures that even if we are clicking on
// a garray, we should still be able to get the canvas properties
|| (y && pd_class(&y->g_pd) == garray_class)
/*&& !canvas_isabstraction( ((t_glist*)y) )*/ );
canopen = (y && zgetfn(&y->g_pd, gensym("menu-open")));
/* we add an extra check for scalars to enable the "Open" button
......@@ -2478,9 +2482,12 @@ void canvas_vis(t_canvas *x, t_floatarg f)
canvas_destroy_editor(x);
}
//fprintf(stderr,"new\n");
/* ico@vt.edu: here we use hasarray only for toplevel garrays
because they require check_config every time resize is invoked.
We may need to expand this to include scalars, as well. */
canvas_create_editor(x);
canvas_args_to_string(argsbuf, x);
gui_vmess("gui_canvas_new", "xiisiissiiis",
gui_vmess("gui_canvas_new", "xiisiissiiiis",
x,
(int)(x->gl_screenx2 - x->gl_screenx1),
(int)(x->gl_screeny2 - x->gl_screeny1),
......@@ -2492,6 +2499,7 @@ void canvas_vis(t_canvas *x, t_floatarg f)
x->gl_dirty,
x->gl_noscroll,
x->gl_nomenu,
canvas_hasarray(x),
argsbuf);
/* It looks like this font size call is no longer needed,
......@@ -2618,13 +2626,7 @@ void canvas_setgraph(t_glist *x, int flag, int nogoprect)
// check if we have array inside GOP, if so,
// make sure hidetext is always hidden no matter what
t_gobj *g = x->gl_list;
int hasarray = 0;
while (g)
{
if (pd_class(&g->g_pd) == garray_class) hasarray = 1;
g = g->g_next;
}
int hasarray = canvas_hasarray(x);
if (hasarray) x->gl_hidetext = 1;
if (!nogoprect && !x->gl_goprect && !hasarray)
......@@ -2810,13 +2812,7 @@ static void canvas_donecanvasdialog(t_glist *x,
// check if we have array inside GOP, if so,
// make sure GOP/hidetext is always enabled no matter what
t_gobj *g = x->gl_list;
int hasarray = 0;
while (g)
{
if (pd_class(&g->g_pd) == garray_class) hasarray = 1;
g = g->g_next;
}
int hasarray = canvas_hasarray(x);
if (hasarray && graphme != 3)
{
graphme = 3; //gop flag + bit-shifted hidetext
......@@ -3233,6 +3229,7 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which,
to array_motion so that we can update corresponding send when
the array has been changed */
array_garray = NULL;
//post("canvas_doclick %d", doit);
t_gobj *y;
int shiftmod, runmode, altmod, doublemod = 0, rightclick,
......@@ -3479,10 +3476,14 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which,
canvas_check_nlet_highlights(x);
}
}
/* look for an outlet */
// if object is valid, has outlets,
// and we are within the bottom area of an object
else if (ob && (noutlet = obj_noutlets(ob)) && ypos >= y2-4)
/* look for an outlet
if object is valid, has outlets,
and we are within the bottom area of an object
ico@vt.edu: 2020-06-05 added expanded hotspot for
nlets for easier pinpointing
*/
else if (ob && (noutlet = obj_noutlets(ob)) &&
ypos >= y2-4-(x->gl_editor->canvas_cnct_inlet_tag[0] != 0 ? 2 : 0))
{
int width = x2 - x1;
int nout1 = (noutlet > 1 ? noutlet - 1 : 1);
......@@ -3490,8 +3491,13 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which,
int hotspot = x1 +
(width - IOWIDTH) * closest / (nout1);
// if we are within the boundaries of an nlet
/* ico@vt.edu: account for enlarged nlet when already
highlighted to make it easier to "hit" the nlet */
int enlarged = 0;
if (x->gl_editor->canvas_cnct_inlet_tag[0] == closest)
enlarged = 5;
if (closest < noutlet &&
xpos >= (hotspot-1) && xpos <= hotspot + (IOWIDTH+1))
xpos >= (hotspot-1-enlarged) && xpos <= hotspot + (IOWIDTH+1+enlarged))
{
if (doit)
{
......@@ -3566,8 +3572,12 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which,
}
}
/* look for an inlet (these are colored differently
since they are not connectable) */
else if (ob && (ninlet = obj_ninlets(ob)) && ypos <= y1+4)
since they are not connectable)
ico@vt.edu: 2020-06-05 added expanded hotspot for
nlets for easier pinpointing
*/
else if (ob && (ninlet = obj_ninlets(ob))
&& ypos <= y1+4+(x->gl_editor->canvas_cnct_inlet_tag[0] != 0 ? 2 : 0))
{
canvas_setcursor(x, CURSOR_EDITMODE_NOTHING);
int width = x2 - x1;
......@@ -3575,8 +3585,13 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which,
int closest = ((xpos-x1) * (nin1) + width/2)/width;
int hotspot = x1 +
(width - IOWIDTH) * closest / (nin1);
/* ico@vt.edu: account for enlarged nlet when already
highlighted to make it easier to "hit" the nlet */
int enlarged = 0;
if (x->gl_editor->canvas_cnct_inlet_tag[0] == closest)
enlarged = 5;
if (closest < ninlet &&
xpos >= (hotspot-1) && xpos <= hotspot + (IOWIDTH+1))
xpos >= (hotspot-1-enlarged) && xpos <= hotspot + (IOWIDTH+1+enlarged))
{
t_rtext *yr = glist_findrtext(x, (t_text *)&ob->ob_g);
......
......@@ -729,21 +729,32 @@ extern int garray_get_style(t_garray *x);
/* convert an x coordinate value to an x pixel location in window */
t_float glist_xtopixels(t_glist *x, t_float xval)
{
// ico@vt.edu: used to deal with the bar graph
t_float plot_offset = 0;
t_gobj *g = x->gl_list;