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)