Skip to content

add 'bounds' arg to .plotTree; make .plotTree a single instance window; add ServerTreeView class#6294

Merged
telephon merged 24 commits intosupercollider:developfrom
prko:topic/make_plotTree_singleton_window
May 9, 2025
Merged

add 'bounds' arg to .plotTree; make .plotTree a single instance window; add ServerTreeView class#6294
telephon merged 24 commits intosupercollider:developfrom
prko:topic/make_plotTree_singleton_window

Conversation

@prko
Copy link
Contributor

@prko prko commented May 5, 2024

Purpose and Motivation

Currently s.plotTree creates new windows whenever the shortcut is pressed or s.plotTree is evaluated. This behaviour is strange because the following server-related windows are singleton windows

  • s.meter
  • s.freqscope
  • s.scope.

With this PR, s.plotTree makes only one singleton window.
I thought this was a bug, but someone may see it as a new feature.

Merge Note

When this PR is approved or merged, #6282 should be checked to see if it has already been approved or merged.

Types of changes

  • Bug fix or
  • New feature

To-do list

  • Code is tested
  • All tests are passing
  • Updated documentation
  • This PR is ready for review

@prko prko mentioned this pull request May 5, 2024
4 tasks
@telephon
Copy link
Member

telephon commented May 5, 2024

Thank you!

The important thing in all the changes was that we still have an option to have several of them if needed (e.g. for multi-screen setups).

s.meter –> ServerMeter
s.freqscope -> FreqScope
s.scope –> Stethoscope

But we have no ServerTreeView. This would be good.
Otherwise, we have no way to have multiple plotTree for one server if we need it.

Copy link
Member

@telephon telephon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have a possibility to have several views if needed.

@prko
Copy link
Contributor Author

prko commented May 5, 2024

@telephon
Thank you for your comments. This is a good idea!
I have added the feature you mentioned and the corresponding help documentation.
Will this be enough? Please let me know if I should revise the added methods and documentation or add more methods.

I think what you want is the behaviour of making a new window like ServerMeter and Stethoscope. See the Comment below.

ServerTreeView.new(s)
ServerTreeView(s)
ServerTreeView(s, Rect(300, 600, 300, 600)) // // arguments: server, bounds
ServerTreeView(s, Rect(300, 600, 300, 600), 1) // arguments: server, bounds, interval

Comment

  • ServerMeter and Stethoscope make always a new window:
    ServerMeter.new(s, 4, 2)
    // Evaluating this code twice will display two separate ServerMeter windows.
    
    Stethoscope.new 
    // Evaluating this code twice will display two separate Stethoscope windows.
    
  • FreqScope makes only one window:
    FreqScope.new(400, 200, 0, server: s)
    // Evaluating this code twice will display only one FreqScope window.
    

@prko prko changed the title make `.plotTree' a single instance window make .plotTree a single instance window and add ServerTreeView May 5, 2024
change the display text for the link::Search#asRect::
@prko
Copy link
Contributor Author

prko commented May 6, 2024

prko added 2 commits May 7, 2024 00:41
- help file
- remove closeAll
- close method fix
- fix the wrong return.
- revise the new method for the ServerTreeView class
- add plotTreeView method for the ServerTreeView class
- revise (simplify) the plotTree method for the Server class
- revise (simplify)the plotTreeView method for the Server class
@JordanHendersonMusic JordanHendersonMusic added the comp: class library SC class library label May 7, 2024
prko added 2 commits May 9, 2024 01:02
Add ServerTreeView feature with full backwards compatibility
- ServerTreeView
- .plotTree
- .plotTreeView
If there is already a s.plotTree, the following code preserves the precious position.

1. `s.plotTree` // evaluate this.
2. change the position of 1.
3. `s.plotTree` // evaluating this will only show the window, the position and size will not be changed.
@prko prko requested a review from telephon May 16, 2024 01:43
Copy link
Member

@telephon telephon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks already quite good, thank you! There are still some little things to do, but it is getting there...

@telephon
Copy link
Member

telephon commented May 17, 2024

One more idea, to make multiple views even more useful: instead of passing the argument server, you could call it target. Then, the view could monitor any group in the node tree.

Within the code, you can then call asTarget to get the group, and asTarget.server to get the server.

E.g.

g = Group.new(s);

g.asTarget // the group itself
g.asTarget.server // the server

// server asTarget returns the default group 
s.asTarget
// maybe, for passing a server, we want to get the parent
group = if(target.isKindOf(Server)) { s.defaultGroup.parent } { target.asTarget };

// then you could also write
ServerNodeTree.new; // monitors the default server and the full tree
ServerNodeTree.new(42); // monitors group 42

Ndef(\x, { SinOsc.ar(Rand(200, 800)) * 0.1 });
Ndef(\x).fadeTime = 3;
Tdef(\x, { loop { 1.wait; Ndef(\x).send } }).play;
ServerNodeTree.new(Ndef(\x));

etc.

- updated according to review request
- new: if no server argument is given, the default server is used.
Copy link
Member

@telephon telephon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you very much, it is already very good! I made a few more comments.

- updated according to the review
- corrected background colour for start-stop
@prko
Copy link
Contributor Author

prko commented May 20, 2024

@telephon
Could you see my comments to the following two comments of yours?


One more idea, to make multiple views even more useful: instead of passing the argument server, you could call it target. Then, the view could monitor any group in the node tree.

Within the code, you can then call asTarget to get the group, and asTarget.server to get the server.


g = Group.new(s);

g.asTarget // the group itself
g.asTarget.server // the server

// server asTarget returns the default group 
s.asTarget
// maybe, for passing a server, we want to get the parent
group = if(target.isKindOf(Server)) { s.defaultGroup.parent } { target.asTarget };

// then you could also write
ServerNodeTree.new; // monitors the default server and the full tree
ServerNodeTree.new(42); // monitors group 42

Ndef(\x, { SinOsc.ar(Rand(200, 800)) * 0.1 });
Ndef(\x).fadeTime = 3;
Tdef(\x, { loop { 1.wait; Ndef(\x).send } }).play;
ServerNodeTree.new(Ndef(\x));

It is also a great idea. But what do you mean by this?

  • Create a new class ServerNodeTree? (I think this may be what you want)
  • Implement this idea in this PR?

Copy link
Member

@telephon telephon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reading the code, I found that there are a few things to do, I hope this is fine for you.

  • move the whole class definition to a separate file. "ServerPlusGui" implies that these are extensions only
  • for now, maybe let's drop the feature of passing a parent? This can be added later. Let's just make a new window always and just pass the bounds. The current way of handling the parent is brittle. Or do you see a reason that we need that right now?
  • the updater thing is still not correct, this may have been wrong already in the code you copied from the server, I am not sure. The updater is supposed to be a Routine, resulting from the fork, but currently it is just a function. So updateFunc.stop never works! Line 162 should be updater = fork { ... without the extra function brackets. Then, still the stopping on cmdPeriod needs to be fixed. If you need support on that I'll help, but this is getting long so I'll stop here.

prko added 2 commits May 20, 2024 20:22
- Update after review
- Correct loop behaviour to avoid errors after 
   - closing s.plotTree and a window containing `ServerTreeView`, and
   - starting server and quitting server
- correct `updateFunc` and `updater`
@prko
Copy link
Contributor Author

prko commented May 20, 2024

Thank you for your review!

move the whole class definition to a separate file. "ServerPlusGui" implies that these are extensions only

Please let me know the name of the new file and where it is located. What I think is ServerTreeView.sc in the same folder as ServerPlusGui.sc. Is my thinking correct?

for now, maybe let's drop the feature of passing a parent? This can be added later. Let's just make a new window always and just pass the bounds. The current way of handling the parent is brittle. Or do you see a reason that we need that right now?

Do you mean the parent argument in ServerTreeView.new and ServerTreeView.makeWindow? They come from .plotTreeView:

plotTreeView {|interval=0.5, parent, actionIfFail|

Following your recommendation, I have moved some parts of .plotTreeView to ServerTreeView.new and ServerTreeView.makeWindow, and the parent argument has also been copied. Can you explain the brittleness of the parent handling? I will make it more robust.

the updater thing is still not correct, this may have been wrong already in the code you copied from the server, I am not sure. The updater is supposed to be a Routine, resulting from the fork, but currently it is just a function. So updateFunc.stop never works! Line 162 should be updater = fork { ... without the extra function brackets.

Um... anyway, `.stop' has worked (and sorry for not taking a closer look at the part nor writing it by myself!):

@telephon
Copy link
Member

Sorry for not coming back to this, I was busy with outher things. Will continue later, if this is ok.

restore whitespaces
@prko
Copy link
Contributor Author

prko commented Jul 4, 2024

@telephon

Thank you for your review!

move the whole class definition to a separate file. "ServerPlusGui" implies that these are extensions only
Please let me know the name of the new file and where it is located. What I think is ServerTreeView.sc in the same folder as >ServerPlusGui.sc. Is my thinking correct?

for now, maybe let's drop the feature of passing a parent? This can be added later. Let's just make a new window always and just pass the bounds. The current way of handling the parent is brittle. Or do you see a reason that we need that right now?

I have split ServerTreeView from ServerPlusGui.sc and created ServerTreeView.sc in the same folder.

@prko
Copy link
Contributor Author

prko commented Jul 7, 2024

I have moved adding bound argument to plotTree here. It was originally in #6282. I hope this will speed up the review process for both PRs.

@prko prko changed the title make .plotTree a single instance window and add ServerTreeView add 'bounds' arg to .plotTree; make .plotTree a single instance window; add ServerTreeView class Jul 7, 2024
Copy link
Member

@telephon telephon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a little change. The original code (not yours!) was a bit convoluted already, so in the future maybe we can improve that. For now, fine.

The size correction stuff should perhaps be done once and correctly, so we don't have to rethink it each time. You could remove it here and add it later.

@prko prko mentioned this pull request Dec 24, 2024
3 tasks
@prko
Copy link
Contributor Author

prko commented Apr 27, 2025

@prko
Copy link
Contributor Author

prko commented Apr 28, 2025

@telephon

The else branch in https://github.com/prko/supercollider/blob/503e541399fcab8c688d67b1ecd2a029d7f6c5fe/SCClassLibrary/Common/GUI/PlusGUI/Control/ServerPlusGUI.sc#L371C4-L373C41 should be left out, perhaps? We don't want to enforce the limit if someone has consciously resized the view?

(from: #6294 (comment))

I have removed that else part within the braces:

{
			bounds = bounds ? this.plotTreeWindow.bounds;
			bounds = bounds.minSize(395@386);  // `395@386` was Size(395, 386) in the previous commit.
			plotTreeWindow.bounds_(bounds).front;
		};

However, the bounds argument now no longer functions correctly:

  • Code example:
    s.plotTree; //<------ This works!
    
    s.plotTree(2, Rect(200, 200, 100, 200)); //<------ This does not works!
    
    s.plotTree;  //<------ This does not works!
  • The corresponding part in the help documentation (Server.plotTree):
    Screenshot 2025-04-28 at 13 01 26

Given this (demo video), I am considering the best course of action:

  • Should I remove the bounds argument and the corresponding reference to .plotTree in the Server help file?
  • Or would it be preferable to restore the removed portion so that the code functions as expected once again?
  • Would you like to confirm whether you meant only removing the following part?
    bounds = bounds.minSize(395@386);  // `395@386` was `Size(395, 386)` in the previous commit.
    If the issue is primarily caused by enforcing a minimum size, then removing just this line might be a solution while maintaining functionality....?

I would appreciate your insight on this matter.

@prko
Copy link
Contributor Author

prko commented May 4, 2025

Now, bounds argument works again, but it does not change the size even the size is smaller than 395@386.

@telephon
Copy link
Member

telephon commented May 5, 2025

sorry, it's been a while. I think this would be the right way to do it:

plotTree { |interval=0.5, bounds|
	
	if(plotTreeWindow.isNil) {
		bounds = bounds ?? { Rect(128, 64, 400, 400) };
		bounds = bounds.minSize(395@386);
		plotTreeWindow = Window(name.asString ++ " Node Tree", bounds, scroll:true);
		plotTreeWindow.onClose = { plotTreeWindow = nil };
		this.plotTreeView(interval, plotTreeWindow, { defer { plotTreeWindow.close } });
	} {
		if(bounds.notNil) { 
			bounds = bounds.minSize(395@386);
			plotTreeWindow.bounds_(bounds) 
		};
	};
	
	plotTreeWindow.front;
}

What do you think?

@prko
Copy link
Contributor Author

prko commented May 6, 2025

Yes, it is good, Thanks!

@telephon telephon merged commit d21a7d8 into supercollider:develop May 9, 2025
24 of 26 checks passed
@github-project-automation github-project-automation bot moved this from Waiting for review response to Done in SuperCollider development May 9, 2025
@telephon
Copy link
Member

telephon commented May 9, 2025

The new structure is good. Trying this, @prko I found that we have lost a few things in this new system which should be added in.

Screenshot 2025-05-09 at 23 32 35

The node ids for groups are not visible anymore, and also the nesting structure. Would you like to help by adding it back in?

@prko
Copy link
Contributor Author

prko commented May 10, 2025

Thank you for bringing this to my attention, and I sincerely apologise for any inconvenience I caused.

I believe I have identified the issue and resolved it in #6834.

I have also attached a demonstration video for your reference.

Please do let me know if there is anything else that requires further refinement or updates.

@dyfer dyfer mentioned this pull request May 16, 2025
dyfer added a commit that referenced this pull request May 31, 2025
…6294,

* fix "Rect collision issue with too many nodes" (#6834)

* make `.plotTree' a single instance window

* add new class ServerTreeView and SCDoc

* Update ServerPlusGUI.sc

- revise the new method for the ServerTreeView class
- add plotTreeView method for the ServerTreeView class
- revise (simplify) the plotTree method for the Server class
- revise (simplify)the plotTreeView method for the Server class

* Update ServerPlusGUI.sc

Add ServerTreeView feature with full backwards compatibility
- ServerTreeView
- .plotTree
- .plotTreeView

* s.plotTree behaviour change

If there is already a s.plotTree, the following code preserves the precious position.

1. `s.plotTree` // evaluate this.
2. change the position of 1.
3. `s.plotTree` // evaluating this will only show the window, the position and size will not be changed.

* Update ServerPlusGUI.sc

- updated according to review request
- new: if no server argument is given, the default server is used.

* Update ServerPlusGUI.sc

- updated according to the review
- corrected background colour for start-stop

* Update ServerPlusGUI.sc

- Update after review
- Correct loop behaviour to avoid errors after 
   - closing s.plotTree and a window containing `ServerTreeView`, and
   - starting server and quitting server

* Update ServerPlusGUI.sc

- correct `updateFunc` and `updater`


* reflect reviews and fixes bugs

1. Changes the way the rectangle is drawn to prevent collisions when there are many nodes. I initially tried to solve this problem by using a factor, but this approach was not very successful. I left this as a comment. The new implementation is not perfect, but it is an improvement on both the previous commit method and the abandoned approach.
2. It restricts multiple executions of the updater in a ServerTreeView. Starting again from the same ServerTreeView instance will be ignored and a warning will be displayed.
3. It adds a warning when multiple .plotTree calls are made.
4. Additional text is added to the current warning when the .plotTree function closes due to the server not running.

TO DO:
Allow the user to create multiple instances of ServerTreeView, including .plotTree. However, there is currently only one updater and one OSCFunc. Therefore, each instance cannot have its own interval, and stopping an instance does not update the label correctly. In fact, updating the node tree may occur when at least one ServerTreeView instance is running. This issue is documented in the example section of the ServerTreeView.schelp file. To resolve this issue, we need to discuss the various possible solutions.

* ServerTreeView: rework updating logic; cleanup

---------

Co-authored-by: Marcin Pączkowski <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: class library SC class library

Projects

Development

Successfully merging this pull request may close these issues.

3 participants