panda3d
panda3d copied to clipboard
DirectEntry: Enter Without Mouse-Over
Description
I would like to suggest that DirectEntry accept the input that activates its "command"-callback regardless of the position of the mouse, as long as the entry has focus.
(Right now DirectEntry requires that the mouse be hovering over the entry in order to activate its "command".)
Use Case
In short, I feel that DirectEntry's current behaviour in this is counter-intuitive, and runs counter to not-unreasonable behaviour.
To the former, my intuition is that, if I'm typing into an entry, it will similarly accept the key-press that activates its "command"-callback--it has focus, after all.
(And indeed, this tripped me up recently, as I recall--I thought that the command was failing in some way, not realising that the relevant DirectEntry was simply ignoring the prompt due to the mouse not hovering over it.)
To the latter, it seems to me that the presence of the mouse hovering over the entry may obscure a little of the text in the entry, and so it might make sense to move the mouse such that it is no longer over the entry. However, doing so then means that the DirectEntry will no longer respond to the prompt for its "command"--or that the user is required to either deal with the mouse being over the text, or carefully place the mouse at a location that's not problematic, but that's still over the entry...
Thus is seems to me that DirectEntry's current behaviour comes with some usability issues, and hence my suggestion that it be changed to be more liberal about the prompt for its "command"-callback.
(Right now DirectEntry requires that the mouse be hovering over the entry in order to activate its "command".)
No it doesn't. I create my text entry like this:
def text_entry_mode_stuff(self):
if self.text_entry == None:
#deactivate everything
self.event_handler.ignoreAll()
self.event_handler.accept("enter",self.text_entry_mode_stuff)
#create the entry
E=DirectEntry(pos=LVector3(0.5,0,0),scale=0.07,focus=1)
self.text_entry=E
else:
#get text
my_text=self.text_entry.get()
self.output_d["text entry text"]=my_text
#destroy my entry
self.text_entry.destroy()
self.text_entry=None
#rebind everything else.
self.bind_actions(self.last_key_action_dict)
bind_actions
and last_key_action_dict
contain my key bindings.
I think that function is readable but if you have questions go ahead and ask.
No it doesn't. I create my text entry like this: ...
But what you do in that snippet doesn't use the DirectEntry's "command"-callback at all. Indeed, it seems to intentionally circumvent it.
What I'm suggesting is that the default behaviour work whether the mouse is over the DirectEntry or not--much as typing into the entry already does.
[edit] Deleting a double-post that I somehow managed to create.
I just wanted to point out that you don't need to rely on that function. If you want to write a PR that fixes this behavior, go ahead, sounds like a good idea.
I just wanted to point out that you don't need to rely on that function.
I mean, that's fair, and I appreciate that.
Still, it is a bit of a long way around when I would hope for the (rather more convenient) default behaviour to do the job.
If you want to write a PR that fixes this behavior, go ahead, sounds like a good idea.
I might look into it, but I do have other projects already on my plate.
(Right now DirectEntry requires that the mouse be hovering over the entry in order to activate its "command".)
Does it, though? If I am typing into this entry, and hit enter without the mouse being over it, it seems to print just fine:
import direct.directbase.DirectStart
from direct.gui.DirectGui import *
def command(text):
print("Entered", text)
entry = DirectEntry(text = "", scale=.05, command=command, initialText="initial", focus=1)
base.run()
Does it, though? If I am typing into this entry, and hit enter without the mouse being over it, it seems to print just fine:
Hmm, you're quite right: In your test-program the entry works just as expected.
And yet, in my own program, it's quite otherwise...
Ah, I think that I've found it!
As mentioned in this forum thread, I have a custom system set up that allows me to have multiple modal dialogues. As part of this, I'm doing two things:
- Creating a DirectFrame to stand in for the default "fadeScreen",
- Perhaps of note, this DirectFrame has both "suppressKeys" and "suppressMouse" set, in order to prevent presses to UI-elements "below" the dialogue in question.
- Placing both the dialogue and the stand-in "fadeScreen" into a custom bin that uses the "fixed" sorting-mode.
It seems that this results in the stand-in "fadeScreen" suppressing the enter-command, even though the DirectEntry in question is binned above it--unless the mouse is over the DirectEntry, for some reason.
Setting the state of the dialogue to be "DGG.NORMAL" solves the problem... at least as within the bounds of the dialogue. If it strays outside the dialogue, the enter-command again doesn't work.
See this altered version of your example-program to demonstrate:
import direct.directbase.DirectStart
from direct.gui.DirectGui import *
from panda3d.core import CullBinManager
def command(text):
print("Entered", text)
CullBinManager.getGlobalPtr().addBin("mew", CullBinManager.BTFixed, 70)
dialogue = DirectDialog(frameSize = (-1, 1, -1, 1))
# Uncomment the line below to have the enter-command work
# within the bounds of the dialogue--but still not without
#dialogue["state"] = DGG.NORMAL
dialogue.setBin("mew", 100)
dialogue.hide()
fadeFrame = DirectFrame(
frameSize = (-10, 10, -10, 10),
suppressKeys = True,
suppressMouse = True,
state = DGG.NORMAL,
parent = dialogue,
frameColor = (0, 0, 0, 0.7)
)
fadeFrame.setBin("mew", 99)
# Note that the above frame has a lower sort-order
# than that of the dialogue
entry = DirectEntry(text = "", scale=.1, command=command, initialText="initial", focus=1, parent = dialogue, relief = DGG.SUNKEN)
btn = DirectButton(text = "mew", scale = 0.1, command = dialogue.show, pos = (0, 0, -0.75))
base.run()
So this can be closed?
Hmm... It's still unexpected behaviour, I feel, and may potentially lead to poor GUI-usability--if only in edge-cases such as the method that I was using to produce stacking modal dialogues. There is, as noted, as workaround--but it has its own limitations.
So, I'm not sure.