Cursor in gui element Show different text info
-
Hi,
i want to show text something when cursor in gui element.But I can only display some text when the mouse is stopped, I hope different GUI elements display different text. (For example, if there are different buttons in a window, when the mouse is stopped, the information of the current button will be displayed.)
BitmapButtonCustomimGui can achieve this effect. How can button gui achieve this effect?
example dialog:
my code:
def Message(self,msg,result): msg_id = msg.GetId() if msg_id == c4d.BFM_GETCURSORINFO: result.SetId(c4d.BFM_GETCURSORINFO) result.SetString(c4d.RESULT_BUBBLEHELP, "Show something") return c4d.gui.GeDialog.Message(self, msg, result)
Thanks for any Help!
-
Hello @chuanzhen,
Thank you for reaching out to us. I am not so sure what you are asking here for, but when I am reading a bit between the lines, I think the question is: "How to change the bubble help set by
BFM_GETCURSORINFO
in aGeDialog
depending on the currently hovered gadget?" Please feel free to correct me when I misunderstood you.In short, to display a different bubble help per element in a dialog, you must poll each element yourself.
BFM_GETCURSORINFO
is just a global mouse-move event, it carries no mouse-over information. Note that there are also some gadgets which have a builtin custom bubble help as for example edit fields orBitmapButtonCustomGui
as mentioned by yourself. The pattern shown here works for all gadgets.Cheers,
FerdinandCode:
"""Realizes a gadget dependent bubble help in a dialog for gadgets which do not support that on their own. This must be done by polling each gadget manually for a hit. """ import c4d class MyDialog (c4d.gui.GeDialog): """Realizes a dialog with two buttons, both with their own bubble help. """ def CreateLayout(self) -> bool: """Adds the two buttons to the dialog. """ self.GroupBorderSpace(5, 5, 5, 5) self.GroupSpace(5, 5) # Other than edit fields, buttons do not have a builtin bubble help. self.AddButton(1000, c4d.BFH_SCALEFIT, name = "Foo") self.AddButton(1001, c4d.BFH_SCALEFIT, name = "Bar") return True def Message(self, msg: c4d.BaseContainer, result: any) -> bool: """Realizes the context sensitive bubble help. """ # BFM_GETCURSORINFO is being sent independently of gadgets, all we get in #msg, is the # cursor position in global screen-space. A more modern and more aptly chosen name for this # message would be OnMouseMove, because that is all what it does. if msg.GetId() == c4d.BFM_GETCURSORINFO: # Then we have to poll each element in our dialog manually for (x, y) being a point # within their bounds with CheckDropArea (the methods are all not too well named here). for gid, bubbleMsg in ((1000, "Foo Help"), (1001, "Bar Help")): if self.CheckDropArea(gid, msg, True, True): result.SetId(c4d.BFM_GETCURSORINFO) result.SetString(c4d.RESULT_BUBBLEHELP, bubbleMsg) break return c4d.gui.GeDialog.Message(self, msg, result) if __name__ == "__main__": dlg = MyDialog() dlg.Open(c4d.DLG_TYPE_ASYNC, 0, -1, -1, 200, 200)
-
@ferdinand Thank you, this is exactly the effect I want because I couldn't find a method (GetDragPosition() and CheckDropArea()) to query whether the mouse position is on a gui element.
-
@ferdinand Your code works well, but I have another question to ask, why does open dialog in main() result in this effect(failed to create layout)
-
Hey @chuanzhen,
because
dlg
is then not a variable in the module scope anymore and destructed oncemain
is left, causing the problems you see. async dialogs are not supported in scripts, my code was just a quick hack to make it work.You must either use a modal dialog form, e.g.,
c4d.DLG_TYPE_MODAL
, or makedlg
a (global) variable in the module scope again. The latter is however a hack and not officially supported. You sort of have to know what you are doing when using async dialogs in scripts (and even then can run into problems).Cheers,
Ferdinand -
@ferdinand Thank you for your detailed reply!
-
@ferdinand When I change the size of the dialog, the code will have problems in this area.
Modifying this part of the code ensures that even if the dialog size changes, there will be no issues
if self.CheckDropArea(gid, msg, True, True): result.SetId(c4d.BFM_GETCURSORINFO) result.SetString(c4d.RESULT_BUBBLEHELP, bubbleMsg) break
-
Eh, you are right, these two arguments are
bool
, just read their name. Thank you for following up. I fixed my code above. You probably also can then drop the global-local conversion becauseGetDragPosition
does not change the values in themsg
container, I think.Cheers,
Ferdinandedit: yes, one can drop the conversion.
-
@ferdinand The code works very well