RhinoCommon: Multiple English Names

I’m trying to create a fairly simply plugin. It will incorporate multiple commands. But each command will be very similar.
I want to use multiple English Names. And then I want the code to do something slightly different depending on which English Name was called.
Is this possible or do I need to copy the entire “SamplePlugin1Command” class? I suppose it’s not that much work just the code wouldn’t be very DRY.
I’m strong with scripting but my knowledge of software architecture/organization is quite lacking.

namespace SamplePlugin1
{
    public class SamplePlugin1Command : Command
    {
        public SamplePlugin1Command()
        {
            Instance = this;
        }

        public static SamplePlugin1Command Instance { get; private set; }

        public override string EnglishName => "Test1";
        public override string EnglishName => "Test2";
        public override string EnglishName => "Test3";

        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
           
            RhinoApp.WriteLine("Nothing here yet");

            return Result.Success;
        }
    }
}

Visual Studio won’t allow this:

image

In the same class you cannot have two or more properties of the same name.

Make a base class command that you derive from. Then you can override the EnglishName in each subclass.

public class BaseCommand : Command
{
  protected override Result RunCommand(RhinoDoc doc, RunMode mode)
  {
    // logic here
    return Result.Success;
}

public class Test1Command : BaseCommand
{
  public override string EnglishName => "Test1";
}

public class Test1Command : BaseCommand
{
  public override string EnglishName => "Test2";
}

Here an actual code I wrote for toggling lock and pause status:

  public abstract class BaseToggleActiveViewportStateCommand : Command
  {
    public enum Action
    {
      Toggle,
      Enable,
      Disable
    }
    public abstract bool ToggleStateFunction(RealtimeDisplayMode dm, Action action);
    public LocalizeStringPair ToggleString { get; } = new LocalizeStringPair("Toggle", Localization.LocalizeString("Toggle", 658));
    public abstract LocalizeStringPair EnableString { get; }
    public abstract LocalizeStringPair DisableString { get; }

    protected override Result RunCommand(RhinoDoc doc, RunMode mode)
    {
      RealtimeDisplayMode vp = doc.Views.ActiveView.RealtimeDisplayMode;
      if (vp != null)
      {
        GetOption gopt = new GetOption();
        int disableIdx = gopt.AddOption(DisableString);
        int enableIdx = gopt.AddOption(EnableString);
        int toggleIdx = gopt.AddOption(ToggleString);
        gopt.AcceptNothing(true);
        gopt.EnableTransparentCommands(false);
        gopt.SetCommandPrompt(Localization.LocalizeString("Action", 1183));

        _ = gopt.Get();

        Result rc = gopt.CommandResult();
        Rhino.Input.GetResult goptResult = gopt.Result();

        // we either get an Option, or Nothing. For Nothing we will use the toggle action.
        if (rc == Result.Success && (goptResult == Rhino.Input.GetResult.Option || goptResult == Rhino.Input.GetResult.Nothing))
        {
          CommandLineOption clo = gopt.Option();

          // if we got Nothing clo will be null, so use toggleIdx as the default
          int getIndex = clo?.Index ?? toggleIdx;

          Action act = Action.Toggle;
          if (getIndex == enableIdx)
          {
            act = Action.Enable;
          }
          else if (getIndex == disableIdx)
          {
            act = Action.Disable;
          }

          if (ToggleStateFunction(vp, act))
          {
            return Result.Success;
          }
        }
      }
      else
      {
        RhinoApp.WriteLine(Localization.LocalizeString("Active view isn't in a realtime display mode", 1726));

      }
      return Result.Nothing;
    }
  }
  public class PauseActiveRealtimeViewport : BaseToggleActiveViewportStateCommand
  {
    public override string LocalName => LOC.COMMANDNAME("TogglePausedActiveRealtimeViewport");
    public override string EnglishName => "TogglePausedActiveRealtimeViewport";

    public override LocalizeStringPair DisableString { get; } = new LocalizeStringPair("Suspend", Localization.LocalizeString("Suspend", 1805));
    public override LocalizeStringPair EnableString { get; } = new LocalizeStringPair("Resume", Localization.LocalizeString("Resume", 1806));

    public override bool ToggleStateFunction(RealtimeDisplayMode dm, Action action)
    {
      if (dm != null)
      {
        switch (action)
        {
          case Action.Toggle:
            dm.Paused = !dm.Paused;
            break;
          case Action.Disable:
            dm.Paused = true;
            break;
          case Action.Enable:
            dm.Paused = false;
            break;
          default:
            break;
        }

        return true;
      }
      return false;
    }

  }
  public class LockActiveRealtimeViewport : BaseToggleActiveViewportStateCommand
  {
    public override string LocalName => LOC.COMMANDNAME("ToggleLockedActiveRealtimeViewport");
    public override string EnglishName => "ToggleLockedActiveRealtimeViewport";

    public override LocalizeStringPair DisableString { get; } = new LocalizeStringPair("Lock", Localization.LocalizeString("Lock", 1807));
    public override LocalizeStringPair EnableString { get; } = new LocalizeStringPair("Unlock", Localization.LocalizeString("Unlock", 1808));

    public override bool ToggleStateFunction(RealtimeDisplayMode dm, Action action)
    {
      if (dm != null)
      {
        switch (action)
        {
          case Action.Toggle:
            dm.Locked = !dm.Locked;
            break;
          case Action.Disable:
            dm.Locked = true;
            break;
          case Action.Enable:
            dm.Locked = false;
            break;
          default:
            break;
        }

        return true;
      }
      return false;
    }
  }
1 Like

Your code sample is way beyond my ability but something to strive for maybe :+1: . None the less I think I have all I need to complete my mini-project. Thanks!!
My learning is mostly from reference manuals and YouTube. I’m starting to see big knowledge gaps appearing which prompted me to consider a different study approach. It’s hard to find thorough study material. I find it’s either too simple, skips over important parts, emphasizes stuff you’d never use, or is far to advanced. I had a look on Amazon while writing this and see a couple new “step-by-step” books I might try out.

Thanks very much for your help!!