Change button size by registry

Hi,

I am looking to automate some things again and found a way to hide the side bar before starting rhino via registry. Is it also possible to change toolbar button size?

Thank you.

Jordy

@JohnM, is this something you can answer?

You can use the CRhinoUiFile class defined in RhinoSdkUiFile.h to show/hide the side bar and also to access the toolbar interface. Unfortunately there is not currently a SDK function for changing the toolbar button sizes but there is a test command you can use “TestSetRuiTabBitmapSize”.

@JohnM I am using RhinoCommon vb.NET I found a way to hide the sidebar with:

 My.Computer.Registry.SetValue _
            ("HKEY_CURRENT_USER\SOFTWARE\McNeel\Rhinoceros\5.0\Scheme: Default\Window Positions\Docking Windows\Dock bars\7491ffac-ebf2-4214-bf42-d3d1e4e0f0e1", "Visible", "0")
 My.Computer.Registry.SetValue _
            ("HKEY_CURRENT_USER\SOFTWARE\McNeel\Rhinoceros\5.0x64\Scheme: Default\Window Positions\Docking Windows\Dock bars\7491ffac-ebf2-4214-bf42-d3d1e4e0f0e1", "Visible", "0")

But I want to do the same with button size:

The command you have me only changes the panel icons.

Jordy,

Unfortunately Rhino Common does not currently expose methods to do these things. I’m a C# guy not much of a VB guy so I wrote you a C# RhinoCommon command sample that will toggle the toolbar button size between medium and large sizes. The command uses reflection to change a toolbars plug-in setting.

  [System.Runtime.InteropServices.Guid("f194bf2f-458b-481f-a185-695c20079c47")]
  [CommandStyle(Style.Hidden)]
  public class TestSetToolbarButtonSize : Command
  {
    public TestSetToolbarButtonSize()
    {
      // Rhino only creates one instance of each command class defined in a
      // plug-in, so it is safe to store a reference in a static property.
      Instance = this;
    }

    ///<summary>The only instance of this command.</summary>
    public static TestSetToolbarButtonSize Instance { get; private set; }

    ///<returns>The command name as it appears on the Rhino command line.</returns>
    public override string EnglishName
    {
      get { return "TestSetToolbarButtonSize"; }
    }

    internal enum ButtonSize
    {
      Small = 0,
      Normal = 1,
      Large = 2
    };

    protected override Result RunCommand(RhinoDoc doc, RunMode mode)
    {
      var plug_in = Rhino.PlugIns.PlugIn.Find(new Guid("dc297053-96c0-4883-a688-8326b4e024a8"));
      if (plug_in == null)
        return Result.Failure;
      var assembly = plug_in.GetType().Assembly;
      var type = assembly.GetType("Rhino.UI.Controls.RuiSettings", false);
      if (type == null)
        return Result.Failure;
      var property = type.GetProperty(
        "ToolBarBitmap",
        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
      if (property == null)
        return Result.Failure;
      var value = property.GetValue(null, null);
      if (value == null)
        return Result.Failure;
      switch ((int)value)
      {
        case (int)ButtonSize.Small:
        case (int)ButtonSize.Normal:
        case (int)ButtonSize.Large:
          break;
        default:
          return Result.Failure;
      }
      var size = (ButtonSize)value == ButtonSize.Normal ? ButtonSize.Large : ButtonSize.Normal;
      property.SetValue(null, size, null);
      return Result.Success;
    }
  }

The easiest way to show/hide the side bar is to call the RMA.UI.MRhinoDockBarManager.ShowDockBar method using the Rhino_DotNet.dll assembly. You can add a reference to this DLL to your project and call the function directly or use reflection to get the assembly and call the method. You would call the method like this to show the control bar:

RMA.UI.MRhinoDockBarManager.ShowDockBar(new Guid("{7491FFAC-EBF2-4214-BF42-D3D1E4E0F0E1}"), true, false);

This is a sample function that will toggle the state using reflection:

private static bool TestToggleSideBar()
{
  var assemblies = AppDomain.CurrentDomain.GetAssemblies();
  // Get the RhinoDotNet assembly
  Type type = null;
  foreach (var ass in assemblies)
  {
    if (ass.IsDynamic)
      continue;
    type = ass.GetType("RMA.UI.MRhinoDockBarManager", false);
    if (type != null)
      break;
  }
  if (type == null)
    return false;
  try
  {
    var visible_method = type.GetMethod("IsDockBarVisible", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
    if (visible_method == null)
      return false;
    // Sidebar Id
    var id = new Guid("{7491FFAC-EBF2-4214-BF42-D3D1E4E0F0E1}");
    // Get the current visibility state
    var visible = (bool)visible_method.Invoke(null, new object[] { id });
    var show_method = type.GetMethod("ShowDockBar", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
    if (show_method == null)
      return false;
    // Toggle the sidebar visibility
    show_method.Invoke(null, new object[] {id, !visible, false});
    return true;
  }
  catch
  {
    return false;
  }
}

I have attached a sample VB project with 2 test commands that demonstrate what you are trying to do.MyProject1.zip (13.2 KB)

@JohnM that is exactly what I was searching for. Thanks!
I need to restart rhino because else the buttons looks weird. Is there a way to “Redraw” The UI?

After command, before restart

After restart

You can call RMA.UI.MRhinoDockBarManager.RecalcLayout() in Rhino_dotNet to update the docked control bars. I did not test this but it should work:

Protected Function RecalulateLayout() As Boolean
  Dim assemblies = AppDomain.CurrentDomain.GetAssemblies()
  ' Get the RhinoDotNet assembly
  Dim type As Type = Nothing
  For Each ass In assemblies
    If ass.IsDynamic Then
      Continue For
    End If
    type = ass.[GetType]("RMA.UI.MRhinoDockBarManager", False)
    If type IsNot Nothing Then
      Exit For
    End If
  Next
  If type Is Nothing Then
    Return False
  End If
  Dim method = type.GetMethod("RecalcLayout", Reflection.BindingFlags.[Public] Or Reflection.BindingFlags.[Static])
  If method Is Nothing Then
    Return False
  End If
  method.Invoke(Nothing, Nothing)
  Return True
End Function

Thanks but it does not work :frowning:

But Rhino_dotNet will be gone in rhino 6?
Will these 3 functions be available in rhinoCommon for v6?

  • Turn SideBar on/off
  • Change Button Size Small/medium/large
  • RecalcLayout

P.S. How do I get this back to 1 button for left and right mouse button instead of each split in 2 buttons?

@JohnM Can you take one more look into this for me?
Can’t get the recalc to work :frowning:

Jordy,

Rhino_dotNet will be available for at least one more Rhino release however the functions you need are available directly in Rhino 6.0 as static functions in the RhinoWindows.Controls.DockBar class in the RhinoWindows assembly as:

  • RhinoWinows.Controls.DockBar.Show
  • RhinoWinows.Controls.DockBar.RecalcRhinoLayout

The toolbar trick should continue to work in V6.

I’m not sure why your button sizing requires you to restart Rhino, Did you add a reference to Rhino_DotNET to your project or are you using the reflection code I sent previously? If you are using reflection have you stepped into your code to make sure it is finding the correct assembly and method?

Yes it finds everthing in the code and I have tried to import Rhino_dotNET

Protected Function RecalulateLayout() As Boolean
  Dim assemblies = AppDomain.CurrentDomain.GetAssemblies()
  ' Get the RhinoDotNet assembly
  Dim type As Type = Nothing
  For Each ass In assemblies
    If ass.IsDynamic Then
      Continue For
    End If
    type = ass.[GetType]("RMA.UI.MRhinoDockBarManager", False)
    If type IsNot Nothing Then
      Exit For
    End If
  Next
  If type Is Nothing Then
    Return False
  End If
  Dim method = type.GetMethod("RecalcLayout", Reflection.BindingFlags.[Public] Or Reflection.BindingFlags.[Static])
  If method Is Nothing Then
    Return False
  End If
  method.Invoke(Nothing, Nothing)
  Return True
End Function

It goes past:

  If method Is Nothing Then
    Return False
  End If

but:

  method.Invoke(Nothing, Nothing)

seem to do nothing.