API for new behavior of opnening Windows in Layout
-
Hello,
Is there an Python API already for the new behaviour of some Commands like the Assetbrowser where the Window does open in the Layout not as a floating Window? I would like this for some of my Scripts. -
Hello @holgerbiebrach,
thank you for reaching out to us. Please excuse the delay, I have not had the time to pick up your topic yet. There is at least no direct route solution to this like just a registration symbol for
GeDialog
(at least I see none). I will have to unpack on Monday if all the required interfaces for doing this are public (the likely answer from a first glance is no, but I will have to dig a bit deeper to know for sure).Cheers,
Ferdinand -
Hello @holgerbiebrach,
please excuse the wait. So, this is possible in Python and quite easy to do. This new behavior is just the old dialog folding which has been reworked a little bit. I have provided a simple example at the end of the posting. There is one problem regarding title bars which is sort of an obstacle for plugin developers which want to distribute their plugins, it is explained in the example below.
I hope this helps and cheers,
FerdinandThe result:
The code:"""Example for a command plugin with a foldable dialog as provided with the Asset Browser or Coordinate Manger in Cinema 4D R25. The core of this is just the old GeDialog folding mechanic which has been changed slightly with R25 as it will now also hide the title bar of a folded dialog, i.e., the dialog will be hidden completely. The structure shown here mimics relatively closely what the Coordinate Manger does. There is however one caveat: Even our internal implementations do not hide the title bar of a dialog when unfolded. Instead, this is done via layouts, i.e., by clicking onto the ≡ icon of the dialog and unchecking the "Show Window Title" option and then saving such layout. If you would want to provide a plugin which exactly mimics one of the folding managers, you would have to either ask your users to take these steps or provide a layout. Which is not ideal, but I currently do not see a sane way to hide the title bar of a dialog. What you could do, is open the dialog as an async popup which would hide the title bar. But that would also remove the ability to dock the dialog. You could then invoke `GeDialog.AddGadegt(c4d.DIALOG_PIN, SOME_ID)`to manually add a pin back to your dialog, so that you can dock it. But that is not how it is done internally by us, as we simply rely on layouts for that. """ import c4d class ExampleDialog (c4d.gui.GeDialog): """Example dialog that does nothing. The dialog itself has nothing to do with the implementation of the folding. """ ID_GADGETS_START = 1000 ID_GADGET_GROUP = 0 ID_GADGET_LABEL = 1 ID_GADGET_TEXT = 2 GADGET_STRIDE = 10 GADEGT_COUNT = 5 def CreateLayout(self) -> bool: """Creates dummy gadgets. """ self.SetTitle("ExampleDialog") flags = c4d.BFH_SCALEFIT for i in range(self.GADEGT_COUNT): gid = self.ID_GADGETS_START + i * self.GADGET_STRIDE name = f"Item {i}" self.GroupBegin(gid + self.ID_GADGET_GROUP, flags, cols=2) self.GroupBorderSpace(5, 5, 5, 5) self.GroupSpace(2, 2) self.AddStaticText(gid + self.ID_GADGET_LABEL, flags, name=name) self.AddEditText(gid + self.ID_GADGET_TEXT, flags) self.GroupEnd() return True class FoldingManagerCommand (c4d.plugins.CommandData): """Provides the implementation for a command with a foldable dialog. """ ID_PLUGIN = 1058525 REF_DIALOG = None @property def Dialog(self) -> ExampleDialog: """Returns a class bound ExampleDialog instance. """ if FoldingManagerCommand.REF_DIALOG is None: FoldingManagerCommand.REF_DIALOG = ExampleDialog() return FoldingManagerCommand.REF_DIALOG def Execute(self, doc: c4d.documents.BaseDocument) -> bool: """Folds or unfolds the dialog. The core of the folding logic as employed by the Asset Browser or the Coordinate manager in R25. """ # Get the class bound dialog reference. dlg = self.Dialog # Fold the dialog, i.e., hide it if it is open and unfolded. In C++ # you would also want to test for the dialog being visible with # GeDialog::IsVisible, but we cannot do that in Python. if dlg.IsOpen() and not dlg.GetFolding(): dlg.SetFolding(True) # Open or unfold the dialog. The trick here is that calling # GeDialog::Open will also unfold the dialog. else: dlg.Open(c4d.DLG_TYPE_ASYNC, FoldingManagerCommand.ID_PLUGIN) return True def RestoreLayout(self, secret: any) -> bool: """Restores the dialog on layout changes. """ return self.Dialog.Restore(FoldingManagerCommand.ID_PLUGIN, secret) def GetState(self, doc: c4d.documents.BaseDocument) -> int: """Sets the command icon state of the plugin. This is not required, but makes it a bit nicer, as it will indicate in the command icon when the dialog is folded and when not. """ dlg = self.Dialog result = c4d.CMD_ENABLED if dlg.IsOpen() and not dlg.GetFolding(): result |= c4d.CMD_VALUE return result def RegisterFoldingManagerCommand() -> bool: """Registers the example. """ return c4d.plugins.RegisterCommandPlugin( id=FoldingManagerCommand.ID_PLUGIN, str="FoldingManagerCommand", info=c4d.PLUGINFLAG_SMALLNODE, icon=None, help="FoldingManagerCommand", dat=FoldingManagerCommand()) if __name__ == '__main__': if not RegisterFoldingManagerCommand(): raise RuntimeError( f"Failed to register {FoldingManagerCommand} plugin.")
-
Thank you @ferdinand . This is awesome. Thanks for taking the time.
-
Hello @HolgerBiebrach,
we will set this topic to 'Solved' when there are no further questions or replies until Monday, November the 22th.
Thank you for your understanding,
Ferdinand -