Commit 3cacb1f3 authored by Ivica Bukvic's avatar Ivica Bukvic
Browse files

Introduced new activated msg border drawing approach

* Got rid of the problematic svg background which marginally worked on 0.14.7 but doesn't on 0.24.4

* Instead, using the existing msg border/background and adjusting its size dynamically

* The behavior remains identical to before (hide nlets, do not worry about readjusting patch cords)

* LATER: think about integrating patch cord and nlet adjustment to match vanilla behavior, consider further fine-tuning the text placement based on various zoom levels and fonts sizes (some still are a pixel off, this is true for also regular text objects), and finally implement this same approach for the regular text objects
parent c4495143
......@@ -455,6 +455,9 @@ var canvas_events = (function() {
},
text_keydown: function(evt) {
evt.stopPropagation();
setTimeout(function() {
pdgui.gui_message_update_textarea_border(textbox(), 0);
}, 0);
//evt.preventDefault();
return false;
},
......
......@@ -2603,6 +2603,36 @@ function message_border_points(width, height) {
.join(" ");
}
// called from pd_canvas.js text events to deal with
// the drawing of the msg box
function gui_message_update_textarea_border(elem, init_width) {
if (elem.classList.contains("msg")) {
if (init_width) {
var i, ncols = 0,
text = elem.innerHTML,
textByLine = text.split(/\r*\n/);
for (i = 0; i < textByLine.length; i++) {
if (textByLine[i].length > ncols) {
ncols = textByLine[i].length;
}
}
configure_item(elem, {
cols: ncols
});
gui_gobj_erase_io(elem.getAttribute("cid"), elem.getAttribute("tag"));
}
gui_message_redraw_border(
elem.getAttribute("cid"),
elem.getAttribute("tag"),
parseInt(elem.offsetWidth / elem.getAttribute("font_width")) * elem.getAttribute("font_width") + 4,
elem.offsetHeight-1
);
}
}
exports.gui_message_update_textarea_border = gui_message_update_textarea_border;
function gui_message_draw_border(cid, tag, width, height) {
gui(cid).get_gobj(tag)
.append(function(frag) {
......@@ -6251,82 +6281,6 @@ function get_style_by_selector(w, selector) {
// for debugging purposes
exports.get_style_by_selector = get_style_by_selector;
// Big, stupid, ugly SVG data url to shove into CSS when
// the user clicks a box in edit mode. One set of points for
// the "head", or main box, and the other for the "tail", or
// message flag at the right.
// ico@vt.edu 2020-08-31: if you thought the original hack was
// ugly, wait until you see this new version. Hold onto your
// binary barf bags...
function generate_msg_box_bg_data(type, stroke, height) {
//post("height="+height);
var header = 'url(\"data:image/svg+xml;utf8,' +
'<svg ' +
"xmlns:svg='http://www.w3.org/2000/svg' " +
"xmlns='http://www.w3.org/2000/svg' " +
"xmlns:xlink='http://www.w3.org/1999/xlink' " +
"version='1.0' " +
"viewBox='0 0 10 10' " +
"preserveAspectRatio='none'" +
">";
var line_header = "<polyline vector-effect='non-scaling-stroke' " +
"id='bubbles' " +
"fill='none' " +
"stroke=' " +
stroke + // Here's our stroke color
"' ";
var line_ender = "</svg>" +
'")';
if (type === "head")
{
return header + line_header + "stroke-width='2' points='10 0 0 0 0 10 10 10' />" + line_ender;
}
else {
// testing scaling of the flags with the increasing number of lines, top_flag, then bottom_flag
// 1 line: 2.5 7.5
// 2 lines: 1.5 8.5
// 3 lines: 1 9
// 4 lines: 0.75 9.25
var top_flag = 2.5;
var decrement = 1;
while(height > 1)
{
top_flag -= decrement;
decrement /= 2;
height--;
}
var bottom_flag = 10 - top_flag;
return header +
line_header + "stroke-width='2' points='0 0 10 0' />" +
line_header + "stroke-width='2' points='0 10 10 10' />" +
line_header + "stroke-width='1' points='10 0 1 " + top_flag + " 1 " + bottom_flag + " 10 10' />" +
line_ender;
}
}
// Big problem here-- CSS fails miserably at something as simple as the
// message box flag. We use a backgroundImage svg to address this, but
// for security reasons HTML5 doesn't provide access to svg image styles.
// As a workaround we just seek out the relevant CSS rules and shove the
// whole svg data url into them. We do this each time the user
// clicks a box to edit.
// Also, notice that both CSS and SVG _still_ fail miserably at drawing a
// message box flag that expands in the middle while retaining the same angles
// at the edges. As the message spans more and more lines the ugliness becomes
// more and more apparent.
// Anyhow, this enormous workaround makes it possible to just specify the
// edit box color in CSS for the presets.
function shove_svg_background_data_into_css(w, height) {
var head_style = get_style_by_selector(w, "#new_object_textentry.msg"),
tail_style = get_style_by_selector(w, "p.msg::after"),
stroke = head_style.outlineColor;
head_style.backgroundImage = generate_msg_box_bg_data("head", stroke, height);
tail_style.backgroundImage = generate_msg_box_bg_data("tail", stroke, height);
}
function textarea_line_height_kludge(font_size) {
switch(font_size) {
case 8: return "133%";
......@@ -6363,7 +6317,7 @@ function textarea_msg_kludge(zoom) {
}
function gui_textarea(cid, tag, type, x, y, width_spec, height_spec, text,
font_size, is_gop, state, sel_start, sel_end) {
font_size, font_width, is_gop, state, sel_start, sel_end) {
var range, svg_view, p,
gobj = get_gobj(cid, tag), zoom;
gui(cid).get_nw_window(function(nw_win) {
......@@ -6382,10 +6336,33 @@ function gui_textarea(cid, tag, type, x, y, width_spec, height_spec, text,
// (We can probably solve this problem by throwing in yet another
// gui_canvas_get_scroll, but this seems like the right way to go
// anyway.)
configure_item(gobj, { visibility: "hidden" });
// Hide elements:
// all text objects except for the message box hide everything,
// while the message box has a new approach that retains the svg
// shape below it. LATER: we may want to:
// 1) extend this to support nlets (currently we hide them);
// 2) extend this to adjust patch cords as things are being edited, and
// 3) extend this to all text objects.
if (type === "msg") {
// Message approach
var i, nlets = patchwin[cid].window.document
.getElementById(tag+"gobj").querySelectorAll(".xlet_control");
for (i = 0; i < nlets.length; i++) {
nlets[i].style.setProperty("visibility", "hidden");
}
gui(cid).get_gobj(tag).q(".box_text", { visibility: "hidden" });
} else {
// Anything else but message
configure_item(gobj, { visibility: "hidden" });
}
p = patchwin[cid].window.document.createElement("p");
configure_item(p, {
id: "new_object_textentry"
id: "new_object_textentry",
cid: cid,
tag: tag,
font_width: font_width
});
svg_view = patchwin[cid].window.document.getElementById("patchsvg")
.viewBox.baseVal;
......@@ -6431,24 +6408,29 @@ function gui_textarea(cid, tag, type, x, y, width_spec, height_spec, text,
if (is_gop == 1) {
p.style.setProperty("min-height", height_spec - 4 + "px");
}
// set backgroundimage for message box
if (type === "msg") {
// ico@vt.edu: 2020-08-31: message boxes are uniquely borked
// so, we do our best to address that here
// remove leading/trailing whitespace
text = text.trim();
p.textContent = text;
// append to doc body
patchwin[cid].window.document.body.appendChild(p);
if (type === "msg")
{
// ico@vt.edu 2020-09-30: New approach to drawing
// messages that utilizes the original svg border
p.style.setProperty("-webkit-padding-before", "2px");
p.style.setProperty("-webkit-padding-after", "3px");
p.style.setProperty("-webkit-padding-start", "0px");
p.style.setProperty("-webkit-padding-end", "0px");
p.style.setProperty("margin-left", "2.5px");
p.style.setProperty("transform", "translate(0px, " +
textarea_msg_kludge(zoom) + "px)");
p.style.setProperty("background-color", "");
//post("line-height="+ parseInt(p.style.lineHeight) / 100 * font_size);
shove_svg_background_data_into_css(patchwin[cid].window,
parseInt(get_gobj(cid, tag).getBoundingClientRect().height /
(parseInt(p.style.lineHeight) / 100 * font_size)));
//shove_svg_background_data_into_css(patchwin[cid].window,
// parseInt(get_gobj(cid, tag).getBoundingClientRect().height /
// (parseInt(p.style.lineHeight) / 100 * font_size)));
gui_message_update_textarea_border(p,1);
}
// remove leading/trailing whitespace
text = text.trim();
p.textContent = text;
// append to doc body
patchwin[cid].window.document.body.appendChild(p);
p.focus();
select_text(cid, p, sel_start, sel_end);
if (font_size === 36) {
......@@ -6469,6 +6451,15 @@ function gui_textarea(cid, tag, type, x, y, width_spec, height_spec, text,
if (p !== null) {
p.parentNode.removeChild(p);
}
// MSG approach
var i, nlets = patchwin[cid].window.document
.getElementById(tag+"gobj").querySelectorAll(".xlet_control");
for (i = 0; i < nlets.length; i++) {
nlets[i].style.setProperty("visibility", "visible");
}
gui(cid).get_gobj(tag).q(".box_text", { visibility: "visible" });
if (patchwin[cid].window.canvas_events.get_previous_state() ===
"search") {
patchwin[cid].window.canvas_events.search();
......
......@@ -6597,7 +6597,7 @@ static void canvas_cut(t_canvas *x)
if (!bufsize)
return;
canvas_copy(x);
rtext_key(x->gl_editor->e_textedfor, 127, &s_);
//rtext_key(x->gl_editor->e_textedfor, 127, &s_);
canvas_fixlinesfor(x,(t_text*) x->gl_editor->e_selection->sel_what);
canvas_dirty(x, 1);
}
......
......@@ -642,7 +642,7 @@ void rtext_activate(t_rtext *x, int state)
sprintf(tmpbuf, "%.*s", (int)x->x_bufsize, x->x_buf);
/* in case x_bufsize is 0... */
tmpbuf[x->x_bufsize] = '\0';
gui_vmess("gui_textarea", "xssiiiisiiiii",
gui_vmess("gui_textarea", "xssiiiisiiiiii",
canvas,
x->x_tag,
(pd_class((t_pd *)x->x_text) == message_class ? "msg" : "obj"),
......@@ -652,6 +652,7 @@ void rtext_activate(t_rtext *x, int state)
heightspec,
tmpbuf,
sys_hostfontsize(glist_getfont(glist)),
sys_fontwidth(glist_getfont(glist)),
isgop,
state,
selstart,
......
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