Returning coords with Clickable event. Usinsg them to position cursor when clicking in a textfield

master
Dustin Swan 2 days ago
parent 787e071fbd
commit 9f078aaeef
Signed by: dustinswan
GPG Key ID: 30D46587E2100467

@ -8,7 +8,7 @@ view = count \
children = [
Text({ content = str(count), x = 0, y = 20 }),
Clickable {
event = "increment",
event = Increment,
child = Rect { w = 100, h = 40, color = "blue" }
}
]

@ -74,9 +74,26 @@ export function runApp(app: App, canvas: HTMLCanvasElement) {
}
const event = hitTest(x, y);
if (event) {
handleEvent(event);
const hitResult = hitTest(x, y);
if (hitResult) {
const { event, relativeX, relativeY } = hitResult;
if (event.kind === 'constructor') {
const eventWithCoords: Value = {
kind: 'constructor',
name: event.name,
args: [{
kind: 'record',
fields: {
x: { kind: 'int', value: Math.floor(relativeX) },
y: { kind: 'int', value: Math.floor(relativeY) },
}
}]
};
handleEvent(eventWithCoords);
} else {
handleEvent(event);
}
}
});

@ -1,21 +1,31 @@
routeKeyToFocused = state event \
(state.focusedInput == "email"
| True \
newInputState = textInput2.update state.email event;
newInputState = textInput.update state.email event;
state.{ email = newInputState }
| False \
newInputState = textInput2.update state.password event;
newInputState = textInput.update state.password event;
state.{ password = newInputState });
init = {
focusedInput = "email",
email = textInput2.init "",
password = textInput2.init ""
email = textInput.init "",
password = textInput.init ""
};
update = state event \ event
| FocusEmail \ state.{ focusedInput = "email" }
| FocusPassword \ state.{ focusedInput = "password" }
| FocusEmail coords \ (
newState = state.{ focusedInput = "email" };
newInputState = textInput.update state.email (Clicked coords);
newState.{ email = newInputState }
)
| FocusPassword coords \ (
newState = state.{ focusedInput = "password" };
newInputState = textInput.update state.password (Clicked coords);
newState.{ password = newInputState }
)
| ArrowLeft \ routeKeyToFocused state ArrowLeft
| ArrowRight \ routeKeyToFocused state ArrowRight
| Backspace \ routeKeyToFocused state Backspace
@ -29,13 +39,13 @@ view = state viewport \
child = Column {
gap = 10,
children = [
textInput2.view state.email {
textInput.view state.email {
focused = state.focusedInput == "email",
onFocus = FocusEmail,
w = 300,
h = 40
},
textInput2.view state.password {
textInput.view state.password {
focused = state.focusedInput == "password",
onFocus = FocusPassword,
w = 300,

@ -33,7 +33,23 @@ calcScrollOffset = text cursorPos scrollOffset inputWidth \
| True \ cursorX - inputWidth + 20
| False \ scrollOffset));
textInput2 = {
findPosHelper = text targetX index \
(index >= len text)
| True \ len text
| False \ (
widthSoFar = measureText (slice text 0 index);
widthNext = measureText (slice text 0 (index + 1));
midpoint = (widthSoFar + widthNext) / 2;
(targetX < midpoint
| True \ index
| False \ findPosHelper text targetX (index + 1))
);
findCursorPos = text clickX scrollOffset inputPadding \
adjustedX = clickX + scrollOffset - inputPadding;
findPosHelper text adjustedX 0;
textInput = {
# init : String \ State
init = text \ { text = text, cursorPos = 0, scrollOffset = 0 },
@ -65,6 +81,12 @@ textInput2 = {
{ text = newText, cursorPos = newCursorPos, scrollOffset = newScroll }
)
| Clicked coords \ (
newCursorPos = findCursorPos state.text coords.x state.scrollOffset 8;
newScroll = calcScrollOffset state.text newCursorPos state.scrollOffset 284;
{ text = state.text, cursorPos = newCursorPos, scrollOffset = newScroll }
)
| _ \ state,
view = state config \

@ -228,11 +228,15 @@ function measure(ui: UIValue): { width: number, height: number } {
}
}
export function hitTest(x: number, y: number): Value | null {
export function hitTest(x: number, y: number): { event: Value, relativeX: number, relativeY: number } | null {
for (const region of clickRegions) {
if (x >= region.x && x < region.x + region.width &&
y >= region.y && y < region.y + region.height) {
return region.event;
return {
event: region.event,
relativeX: x - region.x,
relativeY: y - region.y,
};
}
}
return null;

Loading…
Cancel
Save