@ferdinand Got it. Thanks you for the tips. Much appreciated
Latest posts made by noisyrender
-
RE: Marquee Selection of Items in GeUserArea
-
RE: Marquee Selection of Items in GeUserArea
Sorry about the confusion 🫠.
Being not very familiar to the API and doing this by reading example code i was wondering if there is a similar lasso selection in python to the c++
https://developers.maxon.net/docs/cpp/2025_2_0a/classcinema_1_1_lasso_selection.htmlI realise by now that i'm asking for feedback. Mes plus plates excuses.
️
-
Marquee Selection of Items in GeUserArea
Hi everyone,
I'm currently working on a custom UI using GeUserArea in Python, and I'd like to implement rectangle selection (by clicking and dragging a selection rectangle over multiple items, similar to how it works in the Object Manager ). A good example is the Xpresso Editor or Kengo Ito's XBarista
I saw a similar function in the C++ doc and i'm wondering if it is possible in python out the box.
I'm fairly new to the api.Here is a snippet for a larger project.
THANK YOU
import c4d NODE_COLOR = c4d.Vector(c4d.COLOR_MENU_BG_SELECTED) class Node: def __init__(self, x, y, ua): self.x: int = x self.y: int = y self.width: int = 80 self.height: int = 80 self.is_selected: bool = False self.col: c4d.Vector = c4d.Vector(0.6, 0.3, 0.5) self.is_selected_col: c4d.Vector = c4d.Vector() self.ua = ua def draw_node(self): if self.is_selected: self.ua.DrawSetPen(NODE_COLOR) # node color when selected else: self.ua.DrawSetPen(self.col) # else the defaault color x1, y1 = self.x, self.y x2, y2 = self.x + self.width, self.y + self.height self.ua.DrawRectangle(int(x1), int(y1), int(x2), int(y2)) def offset(self, x, y): self.x -= x self.y -= y def select(self): self.is_selected = True def deselect(self): self.is_selected = False def is_inside(self, mx, my): # calculate the area of the node return ( self.x <= mx <= self.x + self.width and self.y <= my <= self.y + self.height ) class Gui(c4d.gui.GeDialog): ID_AREA = 10001 def __init__(self): super().__init__() self.SetTitle("Marquee Selection Example") self.area = Area() def CreateLayout(self): self.AddUserArea(self.ID_AREA, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT) self.AttachUserArea(self.area, self.ID_AREA) return True class Area(c4d.gui.GeUserArea): def __init__(self): self.nodes = [ Node(250, 250, self), Node(250, 150, self), ] # the two nodes to marque select self.lasso = False # start drawing the maarque when true # This create the actual custom marquee to draw def drawLasso(self, start_x, start_y, end_x, end_y): self.DrawSetPen(c4d.Vector(0.8, 0.8, 0.18)) self.DrawFrame(start_x, start_y, end_x, end_y, 1, c4d.LINESTYLE_NORMAL) def DrawMsg(self, x1, y1, x2, y2, msg): self.OffScreenOn() self.DrawSetPen(c4d.Vector(0.12, 0.12, 0.14)) self.DrawRectangle(x1, y1, x2, y2) for node in self.nodes: # draw all nodes node.draw_node() if self.lasso: self.drawLasso( self.lasso_start_x, self.lasso_start_y, self.lasso_end_x, self.lasso_end_y, ) def InputEvent(self, msg): # noqa: C901 if msg[c4d.BFM_INPUT_DEVICE] == c4d.BFM_INPUT_MOUSE: mx = int(msg[c4d.BFM_INPUT_X]) my = int(msg[c4d.BFM_INPUT_Y]) mx -= self.Local2Global()["x"] my -= self.Local2Global()["y"] channel = msg[c4d.BFM_INPUT_CHANNEL] self.lasso_start_x = int( mx ) # Mouse positions at the moment we start drawing self.lasso_start_y = int(my) if channel == c4d.BFM_INPUT_MOUSELEFT: self.MouseDragStart( c4d.BFM_INPUT_MOUSELEFT, mx, my, c4d.MOUSEDRAGFLAGS_DONTHIDEMOUSE, ) while True: res, dx, dy, channels = self.MouseDrag() if res == c4d.MOUSEDRAGRESULT_FINISHED: self.lasso = False self.Redraw() break # We always need this to escape an infinite loop elif res == c4d.MOUSEDRAGRESULT_ESCAPE: break elif res == c4d.MOUSEDRAGRESULT_CONTINUE: self.lasso = True c4d.gui.SetMousePointer(c4d.MOUSE_PAINTSELECTRECT) mx -= dx my -= dy self.lasso_end_x = int(mx) # Mouse positions when stopped self.lasso_end_y = int(my) self.Redraw() self.MouseDragEnd() for node in self.nodes: if node.is_inside(mx, my): node.select() self.Redraw() elif not node.is_inside(mx, my) and c4d.BFM_INPUT_MOUSELEFT: node.deselect() self.Redraw() return True if __name__ == "__main__": Gui().Open(2, 1, xpos=-2, ypos=-2, defaulth=600, defaultw=600)