After all my implementation and changes I noticed that the Dialog used to show warnings and the KeyboardDialog I added to a screen, are not closing when the “back” remote key is pressed.
There is still only one “onKeyEvent” for the whole channel, located at the Scene brs script. I noticed that the “back” “press” event is never triggered at this function, indicating it was handled somewhere else before the scene, but the dialog is not closed. I also noticed that setting the “close” property to true, as described at the documentation, also is not closing the dialog.
I can’t figure out what I did that could have caused this, but I thing it is wrong behaviour, because the documentation says clearly that the “back” key always close dialogs.
i haven’t read that sample - are the “Dialog used to show warnings and the KeyboardDialog” part of it (then pls mention which file/component) or something you added? who has the input focus at that time, when they are up?
“RokuNB” wrote:
i haven’t read that sample - are the “Dialog used to show warnings and the KeyboardDialog” part of it (then pls mention which file/component) or something you added? who has the input focus at that time, when they are up?
The warning Dialog is part of it not the KeyboardDialog. But neither is behaving properly.
“marcelo.cabral” wrote:
Everything works as expected, except the back key that does not close the dialog.
And actually in the documentation there is no declared way to prevent pressing “back” from closing the dialog.
Your sentences - read together - are confusing. One complains Back does not close the dialog, the next says there is no way to prevent dialog from being closed…
Now, i know how to display a modal dialog in a scene and that is by setting scene’s dialog property, i.e.
myScene.dialog = myDialog
myScene.optionsDialog = true ' if you want `*` to also close it '
That’s all - from there on the scene will take care of displaying it modal and hold it on for dear life - that is, until Back button is pressed or say you set myScene.close = true …
So i think the magic ingredient is to let the scene handle it. If not, i assume dialogs behave as generic windows…
“marcelo.cabral” wrote:
Everything works as expected, except the back key that does not close the dialog.
And actually in the documentation there is no declared way to prevent pressing “back” from closing the dialog.
Your sentences - read together - are confusing. One complains Back does not close the dialog, the next says there is no way to prevent dialog from being closed…
Sorry for the confusion, what I meant with the second sentence was that even if I wanted to prevent the back button to close the Dialog, based on the documentation, there is not way to do it.
This was to emphasize that in my view it’s either a bug, or a missing information in the documentation.
“EnTerr” wrote:
Now, i know how to display a modal dialog in a scene and that is by setting scene’s dialog property, i.e.
myScene.dialog = myDialog
myScene.optionsDialog = true ' if you want `*` to also close it '
That’s all - from there on the scene will take care of displaying it modal and hold it on for dear life - that is, until Back button is pressed or say you set myScene.close = true …
So i think the magic ingredient is to let the scene handle it. If not, i assume dialogs behave as generic windows…
Hmmm, the documentation again does not make it clear that the dialog would only respond to a back if is assigned to the scene dialog property. And if it is supposed to act as a regular screen, in my scenario, then the “press” event for the “back” button should be generated at the only “onKeyEvent” of the channel, don’t you agree?
The problem is the example provided by Roku (that I based my implementation on) does not follow this “requirement”, by defining the Dialog named “WarningDialog” in the Screen xml. So I believe the documentation needs to be improved on Dialog node usage, and the fact it “swalows” the back key in some situations is a bug for me.
What you’re both saying aligns with my experience: A dialog isn’t a dialog unless you assign it to the Scene’s dialog field.
Once that’s been done, the Back button will be handled automatically by the dialog and close the dialog. You won’t get a keypress event for Back (in this case), which is consistent with what the documentation says.
The Roku example appears flawed. Surprise, surprise! At least it’s on GitHub, so you can submit an issue and/or pull request.
Another question: I want to show the dialog from a script that is in a screen brs not the scene brs, there is any way I can access the “parent” scene from there ?
The way I implemented was to pass the reference for the scene down to the screen using a field:
else if key = "options"
if m.DetailsScreen.visible = false
m.OptionsScreen.scene = m.top
m.OptionsScreen.visible = true
m.OptionsList.setFocus(true)
end if
“belltown” wrote:
Why do you need the parent’s m.top? Can’t you set the child’s m.top.dialog to the Dialog?
When I set to m.top.dialog at the child screen the dialog never showed, but this way setting in the child screen script it works:
m.top.scene.dialog = keyboardDlg
PS. Considering that I passed down the Scene node as the code in my previous post
I don’t see why setting m.top.dialog in the child component wouldn’t work. Are you setting this in one of the event-handlers in the child’s brs code? And is keyboardDlg set up correctly when assigning it to m.top.dialog in the child component?
“belltown” wrote:
I don’t see why setting m.top.dialog in the child component wouldn’t work. Are you setting this in one of the event-handlers in the child’s brs code? And is keyboardDlg set up correctly when assigning it to m.top.dialog in the child component?
Here is the full code, if I choose line tagged as Option 1 it works, if I switch to the option 2, nothing happens:
sub OnItemSelected()
m.index = m.top.itemSelected
if m.index = 0
print "about selected"
else if m.index < 3
print "open keyboard"
m.keyboardDlg = createObject("RoSGNode", "KeyboardDialog")
m.keyboardDlg.title = "Login"
m.keyboardDlg.text = " "
m.keyboardDlg.observeField("buttonSelected", "OnButtonSelected")
m.keyboardDlg.observeField("text", "OnTextChanged")
if m.index = 1
m.keyboardDlg.message = "Entre o e-mail do usuário:"
if m.global.user <> ""
m.keyboardDlg.text = m.global.user
else
m.keyboardDlg.text = "@email.com"
end if
m.keyboardDlg.keyboard.textEditBox.secureMode = false
else if m.index = 2
m.keyboardDlg.message = "Entre a senha do usuário:"
m.keyboardDlg.text = ""
m.keyboardDlg.keyboard.textEditBox.secureMode = true
end if
[OPTION 1] m.top.scene.dialog = m.keyboardDlg <========= Dialog is Shown
[OPTION 2] m.top.dialog = m.keyboardDlg <============= Nothing happens
else
m.infoLabel.text = ""
item = m.optionsList.content.getChild(2).getChild(m.index - 3)
if item.id <> m.global.maxRes
m.global.maxRes = item.id
LoadMenuItems()
m.optionsList.jumpToItem = m.index
end if
end if
end sub
I’m not really sure what’s going on. All I could come up with is that when OnItemSelected is called, if the component does not have focus, and therefore is not the “current Scene node” then setting that component’s dialog will have no effect because, “Setting the dialog field of the current Scene node to a Dialog node causes the dialog to be displayed”.
“belltown” wrote:
Why do you need the parent’s m.top? Can’t you set the child’s m.top.dialog to the Dialog?
Because not every component has a .dialog property.
Only Scene nodes have that property.
And since saw elsewhere we should use only one and only scene, that means there is only one such node per RSG.
His question is how can i find the scene from one of the children, nested levels down?
I suppose can just walk the tree up:
nxt = m.top
while nxt <> invalid:
scene = nxt
nxt = scene.getParent()
end while
' at this point `scene` is the top-most node `
“belltown” wrote:
Why do you need the parent’s m.top? Can’t you set the child’s m.top.dialog to the Dialog?
Because not every component has a .dialog property.
Only Scene nodes have that property.
And since saw elsewhere we should use only one and only scene, that means there is only one such node per RSG.
His question is how can i find the scene from one of the children, nested levels down?
I suppose can just walk the tree up:
nxt = m.top
while nxt <> invalid:
scene = nxt
nxt = scene.getParent()
end while
' at this point `scene` is the top-most node `
Thanks again EnTerr!
The ideal would be to have it available as the global, once all child screens should be able to open dialogs, but anyway I will keep my implementation.
“EnTerr” wrote:
Because not every component has a .dialog property.
Only Scene nodes have that property.
And since saw elsewhere we should use only one and only scene, that means there is only one such node per RSG.
I get it now. I was confusing components with Scenes. Yes, there’s only one Scene generally, so that’s where you need to set the dialog.
I hadn’t come across this issue myself because most of my dialogs are “custom” components, not real Dialog components, but they behave as modal dialogs. I show/hide them instead of setting scene.dialog. The only time I use actual Dialog components are in my main Scene, so m.top.dialog works.
So yes, EnTerr’s solution should get the Scene m.top, or just pass it in as a component interface field – or, since there’s only one Scene, set m.global.scene = m.top
According to the docs, the note above getRoots() states: The following methods can be called on any subject node and return the same global results. They can be used in a development channel for debugging purposes, but should not be used in a production channel. and then it goes on to say: Any calls to getAll(), getRoots(), getRootsMeta() and getAllMeta() should be removed from your production channels.
“belltown” wrote:
According to the docs, the note above getRoots() states: The following methods can be called on any subject node and return the same global results. They can be used in a development channel for debugging purposes, but should not be used in a production channel. and then it goes on to say: Any calls to getAll(), getRoots(), getRootsMeta() and getAllMeta() should be removed from your production channels.
The wisdom behind of that statement is not immediately apparent to me. It is possible that some of these functions are grossly inefficient (but ok for debug). It might be prudent then to use the previous idea of getParent() to the root.
“belltown” wrote:
According to the docs, the note above getRoots() states: The following methods can be called on any subject node and return the same global results. They can be used in a development channel for debugging purposes, but should not be used in a production channel. and then it goes on to say: Any calls to getAll(), getRoots(), getRootsMeta() and getAllMeta() should be removed from your production channels.
The wisdom behind of that statement is not immediately apparent to me. It is possible that some of these functions are grossly inefficient (but ok for debug). It might be prudent then to use the previous idea of getParent() to the root.
I’d be curious to know the wisdom as well. It did refer to these features as diagnostic tools in the Developer Blog post that announced their availability: https://blog.roku.com/developer/2016/06/21/roku-os-7-2-dev-highlights/. You wouldn’t normally use diagnostic (debugging?) tools in production code, but it doesn’t explain why these particular tools shouldn’t be used in production.