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

fix bugs with grid, add a rudimentary external dialog interface for it and other externals

parent b3525582
......@@ -99,7 +99,8 @@ static void grid_draw_update(t_grid *x, t_glist *glist)
// }
}
static void grid_draw_new(t_grid *x, t_glist *glist)
static void grid_draw_select(t_grid* x, t_glist* glist);
static void grid_draw_configure(t_grid *x, t_glist *glist)
{
t_canvas *canvas=glist_getcanvas(glist);
//GRID_SYS_VGUI8(".x%lx.c create rectangle %d %d %d %d "
......@@ -148,14 +149,7 @@ static void grid_draw_new(t_grid *x, t_glist *glist)
//}
// gui_gobj_new, "xx type text_xpix text_ypix istoplevel"
gui_vmess("gui_gobj_new", "xxsiii",
canvas,
x,
"obj",
text_xpix(&x->x_obj, glist),
text_ypix(&x->x_obj, glist),
glist_istoplevel(glist));
gui_vmess("gui_grid_draw_bg", "xxiisiii",
gui_vmess("gui_configure_grid", "xxiisiii",
canvas,
x,
x->x_width,
......@@ -164,9 +158,23 @@ static void grid_draw_new(t_grid *x, t_glist *glist)
x->x_grid,
x->x_xlines,
x->x_ylines);
if (glist_isselected(glist, &x->x_obj))
grid_draw_select(x, glist);
canvas_fixlinesfor( canvas, (t_text*)x );
}
static void grid_draw_new(t_grid *x, t_glist *glist)
{
t_canvas *canvas=glist_getcanvas(glist);
gui_vmess("gui_grid_new", "xxiii",
canvas,
x,
text_xpix(&x->x_obj, glist),
text_ypix(&x->x_obj, glist),
glist_istoplevel(glist));
grid_draw_configure(x, glist);
}
static void grid_draw_move(t_grid *x, t_glist *glist)
{
t_canvas *canvas=glist_getcanvas(glist);
......@@ -323,14 +331,36 @@ static void grid_save(t_gobj *z, t_binbuf *b)
static void grid_properties(t_gobj *z, t_glist *owner)
{
char buf[800];
char *gfx_tag;
t_grid *x=(t_grid *)z;
sprintf(buf, "pdtk_grid_dialog %%s %s %d %.2f %.2f %d %.2f %.2f %d %.2f %.2f %d %d\n",
x->x_name->s_name, x->x_width, x->x_min, x->x_max, x->x_height,
x->y_min, x->y_max, x->x_grid, x->x_xstep, x->x_ystep,
x->x_xlines, x->x_ylines );
//sprintf(buf, "pdtk_grid_dialog %%s %s %d %.2f %.2f %d %.2f %.2f %d %.2f %.2f %d %d\n",
// x->x_name->s_name, x->x_width, x->x_min, x->x_max, x->x_height,
// x->y_min, x->y_max, x->x_grid, x->x_xstep, x->x_ystep,
// x->x_xlines, x->x_ylines );
// post("grid_properties : %s", buf );
gfxstub_new(&x->x_obj.ob_pd, x, buf);
//gfxstub_new(&x->x_obj.ob_pd, x, buf);
gfx_tag = gfxstub_new2(&x->x_obj.ob_pd, x);
gui_start_vmess("gui_external_dialog", "ss", gfx_tag, "grid");
gui_start_array();
gui_s("receive_symbol"); gui_s(x->x_name->s_name);
gui_s("width"); gui_i(x->x_width);
gui_s("min"); gui_f(x->x_min);
gui_s("max"); gui_f(x->x_max);
gui_s("height"); gui_i(x->x_height);
gui_s("y-min"); gui_f(x->y_min);
gui_s("y-max"); gui_f(x->y_max);
gui_s("grid_toggle"); gui_i(x->x_grid);
gui_s("x-steps"); gui_f(x->x_xstep);
gui_s("y-steps"); gui_f(x->x_ystep);
gui_s("x-lines"); gui_i(x->x_xlines);
gui_s("y-lines"); gui_i(x->x_ylines);
gui_end_array();
gui_end_vmess();
}
static void grid_select(t_gobj *z, t_glist *glist, int selected)
......@@ -390,8 +420,9 @@ static void grid_dialog(t_grid *x, t_symbol *s, int argc, t_atom *argv)
x->x_ystep = argv[9].a_w.w_float;
x->x_xlines = argv[10].a_w.w_float;
x->x_ylines = argv[11].a_w.w_float;
grid_draw_erase(x, x->x_glist);
grid_draw_new(x, x->x_glist);
//grid_draw_erase(x, x->x_glist);
//grid_draw_new(x, x->x_glist);
grid_draw_configure(x, x->x_glist);
}
static void grid_delete(t_gobj *z, t_glist *glist)
......@@ -418,6 +449,26 @@ static void grid_displace(t_gobj *z, t_glist *glist, int dx, int dy)
}
}
static void grid_displace_wtag(t_gobj *z, t_glist *glist, int dx, int dy)
{
t_grid *x = (t_grid *)z;
int xold = text_xpix(&x->x_obj, glist);
int yold = text_ypix(&x->x_obj, glist);
// post( "grid_displace dx=%d dy=%d", dx, dy );
x->x_obj.te_xpix += dx;
x->x_current += dx;
x->x_obj.te_ypix += dy;
x->y_current += dy;
if (xold != text_xpix(&x->x_obj, glist) || yold != text_ypix(&x->x_obj, glist))
{
//grid_draw_move(x, x->x_glist);
canvas_fixlinesfor(glist, (t_text *)z);
}
}
static void grid_motion(t_grid *x, t_floatarg dx, t_floatarg dy)
{
int xold = x->x_current;
......@@ -508,8 +559,9 @@ static void grid_new_color(t_grid *x, t_floatarg color1,
sprintf(col3,"%X",(int) color3);
sprintf( x->x_bgcolor, "#%s%s%s", col1, col2, col3);
grid_draw_erase(x, x->x_glist);
grid_draw_new(x, x->x_glist);
//grid_draw_erase(x, x->x_glist);
//grid_draw_new(x, x->x_glist);
grid_draw_configure(x, x->x_glist);
}
static void grid_values(t_grid* x, t_floatarg xvalue, t_floatarg yvalue)
......@@ -724,6 +776,7 @@ static t_grid *grid_new(t_symbol *s, int argc, t_atom *argv)
static void grid_free(t_grid *x)
{
pd_unbind(&x->x_obj.ob_pd, x->x_name);
gfxstub_deleteforkey(x);
}
void grid_setup(void)
......@@ -759,6 +812,7 @@ void grid_setup(void)
grid_widgetbehavior.w_deletefn = grid_delete;
grid_widgetbehavior.w_visfn = grid_vis;
grid_widgetbehavior.w_clickfn = grid_click;
grid_widgetbehavior.w_displacefnwtag = grid_displace_wtag;
#if PD_MINOR_VERSION >= 37
class_setpropertiesfn(grid_class, grid_properties);
......
<!DOCTYPE html>
<html>
<head>
<link id="page_style" rel="stylesheet" type="text/css" href="css/default.css">
</head>
<body class="dialog_body">
<div class="container">
<form>
<fieldset>
<legend></legend>
</fieldset>
<div class="submit_buttons">
<button type="button"
onClick="ok();"
id="ok_button"
data-i18n="[title]iem.prop.ok_tt">
<span data-i18n="iem.prop.ok"></span>
</button>
<button type="button"
onClick="apply();"
id="apply_button"
data-i18n="[title]iem.prop.apply_tt">
<span data-i18n="iem.prop.apply"></span>
</button>
<button type="button"
onClick="cancel(true);"
data-i18n="[title]iem.prop.cancel_tt">
<span data-i18n="iem.prop.cancel"></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 old_properties; // Original values in case the user wants to cancel changes
var new_properties; // Updated values
// Grab focus for one of the buttons
function focus_button(id) {
document.getElementById(id).focus();
}
function send_props_to_pd(attr_array) {
var values = [];
// Todo: parse symbols the same way we do for iemguis before
// sending them back to Pd. This might require some fanagling on
// the pd side of things...
attr_array.forEach(function(elem) {
values.push(elem.value);
});
pdgui.pdsend(pd_object_callback, "dialog", values.join(" "));
}
function apply() {
focus_button("apply_button");
send_props_to_pd(new_properties);
}
function cancel() {
send_props_to_pd(old_properties);
pdgui.pdsend(pd_object_callback, "cancel");
}
function ok() {
// Focus button so that the "change" event triggers
// for the form before sending values to Pd
focus_button("ok_button");
send_props_to_pd(new_properties);
pdgui.pdsend(pd_object_callback, "cancel");
}
// turn a ["name", value, etc.] array
// into an array of objects where each object contains
// name: name for the input element
// type: type of element (number, string, toggle)
// label: string label (basically the name with underscores turned to spaces)
// value: a value for the input
function parse_attrs(attrs) {
var ret = [],
elem;
attrs.forEach(function(token, i) {
if (i % 2 === 0) {
elem = {};
token = token.split("_");
if (token.length > 1) {
elem.type = token[token.length - 1];
if (elem.type !== "symbol" &&
elem.type !== "toggle") {
// no suffix defaults to "number"
elem.type = "number";
} else {
// remove the type suffix
token = token.slice(0, -1);
}
} else {
elem.type = "number";
}
elem.name = token.join("_");
elem.label = token.join(" ");
} else {
elem.value = token;
// now push the object onto the array
ret.push(elem);
}
});
return ret;
}
// 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, args) {
var external_name = args.name,
array_of_objects;
pd_object_callback = gfxstub;
array_of_objects = parse_attrs(args.attributes);
// Store our array for later use
new_properties = array_of_objects;
// Also make a copy in the case that the user cancels this dialog
old_properties = JSON.parse(JSON.stringify(array_of_objects));
add_events(gfxstub);
// not sure that we need this for properties windows
//pdgui.canvas_map(gfxstub);
translate_form();
build_form(external_name, array_of_objects);
// 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");
}
// 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 get_input_type(t) {
return t === "symbol" ? "text" :
t === "number" ? "text" :
t === "toggle" ? "checkbox":
"text";
}
function build_form(external_name, array_of_objects) {
var fieldset = document.querySelector("fieldset");
document.querySelector("legend").textContent = external_name;
array_of_objects.forEach(function(elem) {
var input_elem = document.createElement("input"),
label = document.createElement("label");
input_elem.type = get_input_type(elem.type);
if (input_elem.type === "checkbox") {
input_elem.checked = elem.value !== 0;
input_elem.onchange = function() {
elem.value = input_elem.checked ? 1 : 0;
};
} else {
input_elem.value = elem.value;
input_elem.onchange = function() {
elem.value = input_elem.value;
}
}
label.textContent = elem.label;
label.appendChild(input_elem);
fieldset.appendChild(label);
// stop-gap until we make this prettier through css: insert a break
fieldset.appendChild(document.createElement("br"));
});
}
function add_events(name) {
// closing the Window
gui.Window.get().on("close", function () {
// this needs to do whatever the "cancel" button does
cancel();
});
pdgui.dialog_bindings(name);
}
</script>
</body>
</html>
......@@ -3596,7 +3596,7 @@ function gui_scope_displace(cid, tag, dx, dy) {
// unauthorized/grid
function make_grid_data(w, h, x_l, y_l) {
function get_grid_data(w, h, x_l, y_l) {
var d, x, y, offset;
d = [];
offset = Math.floor(w / x_l);
......@@ -3609,7 +3609,7 @@ function make_grid_data(w, h, x_l, y_l) {
}
offset = Math.floor(h / y_l);
if (offset > 0) {
for (y = 0; y < w; y += offset) {
for (y = 0; y < h; y += offset) {
d = d.concat(["M", 0, y, w, y]); // horizontal line
}
} else {
......@@ -3618,23 +3618,17 @@ function make_grid_data(w, h, x_l, y_l) {
return d.join(" ");
}
function gui_grid_draw_bg(cid, tag, w, h, bg_color, has_grid, x_l, y_l) {
function gui_configure_grid(cid, tag, w, h, bg_color, has_grid, x_l, y_l) {
var g = get_gobj(cid, tag),
border, // for inheriting gui preset colors
bg,
out_0,
out_1,
grid,
// configure each element in the grid
grid_d_string,
point,
point_size = 5;
bg = create_item(cid, "rect", {
configure_item(g.querySelector(".bg"), {
width: w,
height: h,
fill: bg_color,
class: "bg"
});
border = create_item(cid, "path", {
configure_item(g.querySelector(".border"), {
d: ["M", 0, 0, w, 0,
"M", 0, h, w, h,
"M", 0, 0, 0, h,
......@@ -3645,18 +3639,16 @@ function gui_grid_draw_bg(cid, tag, w, h, bg_color, has_grid, x_l, y_l) {
fill: "none",
stroke: "black",
"stroke-width": 1,
class: "border" // now we can inherit the css border styles
});
out_0 = create_item(cid, "rect", {
configure_item(g.querySelector(".out_0"), {
y: h + 1,
width: 7,
height: 1,
fill: "none",
stroke: "black",
"stroke-width": 1,
class: "out_0"
});
out_1 = create_item(cid, "rect", {
configure_item(g.querySelector(".out_1"), {
x: w - 7,
y: h + 1,
width: 7,
......@@ -3664,26 +3656,45 @@ function gui_grid_draw_bg(cid, tag, w, h, bg_color, has_grid, x_l, y_l) {
fill: "none",
stroke: "black",
"stroke-width": 1,
class: "out_1"
});
if (has_grid === 1) {
grid_d_string = make_grid_data(w, h, x_l, y_l);
grid = create_item(cid, "path", {
d: grid_d_string,
stroke: "white",
"stroke-width": 1,
class: "grid"
});
}
point = create_item(cid, "rect", {
grid_d_string = !!has_grid ? get_grid_data(w, h, x_l, y_l) : "";
configure_item(g.querySelector(".grid"), {
d: grid_d_string,
stroke: "white",
"stroke-width": 1,
});
configure_item(g.querySelector(".point"), {
style: "visibility: none;",
width: 5,
height: 5,
fill: "#ff0000",
stroke: "black",
"stroke-width": 1,
class: "point"
});
}
function gui_grid_new(cid, tag, x, y, is_toplevel) {
var g = gui_gobj_new(cid, tag, "obj", x, y, is_toplevel),
bg = create_item(cid, "rect", {
class: "bg"
}),
border = create_item(cid, "path", {
class: "border" // now we can inherit the css border styles
}),
out_0 = create_item(cid, "rect", {
class: "out_0"
}),
out_1 = create_item(cid, "rect", {
class: "out_1"
}),
grid = create_item(cid, "path", {
class: "grid"
}),
point = create_item(cid, "rect", {
class: "point"
});
g.appendChild(bg);
g.appendChild(out_0);
g.appendChild(out_1);
......@@ -3692,6 +3703,7 @@ function gui_grid_draw_bg(cid, tag, w, h, bg_color, has_grid, x_l, y_l) {
g.appendChild(border);
}
function gui_grid_point(cid, tag, x, y) {
var g = get_gobj(cid, tag),
p = g.querySelector(".point");
......@@ -4331,6 +4343,15 @@ function gui_font_dialog(cid, gfxstub, font_size) {
attrs);
}
function gui_external_dialog(did, external_name, attr_array) {
create_window(did, "external", 265, 450,
popup_coords[2], popup_coords[3],
{
name: external_name,
attributes: attr_array
});
}
// Global settings
function gui_pd_dsp(state) {
......
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