diff --git a/src/cg/03-ui-components.cg b/src/cg/03-ui-components.cg index 174d732..47286c2 100644 --- a/src/cg/03-ui-components.cg +++ b/src/cg/03-ui-components.cg @@ -210,7 +210,7 @@ textInput = config \ # | Key { key = k } \ { state = state, emit = [\ c.onKeyDown k ] } | _ \ { state = state, emit = [] }, - view = state \ + view = state emit \ textBeforeCursor = slice state.text 0 state.cursorPos; cursorX = ui.measureText textBeforeCursor; padding = 8; diff --git a/src/cg/05-palette.cg b/src/cg/05-palette.cg index 14ce888..c558ad9 100644 --- a/src/cg/05-palette.cg +++ b/src/cg/05-palette.cg @@ -99,7 +99,7 @@ palette = config \ | _ \ { state = state, emit = [] }) | _ \ { state = state, emit = [] }, - view = state \ + view = state emit \ ui.positioned { x = (config.viewport.width - windowWidth) / 2, y = (config.viewport.height - windowHeight) / 2, diff --git a/src/cg/06-inspector.cg b/src/cg/06-inspector.cg index f394147..6bda7ee 100644 --- a/src/cg/06-inspector.cg +++ b/src/cg/06-inspector.cg @@ -1,11 +1,4 @@ inspector = config \ - windowHeight = 400; - windowWidth = 600; - - source = getSource config.name; - sourceLines = split "\n" source; - lineHeight = 20; - val = eval config.name; _ = debug "val" val; @@ -13,36 +6,17 @@ inspector = config \ | Value v \ reflect v | _ \ reflect 0; - _ = debug "reflected" reflected; - - dialogPadding = 0; - textInputHeight = 40; - contentWidth = windowWidth - (dialogPadding * 2); - contentHeight = windowHeight - (dialogPadding * 2); ui.column { gap = 0, children = [ - # display source - scrollable { + # tree + tree { + value = reflected, + path = config.name, w = config.w, - 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 - # } + h = config.h - textInputHeight }, # definition bar diff --git a/src/cg/06-tree.cg b/src/cg/06-tree.cg index f097634..e0523a0 100644 --- a/src/cg/06-tree.cg +++ b/src/cg/06-tree.cg @@ -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 "" + | _ \ 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; indent = depth * 20; @@ -14,51 +42,76 @@ tree = config \ | FunctionValue _ \ Some "" | _ \ 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 | NumberValue n \ simple (show n) "#6cf" | StringValue n \ simple ("\"" & n & "\"") "#f6a" | ConstructorValue { tag = tag } \ simple tag "#fc6" | FunctionValue _ \ simple "" "#888" | RecordValue entries \ - ui.stateful { - key = "tree-" & config.path, - init = { collapsed = True }, - - update = state event \ event - | Clicked _ \ ( - _ = 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) - | Some label \ simple (entry.key & " = " & label) "#aaa" - | None \ ui.column { gap = 0, children = [ - simple entry.key "#aaa", - tree { value = entry.value, depth = depth + 1, path = config.path & "." & entry.key } - ]} - ) entries) - ] - } - } + ui.column { gap = 0, children = [ + header isExp ((show (len entries)) & " fields") "#888", + ...(isExp + | True \ [ui.clickable { + onClick = _ \ noOp, + child = ui.column { gap = 0, children = map (entry \ + (valueLabel entry.value) + | Some label \ simple (entry.key & " = " & label) "#aaa" + | None \ ui.column { gap = 0, children = [ + simple entry.key "#aaa", + treeNode { value = entry.value, depth = depth + 1, path = config.path & "." & entry.key, expanded = config.expanded, onToggle = config.onToggle } + ]} + ) entries } + }] + | False \ []) + ]} | ListValue items \ - ui.column { - gap = 0, - children = mapWithIndex (item i \ - (valueLabel item) - | Some label \ simple ((show i) & ": " & label) "#aaa" - | None \ ui.column { gap = 0, children = [ - simple (show i) "#aaa", - tree { value = item, depth = depth + 1 } - ]} - ) items - } + ui.column { gap = 0, children = [ + header isExp ((show (len items)) & " items") "#888", + ...(isExp + | True \ [ui.clickable { + onClick = _ \ noOp, + child = ui.column { gap = 0, children = mapWithIndex (item i \ + (valueLabel item) + | Some label \ simple ((show i) & " : " & label) "#aaa" + | None \ ui.column { gap = 0, children = [ + simple (show i) "#aaa", + treeNode { value = item, depth = depth + 1, path = config.path & "." & (show i), expanded = config.expanded, onToggle = config.onToggle } + ]} + ) items } + }] + | False \ []) + ]} | _ \ 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 } + } + }; diff --git a/src/cg/10-os.cg b/src/cg/10-os.cg index 5b0d70a..8a59700 100644 --- a/src/cg/10-os.cg +++ b/src/cg/10-os.cg @@ -137,7 +137,7 @@ os = | Focused \ { state = state, emit = [focusWindow config.index] } | ChildFocused \ { state = state, emit = [focusWindow config.index] } | _ \ { state = state, emit = [] }, - view = state \ renderWindow config.window config.isActive + view = state emit \ renderWindow config.window config.isActive }; renderWindows = _ \ @@ -203,7 +203,7 @@ os = { state = state, emit = [toggleMaximizeFocusedWindow 0] } | _ \ { state = state, emit = [] }, - view = state \ + view = state emit \ ui.stack { children = [ ui.rect { w = viewport.width, h = viewport.height, color = "#012" }, diff --git a/src/runtime-compiled.ts b/src/runtime-compiled.ts index d9c263d..de72d0b 100644 --- a/src/runtime-compiled.ts +++ b/src/runtime-compiled.ts @@ -92,7 +92,9 @@ export function runAppCompiled(canvas: HTMLCanvasElement, store: any) { 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 = { kind: 'clickable', child: viewResult, @@ -206,6 +208,11 @@ export function runAppCompiled(canvas: HTMLCanvasElement, store: any) { return; } + if (event._tag === 'ComponentEvent') { + handleComponentEvent(event._0, event._1); + return; + } + if (event._tag === 'NoOp') return; }