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

Merge branch 'aggraef/purr-data-release_2.15.0'

parents c4495143 daf883f9
Pipeline #2948 failed with stage
in 209 minutes and 13 seconds
<!DOCTYPE html>
<html>
<head>
<link id="page_style" rel="stylesheet" type="text/css" href="css/default.css">
</head>
<body class="dialog_body prefs_body" style="overflow: hidden;">
<div class="container noselect prefs_container">
<table id="titlebar">
<tr>
<td style="width: 100%;">
<div id="titlebar_title">Abstractions</div>
</td>
<td id="titlebar_buttons_td">
<div class="titlebar_buttons">
<div id="titlebar_close_button" onclick="cancel();">&#215</div>
</div>
</td>
</tr>
</table>
<form>
<fieldset style="width: 90%">
<legend data-i18n="abstractions.private"></legend>
<strong data-i18n="abstractions.global"></strong>
<hr>
<table style="width: 90%; table-layout: fixed;">
</table>
<br>
<strong data-i18n="abstractions.local"></strong>
<hr>
<table style="width: 90%; table-layout: fixed;">
</table>
<br>
<button id="selectall_button" type="button" onClick="selectall()" data-i18n="[title]abstractions.selectall_tt" style="float: right;">
<span data-i18n="abstractions.selectall"></span>
</button>
</fieldset>
<!--
<hr>
<fieldset style="width: 90%; border: 2px solid grey">
<legend data-i18n="abstractions.filebased"></legend>
<i>NOT IMPLEMENTED</i>
<table style="width: 90%; table-layout: fixed;">
</table>
</fieldset>
<hr>
-->
<div class="submit_buttons">
<button id="delete_button" type="button" onClick="deleteselected()" data-i18n="[title]abstractions.delete_tt">
<span data-i18n="abstractions.delete"></span>
</button>
<button type="button" onClick="cancel()" data-i18n="[title]abstractions.close_tt">
<span data-i18n="abstractions.close"></span>
</button>
</div>
</form>
</div>
<script>
"use strict";
var gui = require("nw.gui");
var pdgui = require("./pdgui.js");
// For translations
var l = pdgui.get_local_string;
pdgui.skin.apply(window);
var pd_object_callback;
var canvas;
var deletequeue;
function selectall() {
var checkboxes = document.querySelectorAll('input[type="checkbox"]:not(:checked)');
for(var i = 0, n = checkboxes.length; i < n; i++) {
if(!checkboxes[i].checked)
{
checkboxes[i].click();
}
}
}
function deleteselected() {
pdgui.pdsend(pd_object_callback, "delabstractions", Array.from(deletequeue).join(" "));
cancel();
}
function cancel() {
pdgui.pdsend(pd_object_callback, "cancel");
}
function populate_form(attrs) {
var filebased_abs = attrs.filebased_abs,
private_abs = attrs.private_abs,
i,
zero = 0;
canvas = attrs.canvas;
deletequeue = new Set();
var tables = document.querySelectorAll("table"),
privateglobal_table = tables[1],
privatelocal_table = tables[2];
//filebased_table = tables[2]
/*
for(i = 0; i < filebased_abs.length; i += 2)
{
var row = document.createElement("tr");
cell1 = document.createElement("td"),
cell2 = document.createElement("td"),
cell3 = document.createElement("td");
cell1.textContent = filebased_abs[i];
cell1.style.setProperty("width", "70%");
cell2.textContent = filebased_abs[i+1];
cell2.style.setProperty("width", "20%");
row.appendChild(cell1);
row.appendChild(cell2);
row.appendChild(cell3);
filebased_table.appendChild(row);
}
*/
for(i = 0; i < private_abs.length; i += 2)
{
var row = document.createElement("tr"),
cell1 = document.createElement("td"),
cell2 = document.createElement("td"),
cell3 = document.createElement("td");
cell1.textContent = private_abs[i];
cell1.style.setProperty("width", "70%");
cell2.textContent = private_abs[i+1];
cell2.style.setProperty("width", "20%");
if(private_abs[i+1] === 0)
{
let input_elem = document.createElement("input"),
j = i;
input_elem.type = "checkbox";
input_elem.style.setProperty("max-height", "10px");
input_elem.style.setProperty("top", "0px");
input_elem.onchange = function() {
if(input_elem.checked) {
deletequeue.add(private_abs[j]);
} else {
deletequeue.delete(private_abs[j]);
}
get_elem("delete_button").disabled = (deletequeue.size === 0);
};
cell3.appendChild(input_elem);
zero++;
}
row.appendChild(cell1);
row.appendChild(cell2);
row.appendChild(cell3);
if(private_abs[i][0] === '@') {
privatelocal_table.appendChild(row);
} else {
privateglobal_table.appendChild(row);
}
}
get_elem("selectall_button").disabled = (zero === 0);
get_elem("delete_button").disabled = true;
}
// This gets called from the nw_create_window function in index.html
// It provides us with our window id from the C side. Once we have it
// we can create the menu and register event callbacks
function register_window_id(gfxstub, attrs) {
pd_object_callback = gfxstub;
add_events(gfxstub);
// not sure that we need this for properties windows
//pdgui.canvas_map(gfxstub);
translate_form();
populate_form(attrs);
// We don't turn on rendering of the "container" div until
// We've finished displaying all the spans and populating the
// labels and form elements. That makes it more efficient and
// snappier, at least on older machines.
document.getElementsByClassName("container")[0].style.setProperty("display", "inline");
gui.Window.get().setResizable(false);
}
function get_elem(name) {
return document.getElementById(name);
}
// Stop-gap translator
function translate_form() {
var elements = document.querySelectorAll("[data-i18n]"),
data,
i;
for (i = 0; i < elements.length; i++) {
data = elements[i].dataset.i18n;
if (data.slice(0, 7) === "[title]") {
elements[i].title = l(data.slice(7));
} else {
elements[i].textContent = l(data);
}
}
}
function add_events(name) {
gui.Window.get().on("close", function () {
cancel();
});
pdgui.dialog_bindings(name);
}
</script>
</body>
</html>
......@@ -149,7 +149,8 @@ function parse_attrs(attrs) {
if (token.length > 1) {
elem.type = token[token.length - 1];
if (elem.type !== "symbol" &&
elem.type !== "toggle") {
elem.type !== "toggle" &&
elem.type !== "hidden") {
// no suffix defaults to "number"
elem.type = "number";
} else {
......@@ -218,6 +219,7 @@ function get_input_type(t) {
return t === "symbol" ? "text" :
t === "number" ? "text" :
t === "toggle" ? "checkbox":
t === "hidden" ? "hidden":
"text";
}
......
......@@ -291,6 +291,27 @@
<fieldset>
<legend data-i18n="iem.prop.heading.colors"></legend>
<table class="draw_style prop hidden" style="margin-bottom: 7px;">
<tr>
<td>
<label data-i18n="[title]iem.prop.drawstyle_tt">
<span data-i18n="iem.prop.drawstyle"
style="margin-right: 6px;"></span>
</label>
</td>
<td data-i18n="[title]iem.prop.drawstyle_tt">
<select name="draw_style"
onchange="update_attr(this, true);"
style="width: 14em;">
<option value="0">draw everything (default)</option>
<option value="1">draw frame only</option>
<option value="2">draw triangle only</option>
<option value="3">draw number only</option>
</select>
</td>
<td>
</table>
<div class="background_color prop hidden">
<label data-i18n="[title]iem.prop.bgcolor_tt">
<input type="color" name="background_color"
......@@ -512,6 +533,8 @@ function send_params(attrs, create_undo_point) {
var slot18 = attrs.steady_on_click ? +attrs.steady_on_click : 0;
var draw_style = attrs.draw_style ? +attrs.draw_style : 0;
pdgui.pdsend(pd_object_callback, "dialog",
width, height,
slot3, // bng: flash_interrupt
......@@ -532,7 +555,7 @@ function send_params(attrs, create_undo_point) {
background_color, foreground_color,
label_color,
slot18, // steady on click
0, // not sure what this is doing here
draw_style, // numbox draw style
create_undo_point ? 1 : 0 // whether we set an undo point
);
}
......
......@@ -5,7 +5,7 @@
"size": "Größe und Verhalten",
"messages": "Nachrichten",
"label": "Etikett",
"colors": "Farben"
"colors": "Erscheinungsbild"
},
"size_tt": "Größe des iemgui-Elements",
"size": "Größe",
......@@ -41,6 +41,8 @@
"log_height_tt": "the framus intersects with the ramistan approximately at the podernoster",
"steady": "stabil beim Klicken",
"steady_tt": "verschiebe den Schieberegler nicht beim Klicken. Verschiebe ihn nur beim Ziehen der Maus",
"drawstyle": "Rahmen-Stil",
"drawstyle_tt": "Rahmen-Stil durch Auswahl der Elemente anpassen",
"send": "Sende-Symbol",
"send_tt": "Symbol zum Senden drahtloser Nachrichten an andere iemgui-Elemente oder Objekte",
"receive": "Empfangs-Symbol",
......@@ -237,6 +239,8 @@
"visible_ancestor_tt": "Zeige den nächsten aktuell sichtbaren Vorgänger des aktuellen Fensters",
"pdwin": "Pd-Fenster",
"pdwin_tt": "Zeige das Pd-Hauptfenster",
"abstractions": "Abstraktionen",
"abstractions_tt": "Abstraktionen abfragen und verwalten",
"media": "Medien",
......@@ -504,5 +508,17 @@
"building_index": "Erstelle Index...",
"no_results": "Keine Resultate gefunden.",
"search_placeholder": "Suche Pd-Doku"
},
"abstractions": {
"filebased": "Datei-basierte Abstraktionen",
"private": "Private Abstraktionen",
"global": "Globaler Geltungsbereich",
"local": "Lokaler Geltungsbereich",
"selectall": "Alles auswählen",
"selectall_tt": "Wähle alle uninstanziierten Definitionen aus",
"delete": "Löschen",
"delete_tt": "Löscht alle ausgewählten Definitionen",
"close": "Schließen",
"close_tt": "Schließt das Dialog-Fenster"
}
}
......@@ -5,7 +5,7 @@
"size": "size and behavior",
"messages": "messaging",
"label": "label",
"colors": "colors"
"colors": "appearance"
},
"size_tt": "size of the iemgui",
"size": "size",
......@@ -41,6 +41,8 @@
"log_height_tt": "the framus intersects with the ramistan approximately at the podernoster",
"steady": "steady on click",
"steady_tt": "don't move the slider when clicked. Only move it when dragging the mouse",
"drawstyle": "frame style",
"drawstyle_tt": "adjust number frame style by toggling its elements",
"send": "send symbol",
"send_tt": "symbol to send wireless messages to other iemguis or objects",
"receive": "receive symbol",
......@@ -237,6 +239,8 @@
"visible_ancestor_tt": "give focus to the closest ancestor of this window that is currently visible",
"pdwin": "Pd Window",
"pdwin_tt": "Give focus to the main Pd window",
"abstractions": "Abstractions",
"abstractions_tt": "Query and manage abstractions",
"media": "Media",
......@@ -504,5 +508,17 @@
"building_index": "Building index...",
"no_results": "No results found.",
"search_placeholder": "Search Pd Docs"
},
"abstractions": {
"filebased": "File-based abstractions",
"private": "Private abstractions",
"global": "Global scope",
"local": "Local scope",
"selectall": "Select all",
"selectall_tt": "Select all definitions with zero instances",
"delete": "Delete",
"delete_tt": "Delete all selected definitions",
"close": "Close",
"close_tt": "Close the dialog window"
}
}
......@@ -5,7 +5,7 @@
"size": "Taille et comportement",
"messages": "Messages",
"label": "Label",
"colors": "Couleurs"
"colors": "Apparence"
},
"size": "Taille",
"size_tt": "Taille de l'objet IemGui",
......@@ -41,6 +41,8 @@
"log_height_tt": "Le framus se croise avec le ramistan approximativement au paternoster !",
"steady": "Fixe au clic",
"steady_tt": "Ne bouge pas le curseur quand cliqué. Bouge seulement quand on le fait glisser avec la souris",
"drawstyle": "Style du cadre",
"drawstyle_tt": "Ajuster le style du cadre en choisissant ses éléments",
"send": "Envoyer au symbole",
"send_tt": "Messages sans-fil à envoyer à travers le Symbole vers d'autres IemGui ou Objets",
"receive": "Recevoir du symbole",
......@@ -237,6 +239,8 @@
"visible_ancestor_tt": "Donner le focus à l'ancêtre le plus proche de cette fenêtre qui est actuellement visible",
"pdwin": "Fenêtre Console Pd",
"pdwin_tt": "Donner le focus à la fenêtre principale de Pd",
"abstractions": "Abstractions",
"abstractions_tt": "Interroger et gérer les abstractions",
"media": "Média",
......@@ -279,7 +283,7 @@
"canvas": {
"paste_clipboard_prompt": "Attention: vous êtes sur le point de coller du 'code Pd' provenant de l'extérieur de Pd. Voulez-vous continuer ?",
"save_dialog": {
"prompt": "Voulez-vous enregistrer les modifications apportées à ce patch ?",
"prompt": "Voulez-vous enregistrer les modifications apportées à",
"yes": "Oui",
"yes_tt": "Enregistrer les modifications dans le fichier avant de fermer le patch ?",
"no": "Non",
......@@ -504,5 +508,17 @@
"building_index": "Construction de l'index...",
"no_results": "Aucun résultat trouvé !",
"search_placeholder": "Chercher dans les Docs Pd"
},
"abstractions": {
"filebased": "Abstractions basées sur des fichiers",
"private": "Abstractions privées",
"global": "Portée globale",
"local": "Portée locale",
"selectall": "Tout sélectionner",
"selectall_tt": "Sélectionner toutes les définitions avec zéro instance",
"delete": "Supprimer",
"delete_tt": "Supprimer toutes les définitions sélectionnées",
"close": "Fermer",
"close_tt": "Fermer la fenêtre de dialogue"
}
}
......@@ -99,6 +99,22 @@ var canvas_events = (function() {
return 0;
}
},
target_is_canvasobj = function(evt) {
function is_canvas_obj(target) {
return target.classList.contains("obj") &&
target.classList.contains("canvasobj");
};
// ag: A bit of (maybe over-)defensive programming here: depending
// on where exactly the user clicked, the actual object may be the
// parent or the grandparent of the clicked target.
if (evt.target.classList.contains("border") ||
evt.target.classList.contains("box_text"))
return is_canvas_obj(evt.target.parentNode);
else if (evt.target.parentNode.classList.contains("box_text"))
return is_canvas_obj(evt.target.parentNode.parentNode);
else
return is_canvas_obj(evt.target);
},
text_to_normalized_svg_path = function(text) {
text = text.slice(4).trim() // draw
.slice(4).trim() // path
......@@ -383,6 +399,11 @@ var canvas_events = (function() {
(pointer_y + svg_view.y),
b, mod
);
// If Alt is pressed on a box_text, fake a keyup to prevent
// dangling temp runmode in case the click opens a subpatch.
if (evt.altKey && target_is_canvasobj(evt)) {
pdgui.canvas_sendkey(name, 0, evt, "Alt", 0);
}
//evt.stopPropagation();
//evt.preventDefault();
},
......@@ -2008,6 +2029,12 @@ function nw_create_patch_window_menus(gui, w, name) {
pdgui.raise_pd_window();
}
});
minit(m.win.abstractions, {
enabled: true,
click: function () {
pdgui.pdsend(name, "getabstractions");
}
});
// Media menu
minit(m.media.audio_on, {
......
......@@ -579,6 +579,11 @@ function create_menu(gui, type) {
key: shortcuts.menu.pdwin.key,
modifiers: shortcuts.menu.pdwin.modifiers
}));
winman_menu.append(new gui.MenuItem({ type: "separator" }));
winman_menu.append(m.win.abstractions = new gui.MenuItem({
label: l("menu.abstractions"),
tooltip: l("menu.abstractions_tt")
}));
}
// Media menu
......
......@@ -2473,7 +2473,7 @@ exports.gui = gui;
// In the future, it might make sense to combine the scalar and object
// creation, in which case a flag to toggle the offset would be appropriate.
function gui_gobj_new(cid, tag, type, xpos, ypos, is_toplevel) {
function gui_gobj_new(cid, tag, type, xpos, ypos, is_toplevel, is_canvas_obj) {
var g;
xpos += 0.5,
ypos += 0.5,
......@@ -2482,7 +2482,7 @@ function gui_gobj_new(cid, tag, type, xpos, ypos, is_toplevel) {
g = create_item(cid, "g", {
id: tag + "gobj",
transform: transform_string,
class: type + (is_toplevel !== 0 ? "" : " gop")
class: type + (is_toplevel !== 0 ? "" : " gop") + (is_canvas_obj === 0 ? "" : " canvasobj")
});
add_gobj_to_svg(svg_elem, g);
});
......@@ -2964,7 +2964,7 @@ function gui_text_set (cid, tag, text) {
function gui_text_set_mynumbox (cid, tag, text, active) {
gui(cid).get_elem(tag + "text", function(e) {
//post("guit_text_set_activate " + tag + " " + text + " " + active);
//post("gui_text_set_mynumbox " + tag + " " + text + " " + active);
text = text.trim();
e.textContent = "";
text_to_tspans(cid, e, text);
......@@ -3272,13 +3272,18 @@ function gui_toggle_update(cid, tag, state, color) {
})
}
function numbox_data_string(w, h) {
function numbox_data_string_frame(w, h) {
return ["M", 0, 0,
"L", w - 4, 0,
w, 4,
w, h,
0, h,
"z",
"z"]
.join(" ");
}
function numbox_data_string_triangle(w, h) {
return ["M", 0, 0,
"L", 0, 0,
(h / 2)|0, (h / 2)|0, // |0 to force int
0, h]
......@@ -3286,27 +3291,38 @@ function numbox_data_string(w, h) {
}
// Todo: send fewer parameters from c
function gui_numbox_new(cid, tag, color, x, y, w, h, is_toplevel) {
function gui_numbox_new(cid, tag, color, x, y, w, h, drawstyle, is_toplevel) {
// numbox doesn't have a standard iemgui border,
// so we must create its gobj manually
gui(cid).get_elem("patchsvg", function() {
var g = gui_gobj_new(cid, tag, "iemgui", x, y, is_toplevel);
var data = numbox_data_string(w, h);
var border = create_item(cid, "path", {
d: data,
d: numbox_data_string_frame(w, h),
fill: color,
stroke: "black",
"stroke-width": 1,
"stroke-width": (drawstyle < 2 ? 1 : 0),
id: (tag + "border"),
"class": "border"
});
g.appendChild(border);
var triangle = create_item(cid, "path", {
d: numbox_data_string_triangle(w, h),
fill: color,
stroke: "black",
"stroke-width": (drawstyle == 0 || drawstyle == 2 ? 1 : 0),
id: (tag + "triangle"),
"class": "border"
});
g.appendChild(triangle);
});
}
function gui_numbox_coords(cid, tag, w, h) {
gui(cid).get_elem(tag + "border", {
d: numbox_data_string(w, h)
d: numbox_data_string_frame(w, h)
});
gui(cid).get_elem(tag + "triangle", {
d: numbox_data_string_triangle(w, h)
});
}
......@@ -3332,14 +3348,14 @@ function gui_numbox_draw_text(cid,tag,text,font_size,color,xpos,ypos,basex,basey
});
}
function gui_numbox_update(cid, tag, fcolor, bgcolor, font_name, font_size, font_weight) {
function gui_numbox_update(cid, tag, fcolor, bgcolor, num_font_size, font_name, font_size, font_weight) {
gui(cid)
.get_elem(tag + "border", {
fill: bgcolor
})
.get_elem(tag + "text", {
fill: fcolor,
"font-size": font_size
"font-size": num_font_size
})
// label may or may not exist, but that's covered by the API
.get_elem(tag + "label", function() {
......@@ -5668,6 +5684,9 @@ function file_dialog(cid, type, target, start_path) {
// it just doesn't work. So this requires us to have the parent <span>
// around the <input>. Then when we change the innerHTML of the span the
// new value for nwworkingdir magically works.
if(nw_os_is_windows) {
start_path = start_path.replace(/\//g, '\\');
}
dialog_options = {
style: "display: none;",
type: "file",
......@@ -5847,12 +5866,7 @@ function gui_iemgui_dialog(did, attr_array) {
// We are subtracting 25 for the menu