On 06/04/2014 at 11:24, xxxxxxxx wrote:
Thanks Niklas.
I never thought about using Restore() in the main GeDialog class like that.
-ScottA
On 06/04/2014 at 11:24, xxxxxxxx wrote:
Thanks Niklas.
I never thought about using Restore() in the main GeDialog class like that.
-ScottA
On 07/04/2014 at 09:29, xxxxxxxx wrote:
You're welcome, Scott.
You can also find the code at the GitHub py-cinema4sdk repository under gui/restore-sub-dialog.pyp!
Do also take a look at the respective readme file at gui/restore-sub-dialog.md.
Best,
-Niklas
On 07/04/2014 at 11:19, xxxxxxxx wrote:
Thanks for the help guys, however I still have a few problems. Using Kiklas' method I got the SubDialogs to behave correctly when I re-open them while they are open and the window becomes active. I still get a Plugin not found while restoring a layout, I think this reason is due to having more than one sub dialog.
here is the code:
def Restore(self, PLUGIN_ID, secref) :
if secref['subid'] == 1:
return self.sub_dialog1.Restore(PLUGIN_ID,secref)
elif secref['subid'] == 2:
return self.sub_dialog2.Restore(PLUGIN_ID,secref)
else:
return super(MainDialog, self).Restore(PLUGIN_ID,secref)
How do I correctly look for both subdialogs.
On 07/04/2014 at 11:26, xxxxxxxx wrote:
if id == 10017: # Get Render Time
self.sub_dialog2.Open(c4d.DLG_TYPE_ASYNC, defaulth=200, defaultw=300, subid = 2)
Oh wait, I think I just figured it out, This has to have the plugin ID as well correct?
On 07/04/2014 at 11:41, xxxxxxxx wrote:
No that did not work. Here is what my @properties look like
@property
def sub_dialog1(self) :
if not hasattr(self, '_sub_dialog1') :
self._sub_dialog1 = ColorDialog()
return self._sub_dialog1
@property
def sub_dialog2(self) :
if not hasattr(self, '_sub_dialog2') :
self._sub_dialog2 = RenderTimeDialog()
return self._sub_dialog2
On 07/04/2014 at 11:58, xxxxxxxx wrote:
Here is the code from your exaple made to have 2 sub dialogs: Same problem.
import c4d
PLUGIN_ID = 1000004 # Test ID
class MainDialog(c4d.gui.GeDialog) :
# Do not create the object on class-level, although it might
# be unimportant since you do not open multiple objects of your
# MainDialog, it is contradicting to have one instance of sub
# dialog for all instances of the main dialog.
# A property that creates the dialog on-demand is perfect for
# this purpose.
@property
def sub_dialog(self) :
if not hasattr(self, '_sub_dialog') :
self._sub_dialog = SubDialog()
return self._sub_dialog
@property
def sub_dialog2(self) :
if not hasattr(self, '_sub_dialog2') :
self._sub_dialog2 = SubDialog2()
return self._sub_dialog2
# c4d.gui.GeDialog
def CreateLayout(self) :
self.SetTitle('Main Dialog')
self.AddButton(1000, 0, name="Open Sub-Dialog")
return True
def Command(self, param, bc) :
if param == 1000:
self.sub_dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=1)
self.sub_dialog2.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=2)
return True
def Restore(self, pluginid, secref) :
# We override this method so we don't have to handle the sub-
# dialog from the CommandData plugin. THIS dialog is responsible
# for the sub-dialog, do not split such management throughout
# your program or it gets confusing.
if secref['subid'] == 1:
return self.sub_dialog.Restore(pluginid, secref)
elif secref['subid'] == 2:
return self.sub_dialog2.Restore(pluginid, secref)
else:
return super(MainDialog, self).Restore(pluginid, secref)
class SubDialog(c4d.gui.GeDialog) :
def CreateLayout(self) :
self.SetTitle('Sub-Dialog')
self.AddStaticText(1000, 0, name="This is the sub-dialog.")
return True
class SubDialog2(c4d.gui.GeDialog) :
def CreateLayout(self) :
self.SetTitle('Sub-Dialog2')
self.AddStaticText(1000, 0, name="This is the sub-dialog2.")
return True
class Command(c4d.plugins.CommandData) :
def Register(self) :
return c4d.plugins.RegisterCommandPlugin(
PLUGIN_ID, "Sub-Dialog Docking Test", 0, None, "", self)
@property
def dialog(self) :
if not hasattr(self, '_dialog') :
self._dialog = MainDialog()
return self._dialog
# c4d.plugins.CommandData
def Execute(self, doc) :
return self.dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID)
def RestoreLayout(self, secref) :
return self.dialog.Restore(PLUGIN_ID, secref)
if __name__ == '__main__':
Command().Register()
On 07/04/2014 at 13:45, xxxxxxxx wrote:
OK I got the example to work.
however I cannot get my plugin to work. could it be that my main window uses a .res file?
import c4d
PLUGIN_ID = 1000004 # Test ID
class MainDialog(c4d.gui.GeDialog) :
# Do not create the object on class-level, although it might
# be unimportant since you do not open multiple objects of your
# MainDialog, it is contradicting to have one instance of sub
# dialog for all instances of the main dialog.
# A property that creates the dialog on-demand is perfect for
# this purpose.
@property
def sub_dialog(self) :
if not hasattr(self, '_sub_dialog') :
self._sub_dialog = SubDialog()
return self._sub_dialog
@property
def sub_dialog2(self) :
if not hasattr(self, '_sub_dialog2') :
self._sub_dialog2 = SubDialog2()
return self._sub_dialog2
# c4d.gui.GeDialog
def CreateLayout(self) :
self.SetTitle('Main Dialog')
self.AddButton(1000, 0, name="Open Sub-Dialog")
return True
def Command(self, param, bc) :
if param == 1000:
self.sub_dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=1)
self.sub_dialog2.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=2)
return True
def Restore(self, pluginid, secref) :
# We override this method so we don't have to handle the sub-
# dialog from the CommandData plugin. THIS dialog is responsible
# for the sub-dialog, do not split such management throughout
# your program or it gets confusing.
if secref['subid'] == 1:
print "yes"
return self.sub_dialog.Restore(pluginid, secref)
if secref['subid'] == 2:
return self.sub_dialog2.Restore(pluginid, secref)
else:
return super(MainDialog, self).Restore(pluginid, secref)
class SubDialog(c4d.gui.GeDialog) :
def CreateLayout(self) :
self.SetTitle('Sub-Dialog')
self.AddStaticText(1000, 0, name="This is the sub-dialog.")
return True
class SubDialog2(c4d.gui.GeDialog) :
def CreateLayout(self) :
self.SetTitle('Sub-Dialog2')
self.AddStaticText(1000, 0, name="This is the sub-dialog2.")
return True
class Command(c4d.plugins.CommandData) :
def Register(self) :
return c4d.plugins.RegisterCommandPlugin(
PLUGIN_ID, "Sub-Dialog Docking Test", 0, None, "", self)
@property
def dialog(self) :
if not hasattr(self, '_dialog') :
self._dialog = MainDialog()
return self._dialog
# c4d.plugins.CommandData
def Execute(self, doc) :
return self.dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID)
def RestoreLayout(self, secref) :
return self.dialog.Restore(PLUGIN_ID, secref)
if __name__ == '__main__':
Command().Register()
On 08/04/2014 at 14:11, xxxxxxxx wrote:
I think the problem with my plugin has something to do with the main command class, the "RestoreLayout" does not get called at all. I added some print functions to see and nothing. However the example prints just fine. Here is my main command code:
class RenderBuddy(c4d.plugins.CommandData) :
@property
def RBdialog(self) :
if not hasattr(self, '_RBdialog') :
self._RBdialog = BuddyDialog()
return self._RBdialog
def Register(self) :
return c4d.plugins.RegisterCommandPlugin(PLUGIN_ID, "Render Buddy (Beta)",0, bmp, "", self)
def Execute(self, doc) :
return self.RBdialog.Open(c4d.DLG_TYPE_ASYNC,PLUGIN_ID)
def RestorLayout(self, secref) :
print "RB_Main"
return self.RBdialog.Restore(PLUGIN_ID, secref)
if __name__ == "__main__":
path, fn = os.path.split(__file__)
bmp = bitmaps.BaseBitmap()
bmp.InitWith(os.path.join(path, "res/icons/", "icon.tif"))
RenderBuddy().Register()
Everything seems to be right, but the RestoreLayout does not get called.
On 08/04/2014 at 14:14, xxxxxxxx wrote:
Figured it out! After typing it out above I realized RestoreLayout() was misspelled. Thank you guys for all the help!
*Edit there is a new problem the setup:
def Restore(self, pluginid, secref) :
if secref['subid'] == 1:
print "Color"
return self.RB_ColorDLG.Restore(pluginid,secref)
if secref['subid'] == 2:
print "Temp"
return self.RB_TempDLG.Restore(pluginid,secref)
else:
print "Main"
return super(BuddyDialog, self).Restore(pluginid,secref)
This causes cinema to crash. I will restore the layout but if you launch the sub dialog again everything locks up. This happens with the Example as well.
On 08/04/2014 at 16:01, xxxxxxxx wrote:
Hi Shawn, I can reproduce the problems you have described. The Example I posted worked though,
but funnily broke after a few more times testing it. I'll have to talk to a developer on this, I am pretty
sure this is a bug. Especially this message is
Traceback (most recent call last) :
File "'restore-sub-dialog.pyp'", line 57, in CreateLayout
SystemError: error return without exception set
Best,
-Niklas
On 08/04/2014 at 19:28, xxxxxxxx wrote:
It seems to work just fine for me. No errors or problems at all.
Maybe you're trying to do something different than I'm doing?
Here is a complete example that works fine for me in R13.
Save it as a .pyp file and put it in your plugins folder.
The main dialog has buttons to open two other dialogs. And a button that will change the checkbox gizmo in dilaog1.
All three dialogs can be docked into the UI and saved in a custom layout.
#This is an example of a GeDialog plugin that opens three dialogs
#It also allows all three dialogs to be docked and saved in a custom layout
import c4d, os
from c4d import gui, plugins, bitmaps
PLUGIN_ID = 1000004 #Testing ID
SUBDLG_ID1 = 1000005 #Testing ID
SUBDLG_ID2 = 1000006 #Testing ID
MAINDLG_BUTTON1_ID = 1000
MAINDLG_BUTTON2_ID = 1001
MAINDLG_BUTTON3_ID = 1002
SUBDLG_TEXT_ID = 1003
SUBDLG_CHKBOX_ID = 1004
SUBDLG_RESET_ID = 1005
############################
#The first sub dialog
class SubDialog1(c4d.gui.GeDialog) :
def CreateLayout(self) :
self.SetTitle('Sub-Dialog1')
self.GroupBeginInMenuLine()
self.AddCheckbox(SUBDLG_RESET_ID, c4d.BFH_RIGHT, 100, 20, name="Reset")
self.GroupEnd()
self.GroupBegin(0, c4d.BFH_SCALEFIT, 2, 0, "MyGroup")
self.GroupBorderSpace(5, 5, 5, 5)
self.GroupBorder(c4d.BORDER_BLACK)
self.AddStaticText(SUBDLG_TEXT_ID, c4d.BFH_LEFT, 200, 20, "This is the sub-dialog1")
self.AddCheckbox(SUBDLG_CHKBOX_ID, c4d.BFH_LEFT, 20, 20, "myChkbox")
self.GroupEnd()
return True
def Command(self, id, msg) :
if id == SUBDLG_RESET_ID:
self.SetBool(SUBDLG_CHKBOX_ID, False)
self.SetBool(SUBDLG_RESET_ID, False)
return True
############################
#The second sub dialog
class SubDialog2(c4d.gui.GeDialog) :
def CreateLayout(self) :
self.SetTitle('Sub-Dialog2')
self.GroupBeginInMenuLine()
self.AddCheckbox(SUBDLG_RESET_ID, c4d.BFH_RIGHT, 100, 20, name="Reset")
self.GroupEnd()
self.GroupBegin(0, c4d.BFH_SCALEFIT, 2, 0, "MyGroup")
self.GroupBorderSpace(5, 5, 5, 5)
self.GroupBorder(c4d.BORDER_BLACK)
self.AddStaticText(SUBDLG_TEXT_ID, c4d.BFH_LEFT, 200, 20, "This is the sub-dialog2")
self.AddCheckbox(SUBDLG_CHKBOX_ID, c4d.BFH_LEFT, 20, 20, "myChkbox")
self.GroupEnd()
return True
def Command(self, id, msg) :
if id == SUBDLG_RESET_ID:
self.SetBool(SUBDLG_CHKBOX_ID, False)
self.SetBool(SUBDLG_RESET_ID, False)
return True
############################
#The main dialog
class MainDialog(c4d.gui.GeDialog) :
sub_dialog1 = SubDialog1()
sub_dialog2 = SubDialog2()
def CreateLayout(self) :
self.SetTitle('Main Dialog')
self.AddButton(MAINDLG_BUTTON1_ID, 0, name="Open Sub-Dialog1")
self.AddButton(MAINDLG_BUTTON2_ID, 0, name="Open Sub-Dialog2")
self.AddButton(MAINDLG_BUTTON3_ID, 0, name="Change Sub-Dialog1")
return True
def Command(self, id, msg) :
if id == MAINDLG_BUTTON1_ID:
self.sub_dialog1.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=SUBDLG_ID1)
if id == MAINDLG_BUTTON2_ID:
self.sub_dialog2.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=SUBDLG_ID2)
if id == MAINDLG_BUTTON3_ID:
self.sub_dialog1.SetBool(SUBDLG_CHKBOX_ID, True)
return True
#Restore the subdialog and the main dialog in the layout
def Restore(self, pluginid, secref) :
if secref['subid'] == SUBDLG_ID1:
return self.sub_dialog1.Restore(pluginid, secref)
if secref['subid'] == SUBDLG_ID2:
return self.sub_dialog2.Restore(pluginid, secref)
else:
return super(MainDialog, self).Restore(pluginid, secref)
############################
#The Command Data section
class MainDialog_CD(c4d.plugins.CommandData) :
@property
def dialog(self) :
if not hasattr(self, '_dialog') :
self._dialog = MainDialog()
return self._dialog
def Execute(self, doc) :
return self.dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID)
def RestoreLayout(self, secref) :
return self.dialog.Restore(PLUGIN_ID, secref)
if __name__ == "__main__":
bmp = bitmaps.BaseBitmap()
dir, file = os.path.split(__file__)
fn = os.path.join(dir, "res", "icon.png")
bmp.InitWith(fn)
plugins.RegisterCommandPlugin(PLUGIN_ID, "Sub-Dialog Docking",0, bmp, "re-open", MainDialog_CD())
-ScottA