Adding ability for stateful views to 'emit' events to their update functions. enhancing state tree viewer
This commit is contained in:
parent
69407cd25b
commit
6f217a0923
6 changed files with 111 additions and 77 deletions
|
|
@ -210,7 +210,7 @@ textInput = config \
|
||||||
# | Key { key = k } \ { state = state, emit = [\ c.onKeyDown k ] }
|
# | Key { key = k } \ { state = state, emit = [\ c.onKeyDown k ] }
|
||||||
| _ \ { state = state, emit = [] },
|
| _ \ { state = state, emit = [] },
|
||||||
|
|
||||||
view = state \
|
view = state emit \
|
||||||
textBeforeCursor = slice state.text 0 state.cursorPos;
|
textBeforeCursor = slice state.text 0 state.cursorPos;
|
||||||
cursorX = ui.measureText textBeforeCursor;
|
cursorX = ui.measureText textBeforeCursor;
|
||||||
padding = 8;
|
padding = 8;
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ palette = config \
|
||||||
| _ \ { state = state, emit = [] })
|
| _ \ { state = state, emit = [] })
|
||||||
| _ \ { state = state, emit = [] },
|
| _ \ { state = state, emit = [] },
|
||||||
|
|
||||||
view = state \
|
view = state emit \
|
||||||
ui.positioned {
|
ui.positioned {
|
||||||
x = (config.viewport.width - windowWidth) / 2,
|
x = (config.viewport.width - windowWidth) / 2,
|
||||||
y = (config.viewport.height - windowHeight) / 2,
|
y = (config.viewport.height - windowHeight) / 2,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,4 @@
|
||||||
inspector = config \
|
inspector = config \
|
||||||
windowHeight = 400;
|
|
||||||
windowWidth = 600;
|
|
||||||
|
|
||||||
source = getSource config.name;
|
|
||||||
sourceLines = split "\n" source;
|
|
||||||
lineHeight = 20;
|
|
||||||
|
|
||||||
val = eval config.name;
|
val = eval config.name;
|
||||||
_ = debug "val" val;
|
_ = debug "val" val;
|
||||||
|
|
||||||
|
|
@ -13,36 +6,17 @@ inspector = config \
|
||||||
| Value v \ reflect v
|
| Value v \ reflect v
|
||||||
| _ \ reflect 0;
|
| _ \ reflect 0;
|
||||||
|
|
||||||
_ = debug "reflected" reflected;
|
|
||||||
|
|
||||||
dialogPadding = 0;
|
|
||||||
|
|
||||||
textInputHeight = 40;
|
textInputHeight = 40;
|
||||||
contentWidth = windowWidth - (dialogPadding * 2);
|
|
||||||
contentHeight = windowHeight - (dialogPadding * 2);
|
|
||||||
|
|
||||||
ui.column {
|
ui.column {
|
||||||
gap = 0,
|
gap = 0,
|
||||||
children = [
|
children = [
|
||||||
# display source
|
# tree
|
||||||
scrollable {
|
tree {
|
||||||
|
value = reflected,
|
||||||
|
path = config.name,
|
||||||
w = config.w,
|
w = config.w,
|
||||||
h = config.h - textInputHeight,
|
h = config.h - textInputHeight
|
||||||
totalWidth = config.w,
|
|
||||||
# totalHeight = (len sourceLines) * lineHeight,
|
|
||||||
totalHeight = 1000,
|
|
||||||
onScroll = _ \ noOp,
|
|
||||||
child = tree { value = reflected, depth = 0, path = config.name },
|
|
||||||
# child = ui.column {
|
|
||||||
# gap = 0,
|
|
||||||
# children = map (line \
|
|
||||||
# ui.positioned {
|
|
||||||
# x = 8,
|
|
||||||
# y = 2,
|
|
||||||
# child = ui.text { content = line, color = "#ccc" }
|
|
||||||
# }
|
|
||||||
# ) sourceLines
|
|
||||||
# }
|
|
||||||
},
|
},
|
||||||
|
|
||||||
# definition bar
|
# definition bar
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,32 @@
|
||||||
tree = config \
|
treeNodeHeight = value path expanded \
|
||||||
|
lineH = 20;
|
||||||
|
valueLabel = v \ v
|
||||||
|
| NumberValue n \ Some n
|
||||||
|
| StringValue n \ Some n
|
||||||
|
| ConstructorValue { tag = tag } \ Some tag
|
||||||
|
| FunctionValue _ \ Some "<fn>"
|
||||||
|
| _ \ None;
|
||||||
|
|
||||||
|
value
|
||||||
|
| RecordValue entries \
|
||||||
|
(contains path expanded)
|
||||||
|
| True \ lineH + (sum (map (entry \
|
||||||
|
(valueLabel entry.value)
|
||||||
|
| Some _ \ lineH
|
||||||
|
| None \ lineH + (treeNodeHeight entry.value (path & "." & entry.key) expanded)
|
||||||
|
) entries))
|
||||||
|
| False \ lineH
|
||||||
|
| ListValue items \
|
||||||
|
(contains path expanded)
|
||||||
|
| True \ lineH + (sum (mapWithIndex (item i \
|
||||||
|
(valueLabel item)
|
||||||
|
| Some _ \ lineH
|
||||||
|
| None \ lineH + (treeNodeHeight item (path & "." & (show i)) expanded)
|
||||||
|
) items))
|
||||||
|
| False \ lineH
|
||||||
|
| _ \ lineH;
|
||||||
|
|
||||||
|
treeNode = config \
|
||||||
depth = config.depth;
|
depth = config.depth;
|
||||||
indent = depth * 20;
|
indent = depth * 20;
|
||||||
|
|
||||||
|
|
@ -14,51 +42,76 @@ tree = config \
|
||||||
| FunctionValue _ \ Some "<fn>"
|
| FunctionValue _ \ Some "<fn>"
|
||||||
| _ \ None;
|
| _ \ None;
|
||||||
|
|
||||||
|
header = isExp label color \
|
||||||
|
ui.clickable {
|
||||||
|
onClick = _ \ config.onToggle config.path,
|
||||||
|
child = simple ((isExp | True \ "▼ " | False \ "▶ ") & label) color
|
||||||
|
};
|
||||||
|
|
||||||
|
isExp = contains config.path config.expanded;
|
||||||
|
|
||||||
config.value
|
config.value
|
||||||
| NumberValue n \ simple (show n) "#6cf"
|
| NumberValue n \ simple (show n) "#6cf"
|
||||||
| StringValue n \ simple ("\"" & n & "\"") "#f6a"
|
| StringValue n \ simple ("\"" & n & "\"") "#f6a"
|
||||||
| ConstructorValue { tag = tag } \ simple tag "#fc6"
|
| ConstructorValue { tag = tag } \ simple tag "#fc6"
|
||||||
| FunctionValue _ \ simple "<fn>" "#888"
|
| FunctionValue _ \ simple "<fn>" "#888"
|
||||||
| RecordValue entries \
|
| RecordValue entries \
|
||||||
ui.stateful {
|
ui.column { gap = 0, children = [
|
||||||
key = "tree-" & config.path,
|
header isExp ((show (len entries)) & " fields") "#888",
|
||||||
init = { collapsed = True },
|
...(isExp
|
||||||
|
| True \ [ui.clickable {
|
||||||
update = state event \ event
|
onClick = _ \ noOp,
|
||||||
| Clicked _ \ (
|
child = ui.column { gap = 0, children = map (entry \
|
||||||
_ = debug "clicked on node" [];
|
|
||||||
{ state = state.{ collapsed = (not state.collapsed) }, emit = [] }
|
|
||||||
)
|
|
||||||
| _ \ { state = state, emit = [] },
|
|
||||||
|
|
||||||
view = state \
|
|
||||||
ui.column {
|
|
||||||
gap = 0,
|
|
||||||
children = [
|
|
||||||
simple ((state.collapsed | True \ "▶ " | False \ "▼ ") & (show (len entries)) & " fields") "#888",
|
|
||||||
...(state.collapsed
|
|
||||||
| True \ []
|
|
||||||
| False \ map (entry \
|
|
||||||
(valueLabel entry.value)
|
(valueLabel entry.value)
|
||||||
| Some label \ simple (entry.key & " = " & label) "#aaa"
|
| Some label \ simple (entry.key & " = " & label) "#aaa"
|
||||||
| None \ ui.column { gap = 0, children = [
|
| None \ ui.column { gap = 0, children = [
|
||||||
simple entry.key "#aaa",
|
simple entry.key "#aaa",
|
||||||
tree { value = entry.value, depth = depth + 1, path = config.path & "." & entry.key }
|
treeNode { value = entry.value, depth = depth + 1, path = config.path & "." & entry.key, expanded = config.expanded, onToggle = config.onToggle }
|
||||||
|
]}
|
||||||
|
) entries }
|
||||||
|
}]
|
||||||
|
| False \ [])
|
||||||
]}
|
]}
|
||||||
) entries)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
| ListValue items \
|
| ListValue items \
|
||||||
ui.column {
|
ui.column { gap = 0, children = [
|
||||||
gap = 0,
|
header isExp ((show (len items)) & " items") "#888",
|
||||||
children = mapWithIndex (item i \
|
...(isExp
|
||||||
|
| True \ [ui.clickable {
|
||||||
|
onClick = _ \ noOp,
|
||||||
|
child = ui.column { gap = 0, children = mapWithIndex (item i \
|
||||||
(valueLabel item)
|
(valueLabel item)
|
||||||
| Some label \ simple ((show i) & " : " & label) "#aaa"
|
| Some label \ simple ((show i) & " : " & label) "#aaa"
|
||||||
| None \ ui.column { gap = 0, children = [
|
| None \ ui.column { gap = 0, children = [
|
||||||
simple (show i) "#aaa",
|
simple (show i) "#aaa",
|
||||||
tree { value = item, depth = depth + 1 }
|
treeNode { value = item, depth = depth + 1, path = config.path & "." & (show i), expanded = config.expanded, onToggle = config.onToggle }
|
||||||
|
]}
|
||||||
|
) items }
|
||||||
|
}]
|
||||||
|
| False \ [])
|
||||||
]}
|
]}
|
||||||
) items
|
|
||||||
}
|
|
||||||
| _ \ ui.text { content = "?", color = "#666" };
|
| _ \ ui.text { content = "?", color = "#666" };
|
||||||
|
|
||||||
|
tree = config \
|
||||||
|
ui.stateful {
|
||||||
|
key = "tree-" & config.path,
|
||||||
|
init = { expanded = [] },
|
||||||
|
|
||||||
|
update = state event \ event
|
||||||
|
| Toggle path \ ((contains path state.expanded)
|
||||||
|
| True \ { state = state.{ expanded = filter (p \ p != path) state.expanded }, emit = [] }
|
||||||
|
| False \ { state = state.{ expanded = [path, ...state.expanded] }, emit = [] })
|
||||||
|
| _ \ { state = state, emit = [] },
|
||||||
|
|
||||||
|
view = state emit \
|
||||||
|
onToggle = path \ emit (Toggle path);
|
||||||
|
totalH = treeNodeHeight config.value config.path state.expanded;
|
||||||
|
|
||||||
|
scrollable {
|
||||||
|
w = config.w,
|
||||||
|
h = config.h,
|
||||||
|
totalWidth = config.w,
|
||||||
|
totalHeight = totalH,
|
||||||
|
onScroll = _ \ noOp,
|
||||||
|
child = treeNode { value = config.value, path = config.path, depth = 0, expanded = state.expanded, onToggle = onToggle }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ os =
|
||||||
| Focused \ { state = state, emit = [focusWindow config.index] }
|
| Focused \ { state = state, emit = [focusWindow config.index] }
|
||||||
| ChildFocused \ { state = state, emit = [focusWindow config.index] }
|
| ChildFocused \ { state = state, emit = [focusWindow config.index] }
|
||||||
| _ \ { state = state, emit = [] },
|
| _ \ { state = state, emit = [] },
|
||||||
view = state \ renderWindow config.window config.isActive
|
view = state emit \ renderWindow config.window config.isActive
|
||||||
};
|
};
|
||||||
|
|
||||||
renderWindows = _ \
|
renderWindows = _ \
|
||||||
|
|
@ -203,7 +203,7 @@ os =
|
||||||
{ state = state, emit = [toggleMaximizeFocusedWindow 0] }
|
{ state = state, emit = [toggleMaximizeFocusedWindow 0] }
|
||||||
| _ \ { state = state, emit = [] },
|
| _ \ { state = state, emit = [] },
|
||||||
|
|
||||||
view = state \
|
view = state emit \
|
||||||
ui.stack {
|
ui.stack {
|
||||||
children = [
|
children = [
|
||||||
ui.rect { w = viewport.width, h = viewport.height, color = "#012" },
|
ui.rect { w = viewport.width, h = viewport.height, color = "#012" },
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,9 @@ export function runAppCompiled(canvas: HTMLCanvasElement, store: any) {
|
||||||
setFocus(fullKey);
|
setFocus(fullKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
const viewResult = instance.view(instance.state);
|
const emit = (event: any) => ({ _tag: 'ComponentEvent', _0: fullKey, _1: event });
|
||||||
|
const viewResult = instance.view(instance.state)(emit);
|
||||||
|
|
||||||
const viewUI = {
|
const viewUI = {
|
||||||
kind: 'clickable',
|
kind: 'clickable',
|
||||||
child: viewResult,
|
child: viewResult,
|
||||||
|
|
@ -206,6 +208,11 @@ export function runAppCompiled(canvas: HTMLCanvasElement, store: any) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event._tag === 'ComponentEvent') {
|
||||||
|
handleComponentEvent(event._0, event._1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (event._tag === 'NoOp')
|
if (event._tag === 'NoOp')
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue