Changing the shape of apps. adding better error boundries at stateful components. start fontViewer

master
Dustin Swan 5 days ago
parent d58c39a1ac
commit cc33b9a015
Signed by: dustinswan
GPG Key ID: 30D46587E2100467

@ -0,0 +1,55 @@
fontEditor = config \
defaults = { };
c = { ...defaults, ...config };
size \ ui.stateful {
focusable = True,
autoFocus = True,
key = "fontEditor-" & c.path,
init = existing
| Value v \ {
map = v.map,
pixelWidth = 5,
pixelHeight = 7,
cellSize = 30,
selectedRow = 0,
selectedCol = 0
}
| _ \ {
map = [],
pixelWidth = 5,
pixelHeight = 7,
cellSize = 30,
selectedRow = 0,
selectedCol = 0
},
update = state event \ event
| ClickCell { x = x, y = y } \ toggleFocused state.{ selectedRow = y, selectedCol = x }
| Key { key = " " } \ toggleFocused state
| Key { key = "Enter" } \ toggleFocused state
| Key { key = "ArrowDown" } \ downArrow state
| Key { key = "j" } \ downArrow state
| Key { key = "ArrowUp" } \ upArrow state
| Key { key = "k" } \ upArrow state
| Key { key = "ArrowLeft" } \ leftArrow state
| Key { key = "h" } \ leftArrow state
| Key { key = "ArrowRight" } \ rightArrow state
| Key { key = "l" } \ rightArrow state
| UpdateWidth w \ (
newState = state.{ pixelWidth = (int w) };
{ state = newState, emit = saveGlyph newState })
| UpdateHeight h \ (
newState = state.{ pixelHeight = (int h) };
{ state = newState, emit = saveGlyph newState })
| _ \ { state = state, emit = [] },
view = state emit \
ui.text { content = "testing" }
};

@ -1,15 +1,19 @@
inspector = config \ size \ inspector = config \
val = eval! config.name; {
width = 600,
view = size \
val = eval! config.name;
reflected = val reflected = val
| Value v \ reflect v | Value v \ reflect v
| _ \ reflect 0; | _ \ reflect 0;
textInputHeight = 40; textInputHeight = 40;
tree { tree {
value = reflected, value = reflected,
path = config.name, path = config.name,
w = size.w, w = size.w,
h = size.h - textInputHeight h = size.h - textInputHeight
}; }
};

@ -35,113 +35,120 @@ pixelEditor = config \
newState = state.{ map = newMap }; newState = state.{ map = newMap };
{ state = newState, emit = saveGlyph newState }); { state = newState, emit = saveGlyph newState });
_ = debug! "c.path" c.path;
existing = eval! (c.path); existing = eval! (c.path);
_ = debug! "existing" existing;
size \ ui.stateful {
focusable = True, # return App
autoFocus = True, {
width = 600,
key = "pixelEditor-" & c.path,
view = size \ ui.stateful {
init = existing focusable = True,
| Value v \ { autoFocus = True,
map = v.map,
pixelWidth = 5, key = "pixelEditor-" & c.path,
pixelHeight = 7,
cellSize = 30, init = existing
selectedRow = 0, | Value v \ {
selectedCol = 0 map = v.map,
} pixelWidth = 5,
| _ \ { pixelHeight = 7,
map = [], cellSize = 30,
pixelWidth = 5, selectedRow = 0,
pixelHeight = 7, selectedCol = 0
cellSize = 30, }
selectedRow = 0, | _ \ {
selectedCol = 0 map = [],
}, pixelWidth = 5,
pixelHeight = 7,
update = state event \ event cellSize = 30,
| ClickCell { x = x, y = y } \ toggleFocused state.{ selectedRow = y, selectedCol = x } selectedRow = 0,
| Key { key = " " } \ toggleFocused state selectedCol = 0
| Key { key = "Enter" } \ toggleFocused state },
| Key { key = "ArrowDown" } \ downArrow state update = state event \ event
| Key { key = "j" } \ downArrow state | ClickCell { x = x, y = y } \ toggleFocused state.{ selectedRow = y, selectedCol = x }
| Key { key = "ArrowUp" } \ upArrow state | Key { key = " " } \ toggleFocused state
| Key { key = "k" } \ upArrow state | Key { key = "Enter" } \ toggleFocused state
| Key { key = "ArrowLeft" } \ leftArrow state
| Key { key = "h" } \ leftArrow state | Key { key = "ArrowDown" } \ downArrow state
| Key { key = "ArrowRight" } \ rightArrow state | Key { key = "j" } \ downArrow state
| Key { key = "l" } \ rightArrow state | Key { key = "ArrowUp" } \ upArrow state
| Key { key = "k" } \ upArrow state
| UpdateWidth w \ ( | Key { key = "ArrowLeft" } \ leftArrow state
newState = state.{ pixelWidth = (int w) }; | Key { key = "h" } \ leftArrow state
{ state = newState, emit = saveGlyph newState }) | Key { key = "ArrowRight" } \ rightArrow state
| Key { key = "l" } \ rightArrow state
| UpdateHeight h \ (
newState = state.{ pixelHeight = (int h) }; | UpdateWidth w \ (
{ state = newState, emit = saveGlyph newState }) newState = state.{ pixelWidth = (int w) };
{ state = newState, emit = saveGlyph newState })
| _ \ { state = state, emit = [] },
| UpdateHeight h \ (
view = state emit \ newState = state.{ pixelHeight = (int h) };
{ state = newState, emit = saveGlyph newState })
grid = ui.column {
children = map (rIdx \ | _ \ { state = state, emit = [] },
ui.row {
children = map (cIdx \ view = state emit \
on = contains { x = cIdx, y = rIdx } state.map;
color = (on |True\ "#000" |False\ "rgba(255,255,255,0.2)"); grid = ui.column {
children = map (rIdx \
selected = and (rIdx == state.selectedRow) (cIdx == state.selectedCol); ui.row {
strokeColor = (selected | True \ "#f00" | False \ "rgba(0,0,0,0.2)"); children = map (cIdx \
on = contains { x = cIdx, y = rIdx } state.map;
ui.clickable { color = (on |True\ "#000" |False\ "rgba(255,255,255,0.2)");
onClick = \ emit (ClickCell { x = cIdx, y = rIdx }),
child = ui.rect { w = state.cellSize, h = state.cellSize, color = color, strokeWidth = 1, strokeColor = strokeColor } selected = and (rIdx == state.selectedRow) (cIdx == state.selectedCol);
} strokeColor = (selected | True \ "#f00" | False \ "rgba(0,0,0,0.2)");
) (range 0 state.pixelWidth)
} ui.clickable {
) (range 0 state.pixelHeight) onClick = \ emit (ClickCell { x = cIdx, y = rIdx }),
}; child = ui.rect { w = state.cellSize, h = state.cellSize, color = color, strokeWidth = 1, strokeColor = strokeColor }
}
headerHeight = 30; ) (range 0 state.pixelWidth)
}
header = ui.row { ) (range 0 state.pixelHeight)
gap = 10, };
children = [ headerHeight = 30;
ui.positioned { x = 0, y = 8, child = ui.text { content = c.path, color = "#fff" } },
header = ui.row {
textInput { gap = 10,
key = "width-input",
w = 40, children = [
h = headerHeight, ui.positioned { x = 0, y = 8, child = ui.text { content = c.path, color = "#fff" } },
color = "#fff",
backgroundColor = "rgba(0,0,0,0.2)", textInput {
onSubmit = v \ emit (UpdateWidth v), key = "width-input",
initialValue = (show state.pixelWidth) w = 40,
}, h = headerHeight,
color = "#fff",
ui.positioned { x = 0, y = 8, child = ui.text { content = "x", color = "#aaa" } }, backgroundColor = "rgba(0,0,0,0.2)",
onSubmit = v \ emit (UpdateWidth v),
textInput { initialValue = (show state.pixelWidth)
key = "height-input", },
w = 40,
h = headerHeight, ui.positioned { x = 0, y = 8, child = ui.text { content = "x", color = "#aaa" } },
color = "#fff",
backgroundColor = "rgba(0,0,0,0.2)", textInput {
onSubmit = v \ emit (UpdateHeight v), key = "height-input",
initialValue = (show state.pixelHeight) w = 40,
} h = headerHeight,
] color = "#fff",
}; backgroundColor = "rgba(0,0,0,0.2)",
onSubmit = v \ emit (UpdateHeight v),
ui.column { initialValue = (show state.pixelHeight)
children = [ }
header, ]
center size.w size.h grid };
]
} ui.column {
children = [
header,
center size.w size.h grid
]
}
}
}; };

@ -37,7 +37,7 @@ os =
osState.wm.scrollOffset := scrollToWindow index osState.wm.scrollOffset := scrollToWindow index
]; ];
openWindow = title content \ openWindow = title content width \
id = osState.nextId; id = osState.nextId;
batch [ batch [
osState.nextId := id + 1, osState.nextId := id + 1,
@ -45,7 +45,7 @@ os =
id = id, id = id,
title = title, title = title,
content = content, content = content,
width = osState.wm.defaultWindowWidth, width = width,
fullWidth = False fullWidth = False
}], }],
osState.palette.visible := False, osState.palette.visible := False,
@ -171,24 +171,28 @@ os =
isUI = v \ hasField "kind" v; isUI = v \ hasField "kind" v;
openOrFocus = title content \ openOrFocus = title content width \
index title (map (w \ w.title) osState.windows) index title (map (w \ w.title) osState.windows)
| Some i \ focusWindow i | Some i \ focusWindow i
| None \ openWindow title content; | None \ openWindow title content width;
onSelect = input \ onSelect = input \
result = eval! input; dw = osState.wm.defaultWindowWidth;
result appWidth = app \ hasField "width" app | True \ app.width | false \ dw;
| Defined name \ openOrFocus name (inspector { name = name }) eval! input
| Defined name \ (
| Value v \ (isFunction v app = inspector { name = name };
| True \ openOrFocus input v openOrFocus name app.view (appWidth app))
| False \ (isUI v
| True \ openOrFocus input (size \ v) | Value v \ (hasField "view" v
| False \ (getSource input == "" | True \ openOrFocus input v.view (appWidth v)
| True \ openOrFocus input (_ \ ui.text { content = show v, color = "white" }) | False \ (getSource input == ""
| False \ openOrFocus input (inspector { name = input })))) | True \ openOrFocus input (_ \ ui.text { content = show v, color = "white" }) dw
| Err msg \ (_ = debug! "Error" msg; noOp); | False \ (
app = inspector { name = input };
openOrFocus input app.view (appWidth app))))
| Err msg \ (_ = debug! "OS Error" msg; noOp);
handleFocusLeftEvent = state \ handleFocusLeftEvent = state \
newIndex = max 0 (osState.wm.focusedIndex - 1); newIndex = max 0 (osState.wm.focusedIndex - 1);

@ -97,7 +97,17 @@ export function runAppCompiled(canvas: HTMLCanvasElement, store: any) {
} }
const emit = (event: any) => ({ _tag: 'ComponentEvent', _0: fullKey, _1: event }); const emit = (event: any) => ({ _tag: 'ComponentEvent', _0: fullKey, _1: event });
const viewResult = instance.view(instance.state)(emit); let viewResult;
try {
viewResult = instance.view(instance.state)(emit);
} catch (e: any) {
viewResult = {
kind: 'stack', children: [
{ kind: 'rect', w: 9999, h: 60, color: '#400' },
{ kind: 'text', content: `Error: ${e.message}`, x: 10, y: 30, color: '#f88' }
]
};
}
const viewUI = { const viewUI = {
kind: 'clickable', kind: 'clickable',

Loading…
Cancel
Save