Allowin thunks in eventHandlers. more progress on OS palette. adding fuzzy match to storeSearch
This commit is contained in:
parent
f378149146
commit
b8a396a734
6 changed files with 53 additions and 35 deletions
|
|
@ -1,5 +1,8 @@
|
|||
# TODO delete
|
||||
double = a \ a * 2;
|
||||
# nth : Int \ List a \ Maybe a
|
||||
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 = 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 \
|
||||
focusedIndex = 0;
|
||||
windowHeight = 400;
|
||||
|
|
@ -31,6 +12,25 @@ palette = config \
|
|||
contentHeight = windowHeight - (padding * 2);
|
||||
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 {
|
||||
x = (config.viewport.width - windowWidth) / 2,
|
||||
y = (config.viewport.height - windowHeight) / 2,
|
||||
|
|
@ -44,7 +44,7 @@ palette = config \
|
|||
gap = 0,
|
||||
children = [
|
||||
textInput {
|
||||
key = "query",
|
||||
key = "palette-query",
|
||||
initialValue = config.state.query,
|
||||
initialFocus = True,
|
||||
color = "white",
|
||||
|
|
@ -55,6 +55,7 @@ palette = config \
|
|||
onKeyDown = key \ key
|
||||
| ArrowUp \ config.state.focusedIndex := max 0 (config.state.focusedIndex - 1)
|
||||
| ArrowDown \ config.state.focusedIndex := (config.state.focusedIndex + 1)
|
||||
| Enter \ (\ config.onSelect (unwrapOr "" (nth config.state.focusedIndex results)))
|
||||
| _ \ NoOp
|
||||
},
|
||||
Clip {
|
||||
|
|
@ -62,7 +63,13 @@ palette = config \
|
|||
h = listHeight,
|
||||
child = Column {
|
||||
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 = {
|
||||
query = "",
|
||||
focusedIndex = 0,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
init = {};
|
||||
|
|
@ -17,7 +17,7 @@ view = state viewport \
|
|||
palette {
|
||||
state = osState.palette,
|
||||
search = storeSearch,
|
||||
onSelect = item \ debug "selected" item,
|
||||
onSelect = item \ (debug "selected" item),
|
||||
viewport = viewport,
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ export class Parser {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (kind !== 'ident') {
|
||||
if (kind !== 'ident' && kind !== 'underscore') {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ export class Parser {
|
|||
while (true) {
|
||||
const token = this.peek(offset);
|
||||
if (token.kind === 'backslash') return true;
|
||||
if (token.kind !== 'ident') return false;
|
||||
if (token.kind !== 'ident' && token.kind !== 'underscore') return false;
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,6 +142,12 @@ export function runAppCompiled(app: App, canvas: HTMLCanvasElement, rt: any) {
|
|||
}
|
||||
|
||||
function handleEvent(event: any) {
|
||||
// Thunk
|
||||
if (typeof event === 'function') {
|
||||
handleEvent(event(null));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!event || !event._tag) return;
|
||||
|
||||
if (event._tag === 'Batch' && event._0) {
|
||||
|
|
|
|||
|
|
@ -35,15 +35,17 @@ export const _rt = {
|
|||
}
|
||||
return text.length * 10; // fallback
|
||||
},
|
||||
storeSearch: (query: string) => {
|
||||
const results: string[] = [];
|
||||
const searchTerm = query.toLowerCase();
|
||||
for (const name of Object.keys(store)) {
|
||||
if (searchTerm === '' || name.toLowerCase().includes(searchTerm)) {
|
||||
results.push(name);
|
||||
}
|
||||
fuzzyMatch: (query: string) => (target: string) => {
|
||||
const q = query.toLowerCase();
|
||||
const t = target.toLowerCase();
|
||||
let qi = 0;
|
||||
for (let ti = 0; ti < t.length && qi < q.length; ti++) {
|
||||
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) => {
|
||||
const ast = definitions.get(name);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue