Hi,
We are developing a new command that can take a while to execute and so we want to add a progress bar and the option to cancel the operation. I see that there is the ShowProgressMeter() ( https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_UI_StatusBar_ShowProgressMeter.htm ) method which can be used to display a progress meter in the status bar, but there doesn’t seem to be a built-in way to cancel a command or display a cancel button (next to the progress meter for example) in the RhinoCommon API.
My question is:
Can the the status bar / progress bar be customized using the Eto framework? Or do we need to create our own dialog with progress bar + cancel button if we want to have the cancel option?
Thank you.
Hi @benoit.deschenes, you might offer a condition to cancel (eg with ESC and observe the key press). Below example is using Python , should be similar in RhinoCommon.
import Rhino
import scriptcontext
import rhinoscriptsyntax as rs
def DoSomething():
Rhino.UI.StatusBar.ShowProgressMeter(0, 5000, "Processing", True, True)
Rhino.RhinoApp.SetCommandPrompt("Hold ESC To cancel")
for i in xrange(5000):
if scriptcontext.escape_test(False):
Rhino.UI.StatusBar.HideProgressMeter()
return
if i % 100 == 0:
Rhino.UI.StatusBar.UpdateProgressMeter(i, True)
rs.Sleep(1)
Rhino.UI.StatusBar.HideProgressMeter()
DoSomething()
_
c.
Hi @clement,
Your’re right I could listen for some Keyboard input, but I’m more interested to know if there is a graphical UI option in the API for that kind of behavior, or if we have to code it ourselves if we need it.
Thank you.
Hi @benoit.deschenes, i don’t think there is something pre-canned. But you could do it like this:
- Setup a key value pair
Cancel=False
as document user string before the process starts*
- Start your process
- Open a modeless ETO Form with a single button. If the button is pressed, set
Cancel=True
- In your process, check the value similar as i check for ESC press
- If
Cancel
is True
, abort the process and hide the progress bar
- Set
Cancel=False
so it is functional for a next run
*instead of a user string, you might also use a global variable in C#
_
c.
Leaving the final solution here for posterity:
We ended up using the RhinoApp.EscapeKeyPressed
event in order to trigger our task cancellation, this does not require any additional UI creation.
1 Like
Thanks this is a very handy thread, I keep coming back to it to implement this pattern.
Here is a C# version for animation during a command
private bool _animate = true;
private bool _animating;
private void StopAnimation(object sender, EventArgs args) => _animating = false;
public void AnimateSomething() {
try {
_animating = _animate;
if (_animating) {
Rhino.UI.StatusBar.ShowProgressMeter(min, max, "Animating - hit escape to cancel", true, true);
RhinoApp.SetCommandPrompt("Hold ESC To cancel");
RhinoApp.EscapeKeyPressed += StopAnimation;
}
foreach (var item in Work) {
// do work
if (_animating) {
RhinoDoc.ActiveDoc.Views.Redraw();
Rhino.UI.StatusBar.UpdateProgressMeter(currentProgress, true);
RhinoApp.Wait();
Thread.Sleep(250);
}
}
} finally {
if (_animate) {
RhinoApp.EscapeKeyPressed -= StopAnimation;
Rhino.UI.StatusBar.HideProgressMeter();
}
}
}
1 Like