Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Jonathan Wilkes
purr-data
Commits
7f0ae827
Commit
7f0ae827
authored
Sep 17, 2020
by
Jonathan Wilkes
Browse files
Merge branch 'guillembartrina/purr-data-feature-dirtywarnings-rebased'
parents
ffea3cd5
8bf3e10e
Changes
9
Hide whitespace changes
Inline
Side-by-side
pd/nw/locales/de/translation.json
View file @
7f0ae827
...
...
@@ -297,6 +297,10 @@
"none"
:
"Keinen"
,
"none_tt"
:
"Ersetze keinen der Subpatches"
},
"warning"
:
{
"unsaved_tt"
:
"Es gibt ein ungesichertes Exemplar dieser Abstraktion"
,
"multipleunsaved_tt"
:
"Es gibt ein weiteres ungesichertes Exemplar dieser Abstraktion"
},
"find"
:
{
"placeholder"
:
"Suche im Patch"
,
"search"
:
"Suche"
,
...
...
pd/nw/locales/en/translation.json
View file @
7f0ae827
...
...
@@ -297,6 +297,10 @@
"none"
:
"None"
,
"none_tt"
:
"Do not replace any subpatch"
},
"warning"
:
{
"unsaved_tt"
:
"There is an unsaved edited instance of this abstraction"
,
"multipleunsaved_tt"
:
"There is another unsaved edited instance of this abstraction"
},
"find"
:
{
"placeholder"
:
"Search in Canvas"
,
"search"
:
"Search"
,
...
...
pd/nw/locales/fr/translation.json
View file @
7f0ae827
...
...
@@ -297,6 +297,10 @@
"none"
:
"Aucun"
,
"none_tt"
:
"Ne remplacer aucun sous-patch"
},
"warning"
:
{
"unsaved_tt"
:
"Il existe une instance modifiée non enregistrée de cette abstraction"
,
"multipleunsaved_tt"
:
"Il existe une autre instance modifiée non enregistrée de cette abstraction"
},
"find"
:
{
"placeholder"
:
"Chercher dans le Canevas"
,
"search"
:
"Chercher"
,
...
...
pd/nw/pd_canvas.html
View file @
7f0ae827
...
...
@@ -102,6 +102,9 @@
</button>
</div>
</dialog>
<div
style=
"position: fixed; right: 2%; top: 2%; "
>
<strong
id=
"canvas_warning"
style=
"display: none; text-align: right; -webkit-user-select: none; cursor: pointer;"
>
!
</strong>
</div>
<div
id=
"hscroll"
style=
"position: fixed; left: 0px; bottom: 0px; border-radius: 0px; width: 10px; height: 5px; visibility: hidden;"
></div>
<div
id=
"vscroll"
style=
"position: fixed; right: 0px; top: 0px; border-radius: 0px; width: 5px; height: 10px; visibility: hidden;"
></div>
<script
type=
"text/javascript"
src=
"./pd_canvas.js"
></script>
...
...
pd/nw/pd_canvas.js
View file @
7f0ae827
...
...
@@ -1336,6 +1336,9 @@ function register_window_id(cid, attr_array) {
// we check the title_queue to see if our title now contains an asterisk
// (which is the visual cue for "dirty")
// Enable/disable the warning for multiple dirty instances
pdgui
.
gui_canvas_warning
(
cid
,
attr_array
.
warid
);
// Two possibilities for handling this better:
// have a representation of canvas attys in pdgui.js (editmode, dirty, etc.)
// or
...
...
pd/nw/pdgui.js
View file @
7f0ae827
...
...
@@ -1760,7 +1760,7 @@ function create_window(cid, type, width, height, xpos, ypos, attr_array) {
}
// create a new canvas
function
gui_canvas_new
(
cid
,
width
,
height
,
geometry
,
grid
,
zoom
,
editmode
,
name
,
dir
,
dirty_flag
,
hide_scroll
,
hide_menu
,
has_toplevel_scalars
,
cargs
)
{
function gui_canvas_new(cid, width, height, geometry, grid, zoom, editmode, name, dir, dirty_flag,
warid,
hide_scroll, hide_menu, has_toplevel_scalars, cargs) {
// hack for buggy tcl popups... should go away for node-webkit
//reset_ctrl_on_popup_window
...
...
@@ -1817,6 +1817,7 @@ function gui_canvas_new(cid, width, height, geometry, grid, zoom, editmode, name
name: name,
dir: dir,
dirty: dirty_flag,
warid: warid,
args: cargs,
zoom: zoom,
editmode: editmode,
...
...
@@ -2860,6 +2861,35 @@ function gui_gobj_dirty(cid, tag, state) {
});
}
function gui_canvas_warning(cid, warid) {
var warning = get_item(cid, "canvas_warning");
switch(warid)
{
case 0:
warning.style.setProperty("display", "none");
break;
case 1:
warning.title = lang.get_local_string("canvas.warning.unsaved_tt");
warning.onclick = function(){ pdsend(cid, "showdirty"); }
warning.style.setProperty("color", "coral");
warning.style.setProperty("font-size", "x-large");
warning.style.setProperty("display", "inline");
break;
case 2:
warning.title = lang.get_local_string("canvas.warning.multipleunsaved_tt");
warning.onclick = function(){ pdsend(cid, "showdirty"); }
warning.style.setProperty("color", "red");
warning.style.setProperty("font-size", "xx-large");
warning.style.setProperty("display", "inline");
break;
default:
break;
}
}
exports.gui_canvas_warning = gui_canvas_warning;
function gui_canvas_emphasize(cid) {
gui(cid).get_elem("patchsvg", function(e) {
// raise the window
...
...
pd/src/g_canvas.c
View file @
7f0ae827
...
...
@@ -396,6 +396,8 @@ static int calculate_zoom(t_float zoom_hack)
return
zoom
;
}
int
canvas_dirty_broadcast_all
(
t_symbol
*
name
,
t_symbol
*
dir
,
int
mess
);
/* make a new glist. It will either be a "root" canvas or else
it appears as a "text" object in another window (canvas_getcurrent()
tells us which.) */
...
...
@@ -472,6 +474,7 @@ t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv)
else
x
->
gl_env
=
0
;
x
->
gl_subdirties
=
0
;
x
->
gl_dirties
=
0
;
if
(
yloc
<
GLIST_DEFCANVASYLOC
)
yloc
=
GLIST_DEFCANVASYLOC
;
...
...
@@ -522,6 +525,14 @@ t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv)
canvas_field_vec
=
NULL
;
canvas_field_gp
=
NULL
;
/* in the case it is an abstraction (gl_env is not null)
get the number of dirty instances of this same abstraction */
if
(
x
->
gl_env
)
{
x
->
gl_dirties
=
canvas_dirty_broadcast_all
(
x
->
gl_name
,
canvas_getdir
(
x
),
0
);
}
return
(
x
);
}
...
...
@@ -792,6 +803,100 @@ void canvas_dirtyclimb(t_canvas *x, int n)
}
}
/* the following functions are used to broadcast messages to all instances of
a specific abstraction (either file-based or ab).
the state of these instances change accoring to the message sent. */
void
clone_iterate
(
t_pd
*
z
,
t_canvas_iterator
it
,
void
*
data
);
int
clone_match
(
t_pd
*
z
,
t_symbol
*
name
,
t_symbol
*
dir
);
static
void
canvas_dirty_common
(
t_canvas
*
x
,
int
mess
)
{
if
(
mess
==
2
)
{
if
(
x
->
gl_dirty
)
{
if
(
!
x
->
gl_havewindow
)
canvas_vis
(
x
,
1
);
gui_vmess
(
"gui_canvas_emphasize"
,
"x"
,
x
);
}
}
else
{
x
->
gl_dirties
+=
mess
;
if
(
x
->
gl_havewindow
)
canvas_warning
(
x
,
(
x
->
gl_dirties
>
1
?
(
x
->
gl_dirty
?
2
:
1
)
:
(
x
->
gl_dirties
?
!
x
->
gl_dirty
:
0
)));
}
}
/* packed data passing structure for canvas_dirty_broadcast */
typedef
struct
_dirty_broadcast_data
{
t_symbol
*
name
;
t_symbol
*
dir
;
int
mess
;
int
*
res
;
/* return value */
}
t_dirty_broadcast_data
;
static
void
canvas_dirty_deliver_packed
(
t_canvas
*
x
,
t_dirty_broadcast_data
*
data
)
{
*
data
->
res
+=
(
x
->
gl_dirty
>
0
);
canvas_dirty_common
(
x
,
data
->
mess
);
}
static
int
canvas_dirty_broadcast_packed
(
t_canvas
*
x
,
t_dirty_broadcast_data
*
data
);
static
int
canvas_dirty_broadcast
(
t_canvas
*
x
,
t_symbol
*
name
,
t_symbol
*
dir
,
int
mess
)
{
int
res
=
0
;
t_gobj
*
g
;
for
(
g
=
x
->
gl_list
;
g
;
g
=
g
->
g_next
)
{
if
(
pd_class
(
&
g
->
g_pd
)
==
canvas_class
)
{
if
(
canvas_isabstraction
((
t_canvas
*
)
g
)
&&
((
t_canvas
*
)
g
)
->
gl_name
==
name
&&
canvas_getdir
((
t_canvas
*
)
g
)
==
dir
)
{
res
+=
(((
t_canvas
*
)
g
)
->
gl_dirty
>
0
);
canvas_dirty_common
((
t_canvas
*
)
g
,
mess
);
}
else
res
+=
canvas_dirty_broadcast
((
t_canvas
*
)
g
,
name
,
dir
,
mess
);
}
else
if
(
pd_class
(
&
g
->
g_pd
)
==
clone_class
)
{
int
cres
=
0
;
t_dirty_broadcast_data
data
;
data
.
name
=
name
;
data
.
dir
=
dir
;
data
.
mess
=
mess
;
data
.
res
=
&
cres
;
if
(
clone_match
(
&
g
->
g_pd
,
name
,
dir
))
{
clone_iterate
(
&
g
->
g_pd
,
canvas_dirty_deliver_packed
,
&
data
);
}
else
{
clone_iterate
(
&
g
->
g_pd
,
canvas_dirty_broadcast_packed
,
&
data
);
}
res
+=
cres
;
}
}
return
(
res
);
}
static
int
canvas_dirty_broadcast_packed
(
t_canvas
*
x
,
t_dirty_broadcast_data
*
data
)
{
*
data
->
res
=
canvas_dirty_broadcast
(
x
,
data
->
name
,
data
->
dir
,
data
->
mess
);
}
int
canvas_dirty_broadcast_all
(
t_symbol
*
name
,
t_symbol
*
dir
,
int
mess
)
{
int
res
=
0
;
t_canvas
*
x
;
for
(
x
=
pd_this
->
pd_canvaslist
;
x
;
x
=
x
->
gl_next
)
res
+=
canvas_dirty_broadcast
(
x
,
name
,
dir
,
mess
);
return
(
res
);
}
/* mark a glist dirty or clean */
void
canvas_dirty
(
t_canvas
*
x
,
t_floatarg
n
)
{
...
...
@@ -806,6 +911,15 @@ void canvas_dirty(t_canvas *x, t_floatarg n)
/* set dirtiness visual markings */
canvas_dirtyclimb
(
x2
,
(
unsigned
)
n
);
/* in the case it is an abstraction, we tell all other
instances that there is eiher one more dirty instance or
one less dirty instance */
if
(
canvas_isabstraction
(
x2
)
&&
(
x2
->
gl_owner
||
x2
->
gl_isclone
))
{
canvas_dirty_broadcast_all
(
x2
->
gl_name
,
canvas_getdir
(
x2
),
(
x2
->
gl_dirty
?
1
:
-
1
));
}
}
}
...
...
@@ -1034,6 +1148,15 @@ extern void canvas_group_free(t_pd *x);
void
canvas_free
(
t_canvas
*
x
)
{
//fprintf(stderr,"canvas_free %zx\n", (t_uint)x);
/* in the case it is a dirty abstraction, we tell all other
instances that there is one less dirty instance */
if
(
canvas_isabstraction
(
x
)
&&
x
->
gl_dirty
&&
(
x
->
gl_owner
||
x
->
gl_isclone
))
{
canvas_dirty_broadcast_all
(
x
->
gl_name
,
canvas_getdir
(
x
),
-
1
);
}
t_gobj
*
y
;
int
dspstate
=
canvas_suspend_dsp
();
...
...
@@ -1893,6 +2016,13 @@ void canvas_redrawallfortemplatecanvas(t_canvas *x, int action)
canvas_redrawallfortemplate
(
0
,
action
);
}
/* --------- */
static
void
canvas_showdirty
(
t_canvas
*
x
)
{
canvas_dirty_broadcast_all
(
x
->
gl_name
,
canvas_getdir
(
x
),
2
);
}
/* ------------------------------- declare ------------------------ */
/* put "declare" objects in a patch to tell it about the environment in
...
...
@@ -2765,6 +2895,8 @@ void g_canvas_setup(void)
class_addcreator
((
t_newmethod
)
table_new
,
gensym
(
"table"
),
A_DEFSYM
,
A_DEFFLOAT
,
0
);
class_addmethod
(
canvas_class
,
(
t_method
)
canvas_showdirty
,
gensym
(
"showdirty"
),
0
);
/*---------------------------- declare ------------------- */
declare_class
=
class_new
(
gensym
(
"declare"
),
(
t_newmethod
)
declare_new
,
(
t_method
)
declare_free
,
sizeof
(
t_declare
),
CLASS_NOINLET
,
A_GIMME
,
0
);
...
...
pd/src/g_canvas.h
View file @
7f0ae827
...
...
@@ -235,6 +235,7 @@ struct _glist
t_gpointer
gl_gp
;
/* parent for "canvas" data type */
int
gl_subdirties
;
/* number of descending dirty abstractions */
int
gl_dirties
;
/* number of diry instances, for multiple dirty warning */
};
#define gl_gobj gl_obj.te_g
...
...
@@ -581,6 +582,7 @@ EXTERN int canvas_setdeleting(t_canvas *x, int flag);
EXTERN
int
canvas_hasarray
(
t_canvas
*
x
);
EXTERN
int
canvas_has_scalars_only
(
t_canvas
*
x
);
EXTERN
void
canvas_warning
(
t_canvas
*
x
,
int
warid
);
#define LB_LOAD 0
/* "loadbang" actions - 0 for original meaning */
#define LB_INIT 1
/* loaded but not yet connected to parent patch */
...
...
pd/src/g_editor.c
View file @
7f0ae827
...
...
@@ -2752,7 +2752,7 @@ void canvas_vis(t_canvas *x, t_floatarg f)
We may need to expand this to include scalars, as well. */
canvas_create_editor
(
x
);
canvas_args_to_string
(
argsbuf
,
x
);
gui_vmess
(
"gui_canvas_new"
,
"xiisiiissiiiis"
,
gui_vmess
(
"gui_canvas_new"
,
"xiisiiissiiii
i
s"
,
x
,
(
int
)(
x
->
gl_screenx2
-
x
->
gl_screenx1
),
(
int
)(
x
->
gl_screeny2
-
x
->
gl_screeny1
),
...
...
@@ -2763,6 +2763,9 @@ void canvas_vis(t_canvas *x, t_floatarg f)
x
->
gl_name
->
s_name
,
canvas_getdir
(
x
)
->
s_name
,
x
->
gl_dirty
,
(
x
->
gl_dirties
>
1
?
(
x
->
gl_dirty
?
2
:
1
)
:
(
x
->
gl_dirties
?
!
x
->
gl_dirty
:
0
)),
x
->
gl_noscroll
,
x
->
gl_nomenu
,
canvas_hasarray
(
x
),
...
...
@@ -6171,6 +6174,12 @@ void gobj_dirty(t_gobj *x, t_glist *g, int state)
t_rtext *y = glist_findrtext(g, (t_text *)x);
gui_vmess("
gui_gobj_dirty
", "
xsi
", g, rtext_gettag(y), state);
}
/* tell the gui to display a specific message in the
top right corner */
void canvas_warning(t_canvas *x, int warid)
{
gui_vmess("
gui_canvas_warning
", "
xi
", x, warid);
}
static int glist_dofinderror(t_glist *gl, void *error_object)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment