|
|
|
@ -52,11 +52,13 @@ treeNode = config \
|
|
|
|
depth = config.depth;
|
|
|
|
depth = config.depth;
|
|
|
|
indent = depth * 20;
|
|
|
|
indent = depth * 20;
|
|
|
|
|
|
|
|
|
|
|
|
simple = path content color \
|
|
|
|
simple = path content color onClick \
|
|
|
|
selected = (config.selectedPath | Some p \ p == path | None \ False);
|
|
|
|
selected = (config.selectedPath | Some p \ p == path | None \ False);
|
|
|
|
ui.positioned { x = indent, y = 0,
|
|
|
|
inner = ui.text { content = content, color = (selected | True \ "white" | False \ color) };
|
|
|
|
child = ui.text { content = content, color = (selected | True \ "white" | False \ color) }
|
|
|
|
wrapped = (onClick
|
|
|
|
};
|
|
|
|
| Some handler \ ui.clickable { onClick = handler, child = inner }
|
|
|
|
|
|
|
|
| None \ inner);
|
|
|
|
|
|
|
|
ui.positioned { x = indent, y = 0, child = wrapped };
|
|
|
|
|
|
|
|
|
|
|
|
isEditing = config.editing | Some p \ p == config.path | None \ False;
|
|
|
|
isEditing = config.editing | Some p \ p == config.path | None \ False;
|
|
|
|
|
|
|
|
|
|
|
|
@ -68,10 +70,7 @@ treeNode = config \
|
|
|
|
| _ \ None;
|
|
|
|
| _ \ None;
|
|
|
|
|
|
|
|
|
|
|
|
header = isExp label color \
|
|
|
|
header = isExp label color \
|
|
|
|
ui.clickable {
|
|
|
|
simple config.path (config.prefix & (isExp | True \ "▼ " | False \ "▶ ") & label) color (Some (_ \ config.onToggle config.path));
|
|
|
|
onClick = _ \ config.onToggle config.path,
|
|
|
|
|
|
|
|
child = simple config.path (config.prefix & (isExp | True \ "▼ " | False \ "▶ ") & label) color
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
isExp = contains config.path config.expanded;
|
|
|
|
isExp = contains config.path config.expanded;
|
|
|
|
|
|
|
|
|
|
|
|
@ -92,7 +91,7 @@ treeNode = config \
|
|
|
|
h = 30,
|
|
|
|
h = 30,
|
|
|
|
onSubmit = onSubmit
|
|
|
|
onSubmit = onSubmit
|
|
|
|
}
|
|
|
|
}
|
|
|
|
| False \ simple config.path (config.prefix & (show n)) "#6cf")
|
|
|
|
| False \ simple config.path (config.prefix & (show n)) "#6cf" (Some (_ \ config.onEditLeaf config.path)))
|
|
|
|
|
|
|
|
|
|
|
|
| StringValue n \ (isEditing
|
|
|
|
| StringValue n \ (isEditing
|
|
|
|
| True \ textInput {
|
|
|
|
| True \ textInput {
|
|
|
|
@ -105,7 +104,7 @@ treeNode = config \
|
|
|
|
h = 30,
|
|
|
|
h = 30,
|
|
|
|
onSubmit = onSubmit
|
|
|
|
onSubmit = onSubmit
|
|
|
|
}
|
|
|
|
}
|
|
|
|
| False \ simple config.path (config.prefix & "\"" & n & "\"") "#f6a")
|
|
|
|
| False \ simple config.path (config.prefix & "\"" & n & "\"") "#f6a" (Some (_ \ config.onEditLeaf config.path)))
|
|
|
|
|
|
|
|
|
|
|
|
| ConstructorValue { tag = tag } \ (isEditing
|
|
|
|
| ConstructorValue { tag = tag } \ (isEditing
|
|
|
|
| True \ textInput {
|
|
|
|
| True \ textInput {
|
|
|
|
@ -118,9 +117,9 @@ treeNode = config \
|
|
|
|
h = 30,
|
|
|
|
h = 30,
|
|
|
|
onSubmit = onSubmit
|
|
|
|
onSubmit = onSubmit
|
|
|
|
}
|
|
|
|
}
|
|
|
|
| False \ simple config.path (config.prefix & tag) "#fc6")
|
|
|
|
| False \ simple config.path (config.prefix & tag) "#fc6" (Some (_ \ config.onEditLeaf config.path)))
|
|
|
|
|
|
|
|
|
|
|
|
| FunctionValue _ \ simple config.path (config.prefix & "<fn>") "#888"
|
|
|
|
| FunctionValue _ \ simple config.path (config.prefix & "<fn>") "#888" None
|
|
|
|
|
|
|
|
|
|
|
|
| RecordValue entries \
|
|
|
|
| RecordValue entries \
|
|
|
|
ui.column { gap = 0, children = [
|
|
|
|
ui.column { gap = 0, children = [
|
|
|
|
@ -130,7 +129,7 @@ treeNode = config \
|
|
|
|
onClick = _ \ noOp,
|
|
|
|
onClick = _ \ noOp,
|
|
|
|
child = ui.column { gap = 0, children = map (entry \
|
|
|
|
child = ui.column { gap = 0, children = map (entry \
|
|
|
|
pfx = (valueLabel entry.value) | Some _ \ " = " | None \ " ";
|
|
|
|
pfx = (valueLabel entry.value) | Some _ \ " = " | None \ " ";
|
|
|
|
treeNode { value = entry.value, depth = depth + 1, path = config.path & "." & entry.key, expanded = config.expanded, onToggle = config.onToggle, selectedPath = config.selectedPath, prefix = entry.key & pfx, editing = config.editing, onDoneEditing = config.onDoneEditing }
|
|
|
|
treeNode { value = entry.value, depth = depth + 1, path = config.path & "." & entry.key, expanded = config.expanded, onToggle = config.onToggle, selectedPath = config.selectedPath, prefix = entry.key & pfx, editing = config.editing, onDoneEditing = config.onDoneEditing, onEditLeaf = config.onEditLeaf }
|
|
|
|
) entries }
|
|
|
|
) entries }
|
|
|
|
}]
|
|
|
|
}]
|
|
|
|
| False \ [])
|
|
|
|
| False \ [])
|
|
|
|
@ -142,7 +141,7 @@ treeNode = config \
|
|
|
|
| True \ [ui.clickable {
|
|
|
|
| True \ [ui.clickable {
|
|
|
|
onClick = _ \ noOp,
|
|
|
|
onClick = _ \ noOp,
|
|
|
|
child = ui.column { gap = 0, children = mapWithIndex (item i \
|
|
|
|
child = ui.column { gap = 0, children = mapWithIndex (item i \
|
|
|
|
treeNode { value = item, depth = depth + 1, path = config.path & "." & (show i), expanded = config.expanded, onToggle = config.onToggle, selectedPath = config.selectedPath, prefix = (show i) & ": ", editing = config.editing, onDoneEditing = config.onDoneEditing }
|
|
|
|
treeNode { value = item, depth = depth + 1, path = config.path & "." & (show i), expanded = config.expanded, onToggle = config.onToggle, selectedPath = config.selectedPath, prefix = (show i) & ": ", editing = config.editing, onDoneEditing = config.onDoneEditing, onEditLeaf = config.onEditLeaf }
|
|
|
|
) items }
|
|
|
|
) items }
|
|
|
|
}]
|
|
|
|
}]
|
|
|
|
| False \ [])
|
|
|
|
| False \ [])
|
|
|
|
@ -150,6 +149,15 @@ treeNode = config \
|
|
|
|
| _ \ ui.text { content = "?", color = "#666" };
|
|
|
|
| _ \ ui.text { content = "?", color = "#666" };
|
|
|
|
|
|
|
|
|
|
|
|
tree = config \
|
|
|
|
tree = config \
|
|
|
|
|
|
|
|
downArrow = state \
|
|
|
|
|
|
|
|
paths = visiblePaths config.value config.path state.expanded;
|
|
|
|
|
|
|
|
newIndex = min (len paths - 1) (state.selectedIndex + 1);
|
|
|
|
|
|
|
|
{ state = state.{ selectedIndex = newIndex }, emit = [] };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
upArrow = state \
|
|
|
|
|
|
|
|
newIndex = max 0 (state.selectedIndex - 1);
|
|
|
|
|
|
|
|
{ state = state.{ selectedIndex = newIndex }, emit = [] };
|
|
|
|
|
|
|
|
|
|
|
|
ui.stateful {
|
|
|
|
ui.stateful {
|
|
|
|
focusable = True,
|
|
|
|
focusable = True,
|
|
|
|
autoFocus = True,
|
|
|
|
autoFocus = True,
|
|
|
|
@ -167,17 +175,10 @@ tree = config \
|
|
|
|
newY = max 0 (min (totalH - config.h) (state.scrollY + delta.deltaY));
|
|
|
|
newY = max 0 (min (totalH - config.h) (state.scrollY + delta.deltaY));
|
|
|
|
{ state = state.{ scrollY = newY }, emit = [] })
|
|
|
|
{ state = state.{ scrollY = newY }, emit = [] })
|
|
|
|
|
|
|
|
|
|
|
|
| Key { key = "ArrowDown" } \ (
|
|
|
|
| Key { key = "ArrowDown" } \ downArrow state
|
|
|
|
paths = visiblePaths config.value config.path state.expanded;
|
|
|
|
| Key { key = "j" } \ downArrow state
|
|
|
|
newIndex = min (len paths - 1) (state.selectedIndex + 1);
|
|
|
|
| Key { key = "ArrowUp" } \ upArrow state
|
|
|
|
_ = debug "newIndex" newIndex;
|
|
|
|
| Key { key = "k" } \ upArrow state
|
|
|
|
{ state = state.{ selectedIndex = newIndex }, emit = [] })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Key { key = "ArrowUp" } \ (
|
|
|
|
|
|
|
|
# paths = visiblePaths config.value config.path state.expanded;
|
|
|
|
|
|
|
|
newIndex = max 0 (state.selectedIndex - 1);
|
|
|
|
|
|
|
|
_ = debug "newIndex" newIndex;
|
|
|
|
|
|
|
|
{ state = state.{ selectedIndex = newIndex }, emit = [] })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Key { key = "Enter" } \ (
|
|
|
|
| Key { key = "Enter" } \ (
|
|
|
|
items = visiblePaths config.value config.path state.expanded;
|
|
|
|
items = visiblePaths config.value config.path state.expanded;
|
|
|
|
@ -194,12 +195,17 @@ tree = config \
|
|
|
|
|
|
|
|
|
|
|
|
| Key { key = "Escape" } \ { state = state.{ editing = None }, emit = [] }
|
|
|
|
| Key { key = "Escape" } \ { state = state.{ editing = None }, emit = [] }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| EditLeaf path \ { state = state.{ editing = Some path }, emit = [] }
|
|
|
|
|
|
|
|
|
|
|
|
| DoneEditing \ { state = state.{ editing = None }, emit = [] }
|
|
|
|
| DoneEditing \ { state = state.{ editing = None }, emit = [] }
|
|
|
|
|
|
|
|
|
|
|
|
| _ \ { state = state, emit = [] },
|
|
|
|
| _ \ { state = state, emit = [] },
|
|
|
|
|
|
|
|
|
|
|
|
view = state emit \
|
|
|
|
view = state emit \
|
|
|
|
onToggle = path \ emit (Toggle path);
|
|
|
|
onToggle = path \ emit (Toggle path);
|
|
|
|
|
|
|
|
onEditLeaf = path \
|
|
|
|
|
|
|
|
_ = debug "onEditLeaf" path;
|
|
|
|
|
|
|
|
emit (EditLeaf path);
|
|
|
|
onDoneEditing = _ \ emit DoneEditing;
|
|
|
|
onDoneEditing = _ \ emit DoneEditing;
|
|
|
|
totalH = treeNodeHeight config.value config.path state.expanded;
|
|
|
|
totalH = treeNodeHeight config.value config.path state.expanded;
|
|
|
|
paths = visiblePaths config.value config.path state.expanded;
|
|
|
|
paths = visiblePaths config.value config.path state.expanded;
|
|
|
|
@ -213,6 +219,6 @@ tree = config \
|
|
|
|
scrollX = 0,
|
|
|
|
scrollX = 0,
|
|
|
|
scrollY = state.scrollY,
|
|
|
|
scrollY = state.scrollY,
|
|
|
|
onScroll = delta \ emit (Scrolled delta),
|
|
|
|
onScroll = delta \ emit (Scrolled delta),
|
|
|
|
child = treeNode { value = config.value, path = config.path, depth = 0, expanded = state.expanded, onToggle = onToggle, selectedPath = selectedPath, prefix = "", editing = state.editing, onDoneEditing = onDoneEditing }
|
|
|
|
child = treeNode { value = config.value, path = config.path, depth = 0, expanded = state.expanded, onToggle = onToggle, selectedPath = selectedPath, prefix = "", editing = state.editing, onDoneEditing = onDoneEditing, onEditLeaf = onEditLeaf }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|