Allowin thunks in eventHandlers. more progress on OS palette. adding fuzzy match to storeSearch

master
Dustin Swan 3 weeks ago
parent f378149146
commit b8a396a734
Signed by: dustinswan
GPG Key ID: 30D46587E2100467

@ -1,5 +1,8 @@
# TODO delete # nth : Int \ List a \ Maybe a
double = a \ a * 2; nth = i list \ [i, list]
| [_, []] \ None
| [0, [x, ...xs]] \ (Some x)
| [n, [x, ...xs]] \ nth (n - 1) xs;
# map : (a \ b) \ List a \ List b # map : (a \ b) \ List a \ List b
map = f list \ list map = f list \ list

@ -1,22 +1,3 @@
listRow = config \
color = (config.selected | True \ "rgba(255,255,255,0.2)" | False \ "transparent");
Clickable {
event = config.onClick,
child = Stack {
children = [
Rect { w = config.w, h = config.h, color = color },
centerV config.h (
Positioned {
x = 10,
y = 10,
child = Text { content = config.child, color = "white" }
}
)
]
}
};
palette = config \ palette = config \
focusedIndex = 0; focusedIndex = 0;
windowHeight = 400; windowHeight = 400;
@ -31,6 +12,25 @@ palette = config \
contentHeight = windowHeight - (padding * 2); contentHeight = windowHeight - (padding * 2);
listHeight = contentHeight - 40; listHeight = contentHeight - 40;
paletteRow = config \
color = (config.selected | True \ "rgba(255,255,255,0.2)" | False \ "transparent");
Clickable {
event = config.onClick,
child = Stack {
children = [
Rect { w = config.w, h = config.h, color = color },
centerV config.h (
Positioned {
x = 10,
y = 10,
child = Text { content = config.child, color = "white" }
}
)
]
}
};
Positioned { 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,
@ -44,7 +44,7 @@ palette = config \
gap = 0, gap = 0,
children = [ children = [
textInput { textInput {
key = "query", key = "palette-query",
initialValue = config.state.query, initialValue = config.state.query,
initialFocus = True, initialFocus = True,
color = "white", color = "white",
@ -55,6 +55,7 @@ palette = config \
onKeyDown = key \ key onKeyDown = key \ key
| ArrowUp \ config.state.focusedIndex := max 0 (config.state.focusedIndex - 1) | ArrowUp \ config.state.focusedIndex := max 0 (config.state.focusedIndex - 1)
| ArrowDown \ config.state.focusedIndex := (config.state.focusedIndex + 1) | ArrowDown \ config.state.focusedIndex := (config.state.focusedIndex + 1)
| Enter \ (\ config.onSelect (unwrapOr "" (nth config.state.focusedIndex results)))
| _ \ NoOp | _ \ NoOp
}, },
Clip { Clip {
@ -62,7 +63,13 @@ palette = config \
h = listHeight, h = listHeight,
child = Column { child = Column {
gap = 1, gap = 1,
children = mapWithIndex (t i \ listRow { child = t, w = contentWidth, h = textInputHeight, selected = (config.state.focusedIndex == i), onClick = NoOp }) results children = mapWithIndex (t i \ paletteRow {
child = t,
w = contentWidth,
h = textInputHeight,
selected = (config.state.focusedIndex == i),
onClick = \ config.onSelect t
}) results
} }
} }
] ]

@ -2,7 +2,7 @@ osState = {
palette = { palette = {
query = "", query = "",
focusedIndex = 0, focusedIndex = 0,
} },
}; };
init = {}; init = {};
@ -17,7 +17,7 @@ view = state viewport \
palette { palette {
state = osState.palette, state = osState.palette,
search = storeSearch, search = storeSearch,
onSelect = item \ debug "selected" item, onSelect = item \ (debug "selected" item),
viewport = viewport, viewport = viewport,
} }
] ]

@ -101,7 +101,7 @@ export class Parser {
return true; return true;
} }
if (kind !== 'ident') { if (kind !== 'ident' && kind !== 'underscore') {
return false; return false;
} }
@ -109,7 +109,7 @@ export class Parser {
while (true) { while (true) {
const token = this.peek(offset); const token = this.peek(offset);
if (token.kind === 'backslash') return true; if (token.kind === 'backslash') return true;
if (token.kind !== 'ident') return false; if (token.kind !== 'ident' && token.kind !== 'underscore') return false;
offset++; offset++;
} }
} }

@ -142,6 +142,12 @@ export function runAppCompiled(app: App, canvas: HTMLCanvasElement, rt: any) {
} }
function handleEvent(event: any) { function handleEvent(event: any) {
// Thunk
if (typeof event === 'function') {
handleEvent(event(null));
return;
}
if (!event || !event._tag) return; if (!event || !event._tag) return;
if (event._tag === 'Batch' && event._0) { if (event._tag === 'Batch' && event._0) {

@ -35,15 +35,17 @@ export const _rt = {
} }
return text.length * 10; // fallback return text.length * 10; // fallback
}, },
storeSearch: (query: string) => { fuzzyMatch: (query: string) => (target: string) => {
const results: string[] = []; const q = query.toLowerCase();
const searchTerm = query.toLowerCase(); const t = target.toLowerCase();
for (const name of Object.keys(store)) { let qi = 0;
if (searchTerm === '' || name.toLowerCase().includes(searchTerm)) { for (let ti = 0; ti < t.length && qi < q.length; ti++) {
results.push(name); if (t[ti] === q[qi]) qi++;
}
} }
return results; return { _tag: qi === q.length ? 'True' : 'False' };
},
storeSearch: (query: string) => {
return Object.keys(store).filter(name => _rt.fuzzyMatch(query)(name)._tag === 'True');
}, },
getSource: (name: string) => { getSource: (name: string) => {
const ast = definitions.get(name); const ast = definitions.get(name);

Loading…
Cancel
Save