Navigation

    • Register
    • Login
    • Search
    1. Home
    2. alexandre.dj
    alexandre.dj

    alexandre.dj

    @alexandre.dj

    0
    Reputation
    5
    Posts
    1
    Profile views
    0
    Followers
    0
    Following
    Joined Last Online

    • Profile
    • More
      • Following
      • Followers
      • Topics
      • Posts
      • Best
      • Groups
    alexandre.dj Follow

    Best posts made by alexandre.dj

    This user does not have any upvoted posts yet.

    Latest posts made by alexandre.dj

    RE: Defer Modifying Menus to the Main Thread

    @ferdinand
    Just a quick update that using an event message to force update the view after creating the menus is working great.

    c4d.EventAdd(c4d.EVMSG_CHANGE)
    
    posted in Cinema 4D SDK •
    RE: Defer Modifying Menus to the Main Thread

    @alexandre-dj
    Here is my code. I created a BuildBufferedMenus class inheriting from threading.Thread and starting a counter running for 3 seconds.

    Everytime a C4DPL_BUILDMENU message is emitted, I reset the counter to 0.

    When the counter reaches 3 seconds, it builds the menus.

    However, as discussed, the c4d.gui.UpdateMenus() call in my exit() function updates the menus but does not update the view. I cannot see them until I change the layout (minimize the window, change layout, or the like).

    In my latest version, I added the menus_updated property flag to let the main thread know that my menus are built and that I need the layout to update. Hence my previous question about sending a message to the main thread or checking in any method occuring regularly that my menus need an update.

    class BuildBufferedMenus(threading.Thread):
        """ Build c4d menus introducing a delay to deal with multiple builds (R26) """
    
        def __init__(self, max_time=3):
            super().__init__()
            self.max_time = max_time
            self.current_time = 0
            self.is_running = False
            self._menus_updated = False
    
        def build_menus(self):
            """ Method called from the plugin message to start or reset the timer """
            # start timer if thread not running
            if not self.is_running:
                self.start()
            # reset timer if thread is running
            else:
                self.reset()
    
        def run(self):
            """ Timer loop """
            self.is_running = True
            while self.current_time < self.max_time:
                self.current_time += 1
                time.sleep(1)
            # reinit timer variables and exit thread at the end
            self.is_running = False
            self.current_time = 0
            self.exit()
    
        def reset(self):
            """ Reset Timer """
            self.current_time = 0
    
        def exit(self):
            """ Exit timer """
            enhanceMainMenu()  # adds my custom menus
            c4d.gui.UpdateMenus()
            self._menus_updated = True
    
        @property
        def menus_updated(self):
            return self._menus_updated
    
        @menus_updated.setter
        def menus_updated(self, value):
            if not isinstance(value, bool):
                raise ValueError(f'{value} should be of type bool (True or False)')
            self._menus_updated = value
    
    # create class instance
    buffered_menus = BuildBufferedMenus()
    
    def myPluginMessage(id, data):
        if id==c4d.C4DPL_BUILDMENU:
            buffered_menus.build_menus()
    
    posted in Cinema 4D SDK •
    RE: Defer Modifying Menus to the Main Thread

    Thank you Ferdinand and sorry about breaking the forum's rules. I will be more careful in the future and open a new ticket if needed.

    posted in Cinema 4D SDK •
    Defer Modifying Menus to the Main Thread

    @ferdinand Thanks again for your help.

    I managed to build our menus using a simple timer in the end, so it is waiting for the last c4d.C4DPL_BUILDMENU message before triggering the build.

    I am however using a separate thread for this, and I encounter the issue you are mentionning in your answer, that is my menus are built but not showing up, as I am calling c4d.gui.UpdateMenus() from that separate thread, whereas it needs to be called from the main thread.

    Is there a c4d method to send code to execute int he main thread? I can't find anything like this in the documentation. Or can I simply trigger a menu update (using a simple flag set to true when the side thread is done) from the main thread? There must be an Update() function somewhere that is run every few seconds?


    edit: forked from building-menus-with-c4dpl_buildmenu-in-s26 by @ferdinand due to being off topic.

    posted in Cinema 4D SDK •
    RE: Building menus with C4DPL_BUILDMENU in S26+

    Hello Ferdinant. I'm following up on this ticket that I opened last November.

    First of all thank you for your help. I am running some tests to make sure that our custom menus are built only once when starting R26. If possible, I would like to still use the C4DPL_BUILDMENU event and simply check if my menus already exist. I know all menus in C4D have their own id, so this should be an easy check.

    However, I encouter a first issue:
    When firing c4d.gui.GetMenuResource("M_EDITOR") to Get the whole menu of Cinema 4D (as you mention in your code here) I get a different address every time:

    >>> c4d.gui.GetMenuResource("M_EDITOR")
    <c4d.BaseContainer object at 0x000001B406C86580>
    >>> c4d.gui.GetMenuResource("M_EDITOR")
    <c4d.BaseContainer object at 0x000001B406CA6A40>
    >>> c4d.gui.GetMenuResource("M_EDITOR")
    <c4d.BaseContainer object at 0x000001B406C88C80>
    

    So when I use c4d.gui.SearchMenuResource(main_menu_ressource, my_custom_menu) to check if my custom menu is part of the main menu, this always return False, as the address of the main_menu object changes.

    Could you please enlighten me on this?

    posted in Cinema 4D SDK •