Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
Hello everyone~ I have a GeDialogwindow now. and i want to close it when my mouse click in anywhare. I can get the mouse click event in GeDialog.Message(), but it's just work inside of dialog. So i think maybe i need to get the global input event . But i can't find any method in SDK. How do i do that?
GeDialog
GeDialog.Message()
Hello @gheyret,
Thank you for reaching out to us. Yes, you can get the 'global' input event with c4d.gui.GetInputEvent, but the problems are that:
c4d.gui.GetInputEvent
c4d.BFM_LOSTFOCUS
Find below a solution which likely does what you want to do. I would also recommend opening the dialog as a popup dialog, so that users do not get confused as to why your dialog behaves differently than 'normal' dialogs.
Cheers, Ferdinand
The result:
The code:
"""Demonstrates how to close a dialog when it lost focus. This example can be run from the script manager. It will open a dialog that is being closed when the either clicks the 'Apply' button of the dialog, or clicks out of bounds of the dialog. """ import c4d class MouseDialog (c4d.gui.GeDialog): """ """ ID_BTN_APPLY: int = 1004 def CreateLayout(self) -> bool: """Called by Cinema 4D to populate the dialog with gadgets. """ self.GroupBegin(1000, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 1) self.GroupBorderSpace(5, 5, 5, 5) # Add three sliders. self.AddEditSlider(1001, c4d.BFH_SCALEFIT) self.AddEditSlider(1002, c4d.BFH_SCALEFIT) self.AddEditSlider(1003, c4d.BFH_SCALEFIT) # And the 'Apply' button. self.AddButton(self.ID_BTN_APPLY, c4d.BFH_SCALEFIT, name="Apply") self.GroupEnd() return super().CreateLayout() def Command(self, cid: int, msg: c4d.BaseContainer) -> bool: """Called by Cinema 4D on gadget interactions. """ # The apply button has been clicked - do some stuff and then close the dialog. if cid == self.ID_BTN_APPLY: self.Close() return super().Command(cid, msg) def Message(self, msg: c4d.BaseContainer, result: c4d.BaseContainer) -> int: """Called by Cinema 4D to convey events to dialog. """ # Once the dialog lost focus, close it. This will happen for example when the user clicks # out of bounds of the dialog. if msg.GetId() == c4d.BFM_LOSTFOCUS: # It might be tempting to attempt to poll the mouse device here, so that for example # the dialog is only being closed when it lost focus AND the left mouse button is being # pressed. This is unfortunately not possible, as the event queue seems to have already # been flushed at this point. This has nothing to do with opening the dialog in the # Script Manger or not, the same happens for a CommandData plugin. I also tried # BFM_ACTIVE_CHG and offloading the work to GeDialog.AskClose(), all to the same effect: # As soon as the dialog has lost focus, one looses the ability to poll for mouse events, # likely because the event queue has already been flushed at this point. self.Close() return super().Message(msg, result) # Hack to keep an async dialog alive in a Script Manger environment, please do not do this in a # production environment. dlg: MouseDialog = MouseDialog() def main() -> None: """Runs the example. """ # To not to confuse users, a dialog which closes itself once it lost focus, should be opened # as a popup dialog. This will result in a dialog without a title bar. I chose here the resizable # popup variant which has no title bar but a border. There is also the non-resizable popup # variant c4d.DLG_TYPE_ASYNC_POPUPEDIT which has no title bar and no border. dlg.Open(c4d.DLG_TYPE_ASYNC_POPUP_RESIZEABLE, defaultw=300) if __name__ == '__main__': main()
@ferdinand Wow~ Thank you so much bro