Why does a button hide itself and another differently? - rebol

In the following Rebol 2 code, why does button a become visible 5 seconds after it's clicked, while remaining hidden 5 seconds after button b is clicked?
f: does [hide a wait 5]
view layout [
a: button "a" [f]
b: button "b" [f]
]

It looks like a bug that
view layout [
a: button "hide me" [ hide face ]
b: button "hide a" [ hide a ]
]
doesn't work to hide the "a" button unless the hide is called from another button. Your wait 5 must be triggering an update of the layout so that the button disappears.
Instead of wait 5, using do-events (wait []) keeps the button hidden.
view layout [
a: button "hide me" [ hide face do-events ]
b: button "hide a" [ hide a ]
]

When each button is clicked, it is redrawn to look “pressed”, and stays “pressed” until its action has completed. Then, after it's action has completed, the button is redrawn as “unpressed”.
During button a's action, it is hidden, but when its action is completed, it is shown again when it's “unpressed” state is drawn. According to this function summary of hide, hide only “temporarily removes the face from view”, and “The face will become visible again the next time the face is shown either directly or indirectly through one of its parent faces.”
During button b's action, button a is hidden, but when button b's action is completed, it is button b that is redrawn as “unpressed”. At this point, button a is untouched and remained hidden.
Considering Graham Chiu's code:
view layout [
a: button "hide me" [ hide face do-events ]
b: button "hide a" [ hide a ]
]
In this case, the reason why button a remains hidden after being clicked, is that its action doesn't reach completion until the window is closed. If wait 5 represents code which needs to be executed when the button is clicked, it needs to be put before do-events. Otherwise it is not executed until the window is closed.
view layout [
a: button "hide me and print" [
hide face
print "I need to say this when clicked."
do-events
print "I can wait until the window is closed."
]
b: button "hide a" [ hide a ]
]
Some other ways to make a button hide itself can be found on this page under the subheading: “Hiding self”. For example:
view l: layout [b: button [b/show?: false unview/all view l]]

Related

A way to detect a click anywhere but a specific control?

In my app the user can click on a div to highlight it. Is there a way to detect that they've clicked somewhere away from the div? I'd like to unhighlight selected things when this happens. I tried adding an onclick to the big div that contains everything else, but that doesn't really work as desired. IIRC the big div onclick always happens after the contained div onclick, so you can't ever select anything.
You can do this by adding a on "click" event to both the divs and then in the inner div, use onWithOptions to stop the propagation of the event. Here's some (untested) code:
onClickStop msg =
onWithOptions "click"
{ stopPropagation = True, preventDefault = False }
(Json.succeed msg)
view _ =
div [ onClick Clicked ]
[ div [ onClickStop NoOp ] []
]
When the user clicks inside the nested div, the event will be ignored and its propagation to its parent will be cancelled. Only when the user clicks outside the inner div will the Clicked message will be sent to update.

Why do I get error with show window in Rebol/Red?

When I click on button refresh, I get an error
v: [field1 "to refresh" field2 "to refresh"
button "refresh" [show v]]
view v
How can refresh v ?
Update: I don't have error but it doesn't refresh:
test: [
["a1" "b1"]
["a2" "b2"]
]
i: 1
v: layout compose [
field data test/:i/1 field data test/:i/2 button "refresh" [i: i + 1 show v]
]
view v
Show expects a face, not a block.
You want probably something along
v: layout [
f1: field "to refresh"
f2: field "to refresh"
button "refresh" [f1/text: f2/text show v ]
]
To see a change you should type something in the second input field before clicking on the button.
To make something (usefully) working with your update you can use
i: 1
sw: true
v: layout compose [
f1: field data test/:i/1
f2: field data test/:i/2
button "refresh" [
i: pick [1 2] sw: not sw
f1/text: test/:i/1
f2/text: test/:i/2
show v
]
]
show does not load the face definition block again, but the red-gui-system docs say
"Red/View will update both face and graphic objects in realtime as their properties are changed. This is the default behavior, but it can be switched off, when full control over screen updates is desirable. This is achieved by:
system/view/auto-sync?: off
When automatic syncing is turned off, you need to use show function on faces to get the graphic objects updated on screen."
I guess you can get something similar to your intention by destroying the old face object and building a new with the specification block.
test: [
["a1" "b1"]
["a2" "b2"]
]
i: 1
sw: true
vvw: layout v: [
field data test/:i/1
field data test/:i/2
button "refresh" [
i: pick [1 2] sw: not sw
unview vvw
view v
]
]
view vvw
Not sure what you mean by "refresh", but Red's GUI is reactive, you don't need to explicitly tell it to update.
If you just want to update the text data (increment its value) - here's a short working example:
view [f: field "42" button "increment" [f/data: f/data + 1]]
That is, f is assigned to the just created field. On button press - it receives new value, by acessing its data member.

Detecting right clicks in Rebol

view layout [
box red feel [
engage: func [face action event] [
if action = 'alt-down [print "alt down"] ; 1
if event/double-click [print "double-click"] ; 2
]
]
]
This code doesn't detect double right clicks.
When I quickly double click right button it will detect only 1 click (line 1).
I've tried detecting double-clicks but it doesn't work on right mouse button (line 2).
Is there a way to detect successive right mouse button clicks?

Getting the name of a button while the progress bar is going on in webdriver

I have one button named "Add" in my web portal. On clicking on that button a progress bar appears and the name of the button gets changed to "Adding" from "Add" and remains "Adding" until the progress bar is not moved to 100%. After the progress bar is 100% complete, again the text of Add button changes back to "Add" from "Adding".
I need to assert whether the name of the button is changing from "Add" to "Adding" or not during the progress bar movement. But the problem is once I click on the "Add" button, then use the assertion, selenium will first click on "Add" button, completes the progress bar to 100% and then tries to assertion, but now already the text of "Add" button is already changed back to "Add" from "Adding".
Please give the solution. Thanks in advance.
You can find the element, click and immediately return it's text which can be used later for Assert
public string Test()
{
IWebElement element = Driver.FindElement(By.CssSelector("Something"));
element.Click();
return element.Text;
}
Assert.IsTrue(Test().Contains("Adding"));
Note: C# code

How do you set initial focus in a layout?

rebol []
view [
f: field ""
button "focus" on-action [
focus f
]
when [load] on-action [focus f]
]
Using the focus button sets the focus correctly but I'd like the focus to set when the panel appears. I'd have thought the load trigger should do this but it doesn't.
The correct trigger to use is the 'enter trigger
when [enter] on-action [focus f]