Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

developer:rhinocommonsamples:customundo [2015/09/14] (current)
Line 1: Line 1:
 +===== Sample: Custom Undo =====
 +Rhino automatically sets up undo records for you when you modify the document, but in the rare case where you need to support undo/redo of your own private plug-in data, you can use the following approach.
 +
 +===== C# =====
 +<code c#>
 +using System;
 +using System.Runtime.InteropServices;​
 +using Rhino;
 +
 +[Guid("​954B8E21-51F2-4115-BD6B-DE67EE874C74"​)]
 +public class ex_customundoCommand : Rhino.Commands.Command
 +{
 +  public override string EnglishName { get { return "​cs_CustomUndoCommand";​ } }
 +
 +  double MyFavoriteNumber { get; set; }
 +
 +  protected override Rhino.Commands.Result RunCommand(RhinoDoc doc, Rhino.Commands.RunMode mode)
 +  {
 +    // Rhino automatically sets up an undo record when a command is run,
 +    // but... the undo record is not saved if nothing changes in the
 +    // document (objects added/​deleted,​ layers changed,​...)
 +    //
 +    // If we have a command that doesn'​t change things in the document,
 +    // but we want to have our own custom undo called then we need to do
 +    // a little extra work
 +
 +    double d = MyFavoriteNumber;​
 +    if (Rhino.Input.RhinoGet.GetNumber("​Favorite number",​ true, ref d) == Rhino.Commands.Result.Success)
 +    {
 +      double current_value = MyFavoriteNumber;​
 +      doc.AddCustomUndoEvent("​Favorite Number",​ OnUndoFavoriteNumber,​ current_value);​
 +      MyFavoriteNumber = d;
 +    }
 +    return Rhino.Commands.Result.Success;​
 +  }
 +
 +  // event handler for custom undo
 +  void OnUndoFavoriteNumber(object sender, Rhino.Commands.CustomUndoEventArgs e)
 +  {
 +    // !!!!!!!!!!
 +    // NEVER change any setting in the Rhino document or application. ​ Rhino
 +    // handles ALL changes to the application and document and you will break
 +    // the Undo/Redo commands if you make any changes to the application or
 +    // document. This is meant only for your own private plug-in data
 +    // !!!!!!!!!!
 +
 +    // This function can be called either by undo or redo
 +    // In order to get redo to work, add another custom undo event with the
 +    // current value. ​ If you don't want redo to work, just skip adding
 +    // a custom undo event here
 +    double current_value = MyFavoriteNumber;​
 +    e.Document.AddCustomUndoEvent("​Favorite Number",​ OnUndoFavoriteNumber,​ current_value);​
 +
 +    double old_value = (double)e.Tag;​
 +    RhinoApp.WriteLine("​Going back to your favorite = {0}", old_value);
 +    MyFavoriteNumber = old_value;
 +  }
 +}
 +</​code>​
 +===== VB.NET =====
 +<code vb>
 +Imports System.Runtime.InteropServices
 +Imports Rhino
 +
 +<​Guid("​A6924FE1-2B94-4918-94F3-B8935B8DC80C"​)>​ _
 +Public Class ex_customundoCommand
 +  Inherits Rhino.Commands.Command
 +  Public Overrides ReadOnly Property EnglishName() As String
 +    Get
 +      Return "​vb_CustomUndoCommand"​
 +    End Get
 +  End Property
 +
 +  Private Property MyFavoriteNumber() As Double
 +    Get
 +      Return m_MyFavoriteNumber
 +    End Get
 +    Set(value As Double)
 +      m_MyFavoriteNumber = value
 +    End Set
 +  End Property
 +  Private m_MyFavoriteNumber As Double
 +
 +  Protected Overrides Function RunCommand(doc As RhinoDoc, mode As Rhino.Commands.RunMode) As Rhino.Commands.Result
 +    ' Rhino automatically sets up an undo record when a command is run,
 +    ' but... the undo record is not saved if nothing changes in the
 +    ' document (objects added/​deleted,​ layers changed,​...)
 +    '
 +    ' If we have a command that doesn'​t change things in the document,
 +    ' but we want to have our own custom undo called then we need to do
 +    ' a little extra work
 +
 +    Dim d As Double = MyFavoriteNumber
 +    If Rhino.Input.RhinoGet.GetNumber("​Favorite number",​ True, d) = Rhino.Commands.Result.Success Then
 +      Dim current_value As Double = MyFavoriteNumber
 +      doc.AddCustomUndoEvent("​Favorite Number",​ AddressOf OnUndoFavoriteNumber,​ current_value)
 +      MyFavoriteNumber = d
 +    End If
 +    Return Rhino.Commands.Result.Success
 +  End Function
 +
 +  ' event handler for custom undo
 +  Private Sub OnUndoFavoriteNumber(sender As Object, e As Rhino.Commands.CustomUndoEventArgs)
 +    ' !!!!!!!!!!
 +    ' NEVER change any setting in the Rhino document or application. ​ Rhino
 +    ' handles ALL changes to the application and document and you will break
 +    ' the Undo/Redo commands if you make any changes to the application or
 +    ' document. This is meant only for your own private plug-in data
 +    ' !!!!!!!!!!
 +
 +    ' This function can be called either by undo or redo
 +    ' In order to get redo to work, add another custom undo event with the
 +    ' current value. ​ If you don't want redo to work, just skip adding
 +    ' a custom undo event here
 +    Dim current_value As Double = MyFavoriteNumber
 +    e.Document.AddCustomUndoEvent("​Favorite Number",​ AddressOf OnUndoFavoriteNumber,​ current_value)
 +
 +    Dim old_value As Double = CDbl(e.Tag)
 +    RhinoApp.WriteLine("​Going back to your favorite = {0}", old_value)
 +    MyFavoriteNumber = old_value
 +  End Sub
 +End Class
 +</​code>​
 +===== Python =====
 +<code python>
 +import Rhino
 +import scriptcontext
 +
 +
 +def OnUndoFavoriteNumber(sender,​ e):
 +    """​!!!!!!!!!!
 +    NEVER change any setting in the Rhino document or application. ​ Rhino
 +    handles ALL changes to the application and document and you will break
 +    the Undo/Redo commands if you make any changes to the application or
 +    document. This is meant only for your own private plug-in data
 +    !!!!!!!!!!
 +
 +    This function can be called either by undo or redo
 +    In order to get redo to work, add another custom undo event with the
 +    current value. ​ If you don't want redo to work, just skip adding
 +    a custom undo event here
 +    """​
 +    current_value = scriptcontext.sticky["​FavoriteNumber"​]
 +    e.Document.AddCustomUndoEvent("​Favorite Number",​ OnUndoFavoriteNumber,​ current_value)
 +
 +    old_value = e.Tag
 +    print "Going back to your favorite =", old_value
 +    scriptcontext.sticky["​FavoriteNumber"​]= old_value;
 +
 +
 +def TestCustomUndo():​
 +    """​Rhino automatically sets up an undo record when a command is run,
 +       ​but... the undo record is not saved if nothing changes in the
 +       ​document (objects added/​deleted,​ layers changed,​...)
 +    ​
 +       If we have a command that doesn'​t change things in the document,
 +       but we want to have our own custom undo called then we need to do
 +       a little extra work
 +    """​
 +    current_value = 0
 +    if scriptcontext.sticky.has_key("​FavoriteNumber"​):​
 +        current_value = scriptcontext.sticky["​FavoriteNumber"​]
 +    rc, new_value = Rhino.Input.RhinoGet.GetNumber("​Favorite number",​ True, current_value)
 +    if rc!=Rhino.Commands.Result.Success:​ return
 +
 +    scriptcontext.doc.AddCustomUndoEvent("​Favorite Number",​ OnUndoFavoriteNumber,​ current_value);​
 +    scriptcontext.sticky["​FavoriteNumber"​] = new_value
 +
 +if __name__=="​__main__":​
 +    TestCustomUndo()
 +
 +</​code>​
 +
 +{{tag>​Developer rhinocommon}}
  
developer/rhinocommonsamples/customundo.txt ยท Last modified: 2015/09/14 (external edit)