Last active
May 17, 2019 18:46
-
-
Save luce80/8a3e2b58046d9fbd9520413df3c4bead to your computer and use it in GitHub Desktop.
Red VID reactive script in 3 versions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Red [ | |
Title: "Red VID reactive script in 3 versions" | |
Author: "luce80 derived from Nenad Rakocevic" | |
File: %color-slider.red | |
Needs: 'View | |
License: "MIT" | |
Notes: { | |
Demo of chained reactive programming, moving the sliders changes text, field, progress and the box's color | |
which in turn, changes the bottom text font color. Also changing field changes slider that changes all | |
the rest ;) . | |
See at end of script for a nice comment. | |
} | |
] | |
to-color: function [r g b][ | |
color: 0.0.0 | |
if r [color/1: to integer! 256 * r] | |
if g [color/2: to integer! 256 * g] | |
if b [color/3: to integer! 256 * b] | |
color | |
] | |
to-text: function [val][form to integer! 0.5 + 255 * any [val 0]] | |
round-to: func [n scale] [n: 0.5 * scale + n n - mod n scale] | |
scale-to-01: func [value low up] [(min max low any [value 0.0] up) / (up - low)] | |
set-change: func [face [object!] path [word! path!] value] [if value <> get in face path [set in face path value do-actor face none 'change]] | |
clear-reactions ; not needed | |
view [ | |
title "Color slider reactive demo" | |
style label: text 40 right middle ;red | |
style component: text "0" 30 right bold | |
below | |
text "targets react to slider , slider reacts to field" bold font [size: 10] | |
R: slider | |
react [face/data: to-percent scale-to-01 field-num/data 0.0 500.0] | |
component | |
react [face/text: to-text R/data] | |
across | |
field-num: field "0.0" right | |
react [face/data: 500 * round-to to-float R/data 0.001] | |
label "0 - 500" return | |
below | |
progress | |
react [face/data: R/data] | |
box: base | |
react [face/color: to-color R/data 0 0] | |
text "The quick brown fox jumps over the lazy dog." font [size: 14] | |
react [face/font/color: box/color] | |
] | |
clear-reactions ; not needed | |
view [ | |
title "Color slider reactive demo" | |
style label: text 40 right middle ;red | |
style component: text "0" 30 right bold | |
below | |
text "slider propagates to targets, field propagates to slider" bold font [size: 10] | |
R: slider | |
[ | |
textcolor/data: to-text face/data | |
field-num/data: 500 * round-to to-float face/data 0.001 | |
prog/data: face/data | |
set-change box 'color to-color face/data 0 0 ; using set-change to propagate to chained face | |
; here I could have put also box and text-quick changes | |
] | |
textcolor: component | |
across | |
field-num: field "0.0" right ; I have to set default values | |
on-change [set-change R 'data to-percent scale-to-01 face/data 0.0 500.0] | |
label "0 - 500" return | |
below | |
prog: progress | |
box: base black ; I have to set default values | |
on-change [text-quick/font/color: face/color] | |
text-quick: text "The quick brown fox jumps over the lazy dog." font [size: 14] | |
] | |
clear-reactions ; not needed | |
scale-to: func [mn mx value [number!] "Must be in 0.0 - 1.0 range" /round scale [number!] /local dest-type prev-type] [ | |
value: min max 0.0 to float! value 1.0 | |
dest-type: type? mn | |
mn: make mn mn ; make a copy | |
prev-type: type? mn | |
mn: to-float mn | |
mx: make mx mx | |
mx: to-float mx | |
value: value * (mx - mn) + mn | |
if scale [ | |
prev-type: type? scale | |
; if scale < 1 [throw error!] | |
value: 0.5 * scale + value | |
value: value - mod value scale | |
] | |
value: to dest-type to prev-type value | |
] | |
sharing: make reactor! [slide: 0 color: 0.0.0] | |
view [ | |
; NOTE the absence of dereferentiations | |
title "Color slider reactive demo" | |
style label: text 40 right middle ;red | |
style component: text "0" 30 right bold | |
below | |
text "slider and field share data, targets react to shared data" bold font [size: 10] | |
slider [sharing/slide: to-float face/data] | |
react [face/data: scale-to 0% 100% sharing/slide] | |
component | |
react [face/text: scale-to/round "0" "255" sharing/slide 1] | |
across | |
field "0.0" right on-change [sharing/slide: face/data / 500] | |
react [face/data: scale-to/round 0.0 500.0 sharing/slide 0.1] | |
label "0 - 500" return | |
below | |
progress | |
react [face/data: scale-to 0% 100% sharing/slide] | |
base black | |
react [sharing/color: face/color: 1.0.0 * scale-to 0 255 sharing/slide] | |
text "The quick brown fox jumps over the lazy dog." font [size: 14] | |
react [face/font/color: sharing/color] | |
] | |
{ | |
Possible dialect for propagation: (possible name could be "entangle") | |
entangle R [ | |
textcolor out [to-text face/data] ; using "out" because a conversion is needed ; out [scale 0 255 round 1 integer! string!] sequence of converions face/data is implied | |
field-num out [...etc...] in [...etc...] ; using also "in" because reaction is bi-directional ; out [float! scale 0 500] | |
prog ; no need anything else because it is a 1:1 copy | |
box out [...etc...] then text-quick out [...etc...] ; using "then" because box is chained to text-quick | |
] | |
this block (or dialect) could be inside slider definition but also inside a dedicated "entangling" face. | |
A bit of smartness could be applied for simple cases to "automatically" do the necessary conversions like | |
converting number! to string! and vice-versa | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment