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 \
val = eval! config.name;
inspector = config \
{
width = 600,
view = size \
val = eval! config.name;
reflected = val
| Value v \ reflect v
| _ \ reflect 0;
reflected = val
| Value v \ reflect v
| _ \ reflect 0;
textInputHeight = 40;
textInputHeight = 40;
tree {
value = reflected,
path = config.name,
w = size.w,
h = size.h - textInputHeight
};
tree {
value = reflected,
path = config.name,
w = size.w,
h = size.h - textInputHeight
}
};

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

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

Loading…
Cancel
Save