Commit 3cf74797 authored by user's avatar user
Browse files

got a very early working version that does _all_ object text editing (arrow...

got a very early working version that does _all_ object text editing (arrow keys, selection, etc.) in the GUI. (However, it still depends on g_rtext.c for doing everything else.)
parent 3fb7aab2
......@@ -43,120 +43,155 @@ function add_keymods(key, evt) {
var canvas_events = (function() {
var name,
mousemove = function(evt) {
//pdgui.gui_post("x: " + evt.pageX + " y: " + evt.pageY +
// " modifier: " + (evt.shiftKey + (evt.ctrlKey << 1)));
pdgui.pdsend(name +
" motion " + evt.pageX + " " + evt.pageY + " " +
(evt.shiftKey + (evt.ctrlKey << 1)));
evt.stopPropagation();
evt.preventDefault();
return false;
textbox = function () {
return document.getElementById('new_object_textentry');
},
mousedown = function(evt) {
// tk events are one greater than html5...
var b = evt.button + 1;
var mod;
// For some reason right-click sends a modifier value of "8",
// and canvas_doclick in g_editor.c depends on that value to
// do the right thing. So let's hack...
if (b === 3) { // right-click
mod = 8;
} else {
mod = (evt.shiftKey + (evt.ctrlKey << 1));
}
pdgui.pdsend(name + " mouse " + evt.pageX + " " + evt.pageY + " " +
b + " " + mod);
//evt.stopPropagation();
evt.preventDefault();
},
mouseup = function(evt) {
//pdgui.gui_post("mouseup: x: " + evt.pageX + " y: " + evt.pageY +
// " button: " + (evt.button + 1));
pdgui.pdsend(name +
" mouseup " + evt.pageX + " " + evt.pageY + " " +
(evt.button + 1));
evt.stopPropagation();
evt.preventDefault();
},
keydown = function(evt) {
var key_code = evt.keyCode;
var hack = null; // hack for unprintable ascii codes
switch(key_code) {
case 8:
case 9:
case 10:
case 27:
//case 32:
case 127: hack = key_code; break;
case 37: hack = add_keymods('Left', evt); break;
case 38: hack = add_keymods('Up', evt); break;
case 39: hack = add_keymods('Right', evt); break;
case 40: hack = add_keymods('Down', evt); break;
case 33: hack = add_keymods('Prior', evt); break;
case 34: hack = add_keymods('Next', evt); break;
case 35: hack = add_keymods('End', evt); break;
case 36: hack = add_keymods('Home', evt); break;
// Need to handle Control key, Alt
case 16: hack = 'Shift'; break;
case 17: hack = 'Control'; break;
case 18: hack = 'Alt'; break;
}
if (hack !== null) {
pdgui.gui_canvas_sendkey(name, 1, evt, hack);
pdgui.set_keymap(key_code, hack);
events = {
mousemove: function(evt) {
//pdgui.gui_post("x: " + evt.pageX + " y: " + evt.pageY +
// " modifier: " + (evt.shiftKey + (evt.ctrlKey << 1)));
pdgui.pdsend(name +
" motion " + evt.pageX + " " + evt.pageY + " " +
(evt.shiftKey + (evt.ctrlKey << 1)));
evt.stopPropagation();
evt.preventDefault();
return false;
},
mousedown: function(evt) {
// tk events are one greater than html5...
var b = evt.button + 1;
var mod;
// For some reason right-click sends a modifier value of "8",
// and canvas_doclick in g_editor.c depends on that value to
// do the right thing. So let's hack...
if (b === 3) { // right-click
mod = 8;
} else {
mod = (evt.shiftKey + (evt.ctrlKey << 1));
}
pdgui.pdsend(name +
" mouse " + evt.pageX + " " + evt.pageY + " " +
b + " " + mod);
//evt.stopPropagation();
evt.preventDefault();
},
mouseup: function(evt) {
//pdgui.gui_post("mouseup: x: " +
// evt.pageX + " y: " + evt.pageY +
// " button: " + (evt.button + 1));
pdgui.pdsend(name +
" mouseup " + evt.pageX + " " + evt.pageY + " " +
(evt.button + 1));
evt.stopPropagation();
evt.preventDefault();
},
keydown: function(evt) {
var key_code = evt.keyCode;
var hack = null; // hack for unprintable ascii codes
switch(key_code) {
case 8:
case 9:
case 10:
case 27:
//case 32:
case 127: hack = key_code; break;
case 37: hack = add_keymods('Left', evt); break;
case 38: hack = add_keymods('Up', evt); break;
case 39: hack = add_keymods('Right', evt); break;
case 40: hack = add_keymods('Down', evt); break;
case 33: hack = add_keymods('Prior', evt); break;
case 34: hack = add_keymods('Next', evt); break;
case 35: hack = add_keymods('End', evt); break;
case 36: hack = add_keymods('Home', evt); break;
// Need to handle Control key, Alt
case 16: hack = 'Shift'; break;
case 17: hack = 'Control'; break;
case 18: hack = 'Alt'; break;
}
if (hack !== null) {
pdgui.gui_canvas_sendkey(name, 1, evt, hack);
pdgui.set_keymap(key_code, hack);
}
pdgui.gui_post("keydown time: keycode is " + evt.keyCode);
last_keydown = evt.keyCode;
//evt.stopPropagation();
//evt.preventDefault();
},
keypress: function(evt) {
pdgui.gui_canvas_sendkey(name, 1, evt, evt.charCode);
pdgui.set_keymap(last_keydown, evt.charCode);
pdgui.gui_post("keypress time: charcode is " + evt.charCode);
// Don't do things like scrolling on space, arrow keys, etc.
//evt.stopPropagation();
evt.preventDefault();
},
keyup: function(evt) {
var my_char_code = pdgui.get_char_code(evt.keyCode);
pdgui.gui_canvas_sendkey(name, 0, evt, my_char_code);
pdgui.gui_post("keyup time: charcode is: " + my_char_code);
evt.stopPropagation();
evt.preventDefault();
},
text_mousemove: function(evt) { // we may not need this one
evt.stopPropagation();
//evt.preventDefault();
return false;
},
text_mousedown: function(evt) {
if (textbox() !== evt.target) {
pdgui.gui_post("my content was " + textbox().textContent);
pdgui.pdsend(name + " stringforobj "
+ textbox().textContent);
events.mousedown(evt);
canvas_events.normal();
}
evt.stopPropagation();
//evt.preventDefault();
return false;
},
text_mouseup: function(evt) {
pdgui.gui_post("mouseup target is " +
evt.target + " and textbox is " + textbox());
// if (evt.target === textbox) {
// pdgui.gui_post("it's a mouseup in a textbox");
// } else {
// pdgui.gui_post("it's a mouseup outside a textbox");
// }
// evt.stopPropagation();
//evt.preventDefault();
return false;
},
text_keydown: function(evt) {
evt.stopPropagation();
//evt.preventDefault();
return false;
},
text_keyup: function(evt) {
evt.stopPropagation();
//evt.preventDefault();
return false;
},
text_keypress: function(evt) {
evt.stopPropagation();
//evt.preventDefault();
return false;
},
floating_text_click: function(evt) {
pdgui.gui_post("leaving floating mode");
canvas_events.text();
evt.stopPropagation();
evt.preventDefault();
return false;
},
floating_text_keypress: function(evt) {
pdgui.gui_post("leaving floating mode");
canvas_events.text();
evt.stopPropagation();
evt.preventDefault();
return false;
}
pdgui.gui_post("keydown time: keycode is " + evt.keyCode);
last_keydown = evt.keyCode;
//evt.stopPropagation();
//evt.preventDefault();
},
keypress = function(evt) {
pdgui.gui_canvas_sendkey(name, 1, evt, evt.charCode);
pdgui.set_keymap(last_keydown, evt.charCode);
pdgui.gui_post("keypress time: charcode is " + evt.charCode);
// Don't do things like scrolling on space, arrow keys, etc.
//evt.stopPropagation();
evt.preventDefault();
},
keyup = function(evt) {
var my_char_code = pdgui.get_char_code(evt.keyCode);
pdgui.gui_canvas_sendkey(name, 0, evt, my_char_code);
pdgui.gui_post("keyup time: charcode is: " + my_char_code);
evt.stopPropagation();
evt.preventDefault();
},
text_mousemove = function(evt) {
evt.stopPropagation();
//evt.preventDefault();
return false;
},
text_mousedown = function(evt) {
evt.stopPropagation();
//evt.preventDefault();
return false;
},
text_mouseup = function(evt) {
evt.stopPropagation();
//evt.preventDefault();
return false;
},
text_keydown = function(evt) {
evt.stopPropagation();
//evt.preventDefault();
return false;
},
text_keyup = function(evt) {
evt.stopPropagation();
//evt.preventDefault();
return false;
},
text_keypress = function(evt) {
evt.stopPropagation();
//evt.preventDefault();
return false;
}
;
......@@ -195,7 +230,6 @@ var canvas_events = (function() {
}, false
);
// closing the Window
// this isn't actually closing the window yet
nw.Window.get().on("close", function() {
......@@ -203,35 +237,48 @@ var canvas_events = (function() {
});
return {
none: function() {
var name;
for (var prop in events) {
if (events.hasOwnProperty(prop)) {
name = prop.split('_');
name = name[name.length -1];
document.removeEventListener(name, events[prop], false);
}
}
},
normal: function() {
document.removeEventListener("mousemove", text_mousemove, false);
document.removeEventListener("keydown", text_keydown, false);
document.removeEventListener("keypress", text_keypress, false);
document.removeEventListener("keyup", text_keyup, false);
document.removeEventListener("mousedown", text_mousedown, false);
document.removeEventListener("mouseup", text_mouseup, false);
document.addEventListener("mousemove", mousemove, false);
document.addEventListener("keydown", keydown, false);
document.addEventListener("keypress", keypress, false);
document.addEventListener("keyup", keyup, false);
document.addEventListener("mousedown", mousedown, false);
document.addEventListener("mouseup", mouseup, false);
pdgui.gui_post("resetting to normal...");
this.none();
document.addEventListener("mousemove", events.mousemove, false);
document.addEventListener("keydown", events.keydown, false);
document.addEventListener("keypress", events.keypress, false);
document.addEventListener("keyup", events.keyup, false);
document.addEventListener("mousedown", events.mousedown, false);
document.addEventListener("mouseup", events.mouseup, false);
},
text: function() {
document.removeEventListener("mousemove", mousemove, false);
document.removeEventListener("keydown", keydown, false);
document.removeEventListener("keypress", keypress, false);
document.removeEventListener("keyup", keyup, false);
document.removeEventListener("mousedown", mousedown, false);
document.removeEventListener("mouseup", mouseup, false);
document.addEventListener("mousemove", text_mousemove, false);
document.addEventListener("keydown", text_keydown, false);
document.addEventListener("keypress", text_keypress, false);
document.addEventListener("keyup", text_keyup, false);
document.addEventListener("mousedown", text_mousedown, false);
document.addEventListener("mouseup", mouseup, false);
this.none();
document.addEventListener("mousemove", events.text_mousemove, false);
document.addEventListener("keydown", events.text_keydown, false);
document.addEventListener("keypress", events.text_keypress, false);
document.addEventListener("keyup", events.text_keyup, false);
document.addEventListener("mousedown", events.text_mousedown, false);
document.addEventListener("mouseup", events.text_mouseup, false);
},
floating_text: function() {
this.none();
this.text();
document.removeEventListener("mousedown", events.text_mousedown, false);
document.removeEventListener("mouseup", events.text_mouseup, false);
document.removeEventListener("mousemove", events.text_mousemove, false);
document.removeEventListener("keypress", events.text_keypress, false);
document.addEventListener("click", events.floating_text_click, false);
document.addEventListener("keypress", events.floating_text_keypress, false);
document.addEventListener("mousemove", events.mousemove, false);
},
register: function(n) {
name = n;
......
......@@ -2212,8 +2212,22 @@ function gui_text_displace(name, tag, dx, dy) {
elem_displace(get_gobj(name, tag), dx, dy);
}
function textentry_displace(t, dx, dy) {
var transform = t.style.getPropertyValue('transform')
.split('(')[1] // get everything after the '('
.replace(')', '') // remove trailing ')'
.split(','); // split into x and y
var x = +transform[0].trim().replace('px', ''),
y = +transform[1].trim().replace('px', '');
gui_post("x is " + x + " and y is " + y);
t.style.setProperty('transform',
'translate(' +
(x + dx) + 'px, ' +
(y + dy) + 'px)');
}
function gui_canvas_displace_withtag(name, dx, dy) {
var pwin = patchwin[name], i;
var pwin = patchwin[name], i, textentry;
var ol = pwin.window.document.getElementsByClassName('selected');
for (i = 0; i < ol.length; i++) {
elem_displace(ol[i], dx, dy);
......@@ -2223,6 +2237,11 @@ function gui_canvas_displace_withtag(name, dx, dy) {
// elem.matrix.e = new_tx;
// elem.matrix.f = new_ty;
}
textentry = patchwin[name].window.document.getElementById('new_object_textentry');
if (textentry !== null) {
textentry_displace(textentry, dx, dy);
}
// elem.setAttributeNS(null, 'transform',
// 'translate(' + new_tx + ',' + new_ty + ')');
// }
......@@ -3396,9 +3415,10 @@ exports.skin = (function () {
};
}());
function gui_textarea(cid, tag, x, y, font_size, state) {
function gui_textarea(cid, tag, x, y, max_char_width, font_size, state) {
gui_post("x/y is " + x + '/' + y);
if (state === 1) {
gui_post("state? " + state);
if (state !== 0) {
var p = patchwin[cid].window.document.createElement('p');
configure_item(p, {
id: 'new_object_textentry'
......@@ -3407,12 +3427,19 @@ function gui_textarea(cid, tag, x, y, font_size, state) {
p.style.setProperty('left', x + 'px');
p.style.setProperty('top', y + 'px');
p.style.setProperty('font-size', font_size + 'px');
p.textContent = "Fuck Butts";
p.style.setProperty('transform', 'translate(0px, 0px)');
p.style.setProperty('max-width',
max_char_width === 0 ? '60ch' : max_char_width + 'ch');
p.style.setProperty('min-width',
max_char_width === 0 ? '3ch' : max_char_width + 'ch');
// p.textContent = "Fuck Butts";
patchwin[cid].window.document.body.appendChild(p);
p.focus();
patchwin[cid].window.canvas_events.text();
/* here we need to make sure that events inside the
<p> don't propogate down to the svg below... */
if (state === 1) {
patchwin[cid].window.canvas_events.text();
} else {
patchwin[cid].window.canvas_events.floating_text();
}
} else {
var p = patchwin[cid].window.document.getElementById('new_object_textentry');
if (p !== null) {
......
Event settings for edit mode
----------------------------
1) No box - normal editmode behavior
* moving/selecting
* setting a bounding rect
* mouse cannot select text
* text is not editable
* clicking a box triggers #2 below
2) Editing a box in place
* x/y is set
* can type inside box
* can select text with the mouse
* mouse motion doesn't change box position
* applies to all boxes which already exist and are being edited
3) Editing a new box before it's anchored
* x/y follows mouse
* can type new text into the box
* a click in the box will anchor the box and trigger #2 above
*need to be able to tell the difference between new obj and retexted
obj
Problems to put off until all (or most) sys_vgui calls are eliminated:
1) gui-side parser inside -- pdgui.js. Currently we're splitting on newlines so we can separate
gui_vmess from sys_vgui calls. This makes it very difficult to handle multi-line msg and text
......@@ -150,6 +173,7 @@ Everything else: (A [x] means we've fixed it)
\"%.6lx\". (Not exactly sure what good the "x" does there.) It's only
specified in s_inter and in editor_new, so it should be easy to amend
if need be.
[ ] make "rtext" textarea <div> static, and turn display on/off
Crashers
--------
......@@ -509,6 +509,7 @@ EXTERN void rtext_mouse(t_rtext *x, int xval, int yval, int flag); //5
EXTERN void rtext_retext(t_rtext *x); //5
EXTERN char *rtext_gettag(t_rtext *x); //47
EXTERN void rtext_gettext(t_rtext *x, char **buf, int *bufsize); //9
EXTERN void rtext_settext(t_rtext *x, char *buf, int bufsize); //1
EXTERN void rtext_getseltext(t_rtext *x, char **buf, int *bufsize); //4
/* -------------------- functions on canvases ------------------------ */
......
......@@ -7613,6 +7613,28 @@ static void canvas_tip(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
}
}
static void canvas_stringforobj(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
{
int length;
char *buf;
t_gobj *y;
t_rtext *rtext;
if (!x->gl_editor || argc < 1) return;
for (y = x->gl_list; y; y = y->g_next)
{
if (glist_isselected(x, y) && (rtext = glist_findrtext(x, (t_text *)y)))
{
rtext_gettext(rtext, &buf, &length);
t_binbuf *b = binbuf_new();
binbuf_add(b, argc, argv);
binbuf_gettext(b, &buf, &length);
rtext_settext(rtext, buf, length);
binbuf_free(b);
glist_deselect(x, y);
}
}
}
void g_editor_setup(void)
{
/* ------------------------ events ---------------------------------- */
......@@ -7634,6 +7656,8 @@ void g_editor_setup(void)
A_GIMME, A_NULL);
class_addmethod(canvas_class, (t_method)canvas_tip, gensym("echo"),
A_GIMME, A_NULL);
class_addmethod(canvas_class, (t_method)canvas_stringforobj,
gensym("stringforobj"), A_GIMME, A_NULL);
/* ------------------------ menu actions ---------------------------- */
class_addmethod(canvas_class, (t_method)canvas_menuclose,
gensym("menuclose"), A_DEFFLOAT, 0);
......
......@@ -106,6 +106,13 @@ void rtext_gettext(t_rtext *x, char **buf, int *bufsize)
*bufsize = x->x_bufsize;
}
void rtext_settext(t_rtext *x, char *buf, int bufsize)
{
freebytes(x->x_buf, x->x_bufsize);
x->x_buf = buf;
x->x_bufsize = bufsize;
}
void rtext_getseltext(t_rtext *x, char **buf, int *bufsize)
{
*buf = x->x_buf + x->x_selstart;
......@@ -553,7 +560,7 @@ post("selected an rtext");
void rtext_activate(t_rtext *x, int state)
{
fprintf(stderr,"rtext_activate state=%d\n", state);
int w = 0, h = 0, indx;
int w = 0, h = 0, widthspec, indx;
t_glist *glist = x->x_glist;
t_canvas *canvas = glist_getcanvas(glist);
//if (state && x->x_active) printf("duplicate rtext_activate\n");
......@@ -578,14 +585,24 @@ void rtext_activate(t_rtext *x, int state)
glist->gl_editor->e_textedfor = 0;
x->x_active = 0;
}
/* so I guess the following would need to be commented out
if we want to use the textarea junk to feed to Pd... */
rtext_senditup(x, SEND_UPDATE, &w, &h, &indx);
gui_vmess("gui_textarea", "xsiiii",
/* hack...
state = 0 no editing
state = 1 editing
state = 2 editing a new object
State 2 isn't necessary, except that Pd has
traditionally had this "floating" state for
new objects where the box text also happens
to be editable
*/
widthspec = x->x_text->te_width; // width if any specified
gui_vmess("gui_textarea", "xsiiiii",
canvas,
x->x_tag,
x->x_text->te_xpix,
x->x_text->te_ypix,
widthspec,
sys_hostfontsize(glist_getfont(glist)),
state);
}
......
......@@ -226,7 +226,8 @@ static void canvas_objtext(t_glist *gl, int xpix, int ypix,
{
/* this is called if we've been created from the menu. */
glist_select(gl, &x->te_g);
gobj_activate(&x->te_g, gl, 1);
gobj_activate(&x->te_g, gl,
2); // <-- hack to signal that we're a new object
}
if (pd_class(&x->ob_pd) == vinlet_class)
canvas_resortinlets(glist_getcanvas(gl));
......@@ -357,7 +358,8 @@ void canvas_obj(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
canvas_objtext(gl,
connectme ? xpix : xpix - 8,
connectme ? ypix : ypix - 8, 0, 1, b);
connectme ? ypix : ypix - 8,
0, 1, b);
if (connectme == 1)
{
//fprintf(stderr,"canvas_obj calls canvas_connect\n");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment