Detecting right clicks in Rebol - 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?

Related

Turn on/off mouseOver attribute in elm-ui

I am trying to make a simple game on Elm with elm-ui for my interest, but I stacked how to turn on/off mouseOver attribute.
I made a sample code for my explanation: https://ellie-app.com/9rvqJxz4ypga1
In this code, model has only two status (Myself|Opposite) which represent the turn of the game.
I would like to turn on changing background color of each tiles with mouseOver when model has the same status as the label of the tile.
viewTile is the main code which contains what I want to do.
viewTile : Player -> Model -> Element Msg
viewTile player model =
let
desc =
if player == Myself then
"Myself"
else
"Opposite"
changeMouseOver =
if player == model then
mouseOver [ Bg.color (rgba 1 0.2 0.3 0.5) ]
else
mouseOver []
in
column [ width (px 100), height (px 100), Border.width 1, changeMouseOver ] [ el [ centerX, centerY] ( text <| desc ) ]
For example, if model has "Myself" status, mouseOver will turn on only the tile labeled "Myself" .
In addition, "Change turn" button can change model like Myself <-> Opposite.
This trial showed good result if you clicked this button one time. However if you clicked again (means to recover model to Myself), mouseOver of "Myself" tile do not work.
I tried move the if code from let-in section to external, but it did not also work well.
How should I change the code to work turn on/off mouseOver?
This issue seems to be browser-specific one, I tried this code with Ellie in Safari 13.0.5. Firefox 78.0.2 works fine.

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.

Why does a button hide itself and another differently?

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]]

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]