Commit dd632b2d authored by Jonathan Wilkes's avatar Jonathan Wilkes
Browse files

Merge branch 'ico-nwjs-04x-rebased'

parents 11f6610d 0b959eb0
Pipeline #2192 passed with stage
in 309 minutes and 19 seconds
......@@ -235,8 +235,6 @@ static void image_select(t_gobj *z, t_glist *glist, int state)
{
//fprintf(stderr,"image_select %d\n", state);
t_image *x = (t_image *)z;
gui_vmess("gui_image_toggle_border", "xxi",
glist_getcanvas(glist), x, state);
if (state)
{
if (x->x_glist == glist_getcanvas(glist))
......@@ -262,12 +260,14 @@ static void image_select(t_gobj *z, t_glist *glist, int state)
text_xpix(&x->x_obj, glist) + x->x_width/2,
text_ypix(&x->x_obj, glist) + x->x_height/2, x);
}
gui_vmess("gui_image_toggle_border", "xxi", glist_getcanvas(glist),
x, 1);
}
gui_vmess("gui_gobj_select", "xx", glist_getcanvas(glist), x);
//if (glist->gl_owner && !glist_istoplevel(glist))
//sys_vgui(".x%x.c addtag selected withtag %xS\n", glist_getcanvas(glist), x);
//sys_vgui(".x%x.c addtag selected withtag %xMT\n", glist_getcanvas(glist), x);
//sys_vgui(".x%x.c addtag selected withtag %xSEL\n", glist_getcanvas(glist), x);
gui_vmess("gui_gobj_select", "xx", glist_getcanvas(glist), x);
}
else
{
......@@ -276,6 +276,8 @@ static void image_select(t_gobj *z, t_glist *glist, int state)
//if (glist->gl_owner && !glist_istoplevel(glist))
//sys_vgui(".x%lx.c dtag %xS selected\n", glist_getcanvas(glist), x);
//sys_vgui(".x%lx.c dtag %xMT selected\n", glist_getcanvas(glist), x);
gui_vmess("gui_image_toggle_border", "xxi", glist_getcanvas(glist),
x, 0);
gui_vmess("gui_gobj_deselect", "xx", glist_getcanvas(glist), x);
}
}
......@@ -340,7 +342,7 @@ static int image_newclick(t_gobj *z, struct _glist *glist, int xpix, int ypix, i
if (doit && x->x_click)
outlet_bang(x->x_obj.ob_outlet);
// LATER: figure out how to do click on and click off
// and provide a toggle button behavior insteadS
// and provide a toggle button behavior instead
/*{
x->x_clicked = 1;
outlet_float(x->x_obj.ob_outlet, x->x_clicked);
......
......@@ -20,6 +20,13 @@ body {
font-family: "DejaVu Sans Mono";
}
/* delete the default scrollbars, and let's make our own */
.patch_body::-webkit-scrollbar {
width: 0px;
height: 0px;
background: transparent;
}
.noselect {
-webkit-touch-callout: none;
-webkit-user-select: none;
......@@ -272,7 +279,8 @@ mark.console_find_highlighted {
min-width: 3ch;
position: absolute;
display: table-cell;
padding: 3px 2px 3px 2px;
padding: 3px 1.5px 3px 1.5px;
margin-left: 1px;
/* box-shadow: inset 1px 0px 0px 1px #000; */
color: black; /* text color */
background-color: transparent;
......@@ -282,7 +290,7 @@ mark.console_find_highlighted {
}
#new_object_textentry.obj {
outline: 1px solid #e87216;
outline: 2px solid #e87216;
}
/* We're dynamically creating the svg background data in javascript
......@@ -312,9 +320,10 @@ text {
//cursor: default;
}
/* not sure if this is still needed */
/* not sure if this is still needed...
updated the coloring just in case */
.selected_border {
stroke: blue;
stroke: #e87216;
stroke-dasharray: none;
stroke-width: 1;
}
......@@ -391,6 +400,12 @@ text {
stroke-dasharray: 3 2;
}
/* ico@vt.edu: added selected border coloring
in edit mode only */
#patchsvg.editmode .comment.selected .border {
stroke: #e87216;
}
/* A little hack for special case of [cnv].
All other iemguis have a black border, but
[cnv] sets its selection rectangle to the
......@@ -418,14 +433,17 @@ text {
in plain English:
This lets us highlight an object's border, unless it is inside a gop
canvas.
ico@vt.edu added selection highlight only if we are in editmode
*/
:not(.gop).selected .border {
#patchsvg.editmode :not(.gop).selected .border {
stroke: #e87216;
display: inline;
}
/* text inside selected objects */
:not(.gop).selected text {
/* text inside selected objects
ico@vt.edu added selection highlight only if we are in editmode */
#patchsvg.editmode :not(.gop).selected text {
fill: #e87216;
}
......@@ -471,22 +489,12 @@ text {
for every pixel we move inside an xlet. */
@-webkit-keyframes fizzle {
0% {
stroke-width: 1;
stroke-opacity: 1;
rx: 1;
ry: 1;
}
33% {
stroke-width: 12;
stroke-opacity: 1;
rx: 1;
ry: 1;
}
66% {
100% {
stroke-width: 5;
stroke-opacity: 1;
rx: 1;
ry: 1;
}
}
......@@ -495,14 +503,19 @@ text {
stroke: #e87216;
fill: #e87216;
stroke-width: 5;
-webkit-animation: fizzle 0.4s ease-in 1;
-webkit-animation: fizzle 0.2s ease-in 1;
}
.xlet_disabled {
stroke: gray !important;
fill: gray !important;
}
#canvas_find {
width: 100%;
height: 1em;
padding-top: 4px;
padding-left: 8px;
padding-top: 2px;
padding-left: 2px;
padding-bottom: 8px;
background: silver;
position: fixed;
......@@ -513,10 +526,18 @@ text {
/* Dialog to ask to save the patch before quitting */
#save_before_quit {
background-color: #f3f3f3;
border:1px solid #bbb;
border:1px solid #f3f3f3;
padding: 12px;
margin: 12px;
box-shadow: 7px 7px 5px grey;
/*box-shadow: 7px 7px 5px grey;*/
left: 50%;
top: 50%;
width: 40%;
transform: translate(-50%, -50%);
}
dialog::backdrop {
background: rgba(0, 0, 0, 0.5);
}
/* Search dialog */
......
......@@ -17,8 +17,9 @@
</button>
</div>
<dialog id="save_before_quit">
<h4>Do you want to save the changes you made before closing the window?
</h4>
<h5 style="text-align: center;">
Do you want to save the changes you made before closing the window?
</h5>
<div class="submit_buttons">
<button type="button"
onClick="ok()"
......
......@@ -381,6 +381,28 @@ function nw_close_window(window) {
window.close(true);
}
function check_nwjs_version(version) {
// aggraef: check that process.versions["nw"] is at least the given version
// NOTE: We assume that "0.x.y" > "0.x", and just ignore any -beta
// suffixes if present.
var nwjs_array = process.versions["nw"].split("-")[0].
split(".").map(Number);
var vers_array = version.split("-")[0].
split(".").map(Number);
// lexicographic comparison
for (var i = 0; i < vers_array.length; ++i) {
if (nwjs_array.length <= i || vers_array[i] > nwjs_array[i])
return false;
else if (vers_array[i] < nwjs_array[i])
return true;
}
return vers_array.length <= nwjs_array.length;
}
// 0.46+ seems to be required for "null" to work. TODO: Bisect to get the
// actual minimum required version for this.
var null_pos = check_nwjs_version("0.46") ? "null" : "center";
function nw_create_window(cid, type, width, height, xpos, ypos, attr_array) {
// todo: make a separate way to format the title for OSX
var my_title;
......@@ -399,16 +421,25 @@ function nw_create_window(cid, type, width, height, xpos, ypos, attr_array) {
var eval_string = "register_window_id(" +
JSON.stringify(cid) + ", " +
JSON.stringify(attr_array) + ");";
//pdgui.post("x=" + xpos + " y=" + ypos);
var pos;
if (xpos == 0 && ypos == 0) {
pos = "center";
} else {
pos = null_pos;
}
gui.Window.open(my_file, {
title: my_title,
position: "center",
// ico@vt.edu: position in 0.46.2 overrides x and y below
position: pos,
focus: true,
width: width,
// We add 23 as a kludge to account for the menubar at the top of
// 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) {
......
......@@ -4,6 +4,9 @@
"main": "index.html",
"chromium-args": "--proxy-server=http://127.0.0.1 --password-store=basic",
"window": {
"icon": "./purr.png"
"icon": "./purr.png",
"position": "center",
"width": 540,
"height": 440
}
}
......@@ -39,11 +39,13 @@
defaultValue="Search in Canvas"
style="width:10em"/>
</label>
<label><span data-i18n="canvas.find.whole_word"></span>
<input type="checkbox"
<label><span data-i18n="canvas.find.whole_word"
style="margin-left: 7px; margin-right: -3px;"></span>
<input type="checkbox"
id="canvas_find_whole_word"
name="canvas_find_whole_word"
onchange="canvas_find_whole_word(this);"/>
onchange="canvas_find_whole_word(this);"
style="position: relative; top: 2px; margin-right: 5px;"/>
</label>
<button type="button"
id="canvas_find_button"
......@@ -55,9 +57,9 @@
<ol></ol>
</div>
<dialog id="save_before_quit">
<h4><span data-i18n="canvas.save_dialog.prompt"></span>
<h5 style="text-align: center;"><span data-i18n="canvas.save_dialog.prompt"></span>
<span id="save_before_quit_filename"></span>?
</h4>
</h5>
<div class="submit_buttons">
<button type="button"
id="yes_button"
......@@ -76,6 +78,8 @@
</button>
</div>
</dialog>
<div id="hscroll" style="background-color: rgba(0, 0, 0, 0.267); position: fixed; left: 2px; bottom: 2px; border-radius: 0px; width: 10px; height: 5px; visibility: hidden;"></div>
<div id="vscroll" style="background-color: rgba(0, 0, 0, 0.267); 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;
......@@ -325,8 +332,7 @@ var canvas_events = (function() {
pdgui.keydown(name, evt);
// prevent the default behavior of scrolling
// on arrow keys in editmode
if (document.querySelector("#patchsvg")
.classList.contains("editmode")) {
if (document.querySelector("#patchsvg")) {
if ([32, 37, 38, 39, 40].indexOf(evt.keyCode) > -1) {
evt.preventDefault();
}
......@@ -521,6 +527,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 +793,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 +844,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 +964,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,7 +1114,7 @@ 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() {
......@@ -1038,7 +1122,7 @@ var canvas_events = (function() {
});
gui.Window.get().on("focus", function() {
nw_window_focus_callback(name);
});
});
gui.Window.get().on("blur", function() {
nw_window_blur_callback(name);
});
......@@ -1047,6 +1131,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 +1604,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.
......@@ -1553,10 +1553,10 @@ void garray_redraw(t_garray *x)
*/
sys_queuegui(&x->x_gobj, x->x_glist, garray_doredraw);
/* 1-24-2015 Ico: this however causes painfully slow and inefficient red
when we use tabwrite which writes one point per array and requests
redraw after each point is changed. Thus it is deprecated in favor of
of the approach above */
/* 1-24-2015 Ico: the approach below, however causes painfully slow and
inefficient redraw when we use tabwrite which writes one point per
array and requests redraw after each point is changed. Thus it is
deprecated in favor of the approach above */
//garray_doredraw(&x->x_gobj, x->x_glist);
}
......@@ -1950,6 +1950,12 @@ static void garray_print(t_garray *x)
x->x_realname->s_name, array->a_templatesym->s_name, array->a_n);
}
/* ico@vt.edu: used for scalar to detect type and thereby adjust visual offset */
int garray_get_style(t_garray *x)
{
return(x->x_style);
}
void g_array_setup(void)
{
garray_class = class_new(gensym("array"), 0, (t_method)garray_free,
......
......@@ -704,6 +704,8 @@ t_symbol *canvas_makebindsym(t_symbol *s)
return (gensym(buf));
}
int garray_getname(t_garray *x, t_symbol **namep);
void canvas_args_to_string(char *namebuf, t_canvas *x)
{
t_canvasenvironment *env = canvas_getenv(x);
......@@ -713,16 +715,37 @@ 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_symbol *arrayname;
int found = 0;
for (g = x->gl_list; g; g = g->g_next)
{
if (pd_class(&g->g_pd) == garray_class)
{
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 +1337,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 +1348,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)
......@@ -2206,9 +2249,7 @@ static void canvas_f(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
}
// if we are part of a restore message
// of a subpatch in the form "#X restore..., f 123456789+;"
if (pd_class(last_typedmess_pd) == canvas_class &&
(t_canvas *)last_typedmess_pd == x &&
last_typedmess == gensym("restore"))
if (!x->gl_list || !strcmp(last_typedmess->s_name, "restore"))
{
if (x->gl_owner && !x->gl_isgraph)
{
......@@ -2399,7 +2440,7 @@ void canvasgop__motionhook(t_scalehandle *sh, t_floatarg mouse_x,
that is being used to draw the gop red rect move anchor atm. So
rather than muck around with that code, we just set a pointer to
whatever our toplevel is here: */
t_glist *owner = canvas_getrootfor(x);
t_glist *owner = glist_getcanvas(x);
/* Just unvis the object, then vis it once we've done our
mutation and checks */