Redraw UserArea while Dragging



  • On 02/04/2013 at 16:11, xxxxxxxx wrote:

    Hello everybody,

    i want my userarea to redraw while mousedragging, but I dont get it. Ive already managed to get into a dragging loop with updating mouse position. Ive found this ... >If one is designing a real element, for example a slider, one might also want to send regular messages to the parent dialog. These are sent with SendParentMessage() and appear as calls to Command() in the dialog, just as with any regular element:

    // Create an action message,   // with the user area's id:   var action = new(BaseContainer, BFM_ACTION);   action->SetData(BFM_ACTION_ID, GetId());      while(TRUE)   {     // Poll the mouse as above and draw the slider.        // Send a message to the parent dialog, so that     // it knows that the user is dragging the slider:     action->SetData(BFM_ACTION_INDRAG, TRUE);     SendParentMessage(action);   }      // Notify the dialog that the dragging is finished:   action->SetData(BFM_ACTION_INDRAG, FALSE);   SendParentMessage(action);

    ... but Im not able to translate to python.
    Can anyone help?

    My attempt:

    state = c4d.BaseContainer()  
    while self.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSELEFT, state) :  
      
          if state.GetLong(c4d.BFM_INPUT_VALUE)==0: break  
      
          mouse_x=state.GetLong(c4d.BFM_INPUT_X)  
          mouse_y=state.GetLong(c4d.BFM_INPUT_Y)  
      
          # Do Stuff  
      
          action = c4d.BaseContainer(c4d.BFM_ACTION)  
          action.SetLong(c4d.BFM_ACTION_ID, self.GetId())  
          action.SetLong(c4d.BFM_ACTION_INDRAG, True)  
          self.SendParentMessage(action)  
      
          self.Redraw()  
      
    action.SetLong(c4d.BFM_ACTION_INDRAG, False)  
    self.SendParentMessage(action)
    

    Greetings
    rown



  • On 03/04/2013 at 16:31, xxxxxxxx wrote:

    I did it ...

    import c4d  
    from c4d import bitmaps, gui, plugins, utils  
    import collections, os  
      
    PLUGIN_ID = 10000056 #TestID only!!!!!!!!!!!!  
      
      
    class Area(gui.GeUserArea) :  
      
      def DrawMsg(self, x1, y1, x2, y2, msg) :  
          state=c4d.BaseContainer()  
          action = c4d.BaseContainer(c4d.BFM_ACTION)  
          action.SetLong(c4d.BFM_ACTION_ID, self.GetId())  
      
          while self.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSELEFT, state) :  
            if state.GetLong(c4d.BFM_INPUT_VALUE)==0: break  
      
            x=state.GetLong(c4d.BFM_INPUT_X)  
            y=state.GetLong(c4d.BFM_INPUT_Y)  
      
            self.Draw(x,y)  
            action.SetLong(c4d.BFM_ACTION_INDRAG, True)  
            self.SendParentMessage(action)  
      
          action.SetLong(c4d.BFM_ACTION_INDRAG, False)  
          self.SendParentMessage(action)  
      
      def Draw(self, x, y) :  
          self.DrawSetPen(c4d.Vector(127.0/255))  
          self.DrawSetTextCol(c4d.Vector(255.0/255),c4d.Vector(0.0/255))  
      
          self.DrawRectangle(0,0,500,500)  
          self.DrawText("TEST", x, y-20, flags=c4d.DRAWTEXT_STD_ALIGN)  
      
          return True  
            
      def InputEvent(self, msg) :  
          self.Redraw()  
          return True  
      
    class MyDialog(gui.GeDialog) :  
      
      def __init__(self, area) :  
          self.area = area  
      
      def CreateLayout(self) :  
          self.SetTitle("Table")  
      
          self.AddUserArea(1000, c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT)  
          self.AttachUserArea(self.area, 1000)  
          self.GroupEnd()  
      
          return True  
      
      def Command(self, id, msg) :  
          print id  
          return True  
      
    class Test(plugins.CommandData) :  
        
      area = Area()  
      dialog = None  
      
      def Execute(self, doc) :  
          if self.dialog is None: self.dialog = MyDialog(self.area)  
          return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=500, defaulth=500)  
      def RestoreLayout(self, sec_ref) :  
          if self.dialog is None: self.dialog = MyDialog(self.area)  
          return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref)  
      
    if __name__ == "__main__":  
       bmp = bitmaps.BaseBitmap()  
       dir, f = os.path.split(__file__)  
       fn = os.path.join(dir, "res", "icon.tif")  
       bmp.InitWith(fn)  
       plugins.RegisterCommandPlugin(id=PLUGIN_ID,   
                                    str="Test01",  
                                    info=0,  
                                    help="Test01",   
                                    dat=Test(),  
                                    icon=bmp)
    

    Since I added Command() in GeDialog it works. But it doesnt work well. If I remove 'print id' from Command() it doesnt work. And if I use 'GeUserArea.OffScreenOn([ x , y , w , h ])' it doesnt work.



  • On 03/04/2013 at 18:59, xxxxxxxx wrote:

    I don't think we're allowed to use the overridden Draw() method with the user area.

    This is a different way to write your code:

    import c4d  
    from c4d import bitmaps, gui, plugins, utils  
    import collections, os  
      
    PLUGIN_ID = 10000010 #TestID only!!!!!!!!!!!!  
      
    class Area(gui.GeUserArea) :  
      
      def DrawMsg(self, x1, y1, x2, y2, msg) :   
      
          self.DrawSetPen(c4d.Vector(.2))                                  #Set the Background Color  
          self.DrawRectangle(x1, y1, x2, y2)                               #Draws the UA rectangle area  
            
          self.DrawSetPen(c4d.Vector(1,0,0))                               #Sets the color to red  
          self.DrawRectangle(80,80,100,100)                                #Draws a little rectangle in the UA  
            
          self.DrawSetTextCol(c4d.Vector(1,1,1), c4d.Vector(0,0,0))        #Sets the foreground & background color of the text  
          self.DrawText("Hello", 0, 0, flags=c4d.DRAWTEXT_STD_ALIGN)         #Draws the text at the coords 0x,0y  
            
      def InputEvent(self, msg) :  
       
          action = c4d.BaseContainer(c4d.BFM_ACTION)  
          action.SetLong(c4d.BFM_ACTION_ID, self.GetId())  
      
          while self.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSELEFT, msg) :    #While the left mouse button is held down  
            if msg.GetLong(c4d.BFM_INPUT_VALUE)==0: break  
      
            mx=msg.GetLong(c4d.BFM_INPUT_X)                         #Get the mouse coords.  
            my=msg.GetLong(c4d.BFM_INPUT_Y)   
            action.SetLong(c4d.BFM_ACTION_INDRAG, True)  
            self.SendParentMessage(action)                          #Sends a message to the parent dialog that the mouse is dragging in the UA  
            self.Redraw()                                           #Redraw while the left mouse button is held down  
      
          action.SetLong(c4d.BFM_ACTION_INDRAG, False)  
          self.SendParentMessage(action)                            #Sends a message to the parent dialog that the mouse has stopped dragging in the UA  
            
          return True  
            
      
    class MyDialog(gui.GeDialog) :  
      
      def __init__(self, area) :  
          self.area = area  
      
      def CreateLayout(self) :  
          self.SetTitle("My UserArea")  
      
          self.AddUserArea(1000, c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT)  
          self.AttachUserArea(self.area, 1000)  
          self.GroupEnd()  
      
          return True  
      
      def Command(self, id, msg) :  
          print id                     #Prints the ID of the UA  
          return True  
      
    class Test(plugins.CommandData) :  
        
      area = Area()  
      dialog = None  
      
      def Execute(self, doc) :  
          if self.dialog is None: self.dialog = MyDialog(self.area)  
          return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=500, defaulth=500)  
      def RestoreLayout(self, sec_ref) :  
          if self.dialog is None: self.dialog = MyDialog(self.area)  
          return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref)  
      
    if __name__ == "__main__":  
       bmp = bitmaps.BaseBitmap()  
       dir, f = os.path.split(__file__)  
       fn = os.path.join(dir, "res", "icon.tif")  
       bmp.InitWith(fn)  
       plugins.RegisterCommandPlugin(id=PLUGIN_ID,   
                                    str="Test01",  
                                    info=0,  
                                    help="Test01",   
                                    dat=Test(),  
                                    icon=bmp)
    

    -ScottA



  • On 03/04/2013 at 23:21, xxxxxxxx wrote:

    Scott, from what I see in your code, you are not moving the drawn content depending on the drag
    offset? I may be wrong and didn't find it, though. Anyway, there is no "Draw()" method in the
    GeUserArea class as far as I can tell.

    Best,
    -Niklas



  • On 04/04/2013 at 07:56, xxxxxxxx wrote:

    His code does not have anything that moves the drawn content either.
    I simply re-wrote his code in a more stable manner.
    But if that's a problem. Here's an example that lets the user drag the text around in the UA with the left mouse button:

    import c4d  
    from c4d import bitmaps, gui, plugins, utils  
    import collections, os  
      
    PLUGIN_ID = 10000010 #TestID only!!!!!!!!!!!!  
      
    class Area(gui.GeUserArea) :  
      
      xValue = 0  
      yValue = 0  
      
      def DrawMsg(self, x1, y1, x2, y2, msg) :   
      
          self.DrawSetPen(c4d.Vector(.2))                                  #Set the Background Color  
          self.DrawRectangle(x1, y1, x2, y2)                               #Draws the UA rectangle area  
            
          self.DrawSetPen(c4d.Vector(1,0,0))                               #Sets the color to red  
          self.DrawRectangle(80,80,100,100)                                #Draws a little rectangle in the UA  
            
          self.DrawSetTextCol(c4d.Vector(1,1,1), c4d.Vector(0,0,0))        #Sets the foreground & background color of the text  
          self.DrawText("Hello", self.xValue, self.yValue, flags=c4d.DRAWTEXT_STD_ALIGN)    #Draws the text at the current mouse coords  
            
      def InputEvent(self, msg) :  
       
          action = c4d.BaseContainer(c4d.BFM_ACTION)  
          action.SetLong(c4d.BFM_ACTION_ID, self.GetId())  
      
          while self.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSELEFT, msg) :    #While the left mouse button is held down  
            if msg.GetLong(c4d.BFM_INPUT_VALUE)==0: break  
      
            mouseX=msg.GetLong(c4d.BFM_INPUT_X)                     #Get the global mouse coords.  
            mouseY=msg.GetLong(c4d.BFM_INPUT_Y)  
            localPos = self.Global2Local()                          #Convert the mouse positions from global to local  
            mouseX += localPos['x']                                 #The mouse's local coords.  
            mouseY += localPos['y']  
           
            self.xValue = mouseX                                    #Class variables are set to same as mouse coords. so the DrawMsg() can use them  
            self.yValue = mouseY  
              
            action.SetLong(c4d.BFM_ACTION_INDRAG, True)  
            self.SendParentMessage(action)                          #Sends a message to the parent dialog that the mouse is dragging in the UA  
            self.Redraw()                                           #Redraw while the left mouse button is held down  
      
          action.SetLong(c4d.BFM_ACTION_INDRAG, False)  
          self.SendParentMessage(action)                            #Sends a message to the parent dialog that the mouse has stopped dragging in the UA  
            
          return True  
            
      
    class MyDialog(gui.GeDialog) :  
      
      def __init__(self, area) :  
          self.area = area  
      
      def CreateLayout(self) :  
          self.SetTitle("My UserArea")  
      
          self.AddUserArea(1000, c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT)  
          self.AttachUserArea(self.area, 1000)  
          self.GroupEnd()  
      
          return True  
      
      def Command(self, id, msg) :  
          print id                     #Prints the ID of the UA  
          return True  
      
    class Test(plugins.CommandData) :  
        
      area = Area()  
      dialog = None  
      
      def Execute(self, doc) :  
          if self.dialog is None: self.dialog = MyDialog(self.area)  
          return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=500, defaulth=500)  
      def RestoreLayout(self, sec_ref) :  
          if self.dialog is None: self.dialog = MyDialog(self.area)  
          return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref)  
      
    if __name__ == "__main__":  
       bmp = bitmaps.BaseBitmap()  
       dir, f = os.path.split(__file__)  
       fn = os.path.join(dir, "res", "icon.tif")  
       bmp.InitWith(fn)  
       plugins.RegisterCommandPlugin(id=PLUGIN_ID,   
                                    str="Test01",  
                                    info=0,  
                                    help="Test01",   
                                    dat=Test(),  
                                    icon=bmp)
    

    -ScottA



  • On 04/04/2013 at 08:53, xxxxxxxx wrote:

    Hey Scott,

    it wasnt a problem. I thank you very much. It helps alot!

    class Area(gui.GeUserArea) :  
      
      mx = 0  
      my = 0  
      
      def DrawMsg(self, x1, y1, x2, y2, msg) :   
          self.OffScreenOn(x1, y1, x2, y2)  
      
          self.DrawSetPen(c4d.Vector(.2))                                  #Set the Background Color  
          self.DrawRectangle(x1, y1, x2, y2)                               #Draws the UA rectangle area  
            
          self.DrawSetPen(c4d.Vector(1,0,0))                               #Sets the color to red  
          self.DrawRectangle(80,80,100,100)                                #Draws a little rectangle in the UA  
            
          self.DrawSetTextCol(c4d.Vector(1,1,1), c4d.Vector(0,0,0))        #Sets the foreground & background color of the text  
          self.DrawText("Hello", self.mx, self.my, flags=c4d.DRAWTEXT_STD_ALIGN)         #Draws the text at the coords 0x,0y  
            
      def InputEvent(self, msg) :  
          print "Input"  
       
          action = c4d.BaseContainer(c4d.BFM_ACTION)  
          action.SetLong(c4d.BFM_ACTION_ID, self.GetId())  
      
          while self.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSELEFT, msg) :    #While the left mouse button is held down  
            if msg.GetLong(c4d.BFM_INPUT_VALUE)==0: break  
      
            self.mx=msg.GetLong(c4d.BFM_INPUT_X)                         #Get the mouse coords.  
            self.my=msg.GetLong(c4d.BFM_INPUT_Y)   
            action.SetLong(c4d.BFM_ACTION_INDRAG, True)  
            self.SendParentMessage(action)                          #Sends a message to the parent dialog that the mouse is dragging in the UA  
            self.Redraw()                                           #Redraw while the left mouse button is held down  
      
          action.SetLong(c4d.BFM_ACTION_INDRAG, False)  
          self.SendParentMessage(action)                            #Sends a message to the parent dialog that the mouse has stopped dragging in the UA  
            
          return True  
      
      
    class MyDialog(gui.GeDialog) :  
      
      def __init__(self, area) :  
          self.area = area  
      
      def CreateLayout(self) :  
          self.SetTitle("Table")  
      
          self.AddUserArea(1000, c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT)  
          self.AttachUserArea(self.area, 1000)  
          self.GroupEnd()  
      
          return True  
      
      def Command(self, id, msg) :  
          return True
    

    Greetings
    rown



  • On 04/04/2013 at 08:54, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    His code does not have anything that moves the drawn content either.

    It actually does:

        def DrawMsg(self, x1, y1, x2, y2, msg) :
        
        
                state=c4d.BaseContainer()  
              action = c4d.BaseContainer(c4d.BFM_ACTION)  
              action.SetLong(c4d.BFM_ACTION_ID, self.GetId())  
          
              while self.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSELEFT, state) :  
                if state.GetLong(c4d.BFM_INPUT_VALUE)==0: break  
          
         **           x=state.GetLong(c4d.BFM_INPUT_X)  
                y=state.GetLong(c4d.BFM_INPUT_Y)  
          
                self.Draw(x,y)**  
                action.SetLong(c4d.BFM_ACTION_INDRAG, True)  
                self.SendParentMessage(action)  
          
              action.SetLong(c4d.BFM_ACTION_INDRAG, False)  
              self.SendParentMessage(action)
    

Log in to reply