|
|
|
@ -98,12 +98,17 @@ box = config \
|
|
|
|
]
|
|
|
|
]
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
insertChar = text pos char \
|
|
|
|
textInput = config \
|
|
|
|
|
|
|
|
defaults = { onSubmit = _ \ noOp };
|
|
|
|
|
|
|
|
c = { ...defaults, ...config };
|
|
|
|
|
|
|
|
_ = debug "c" c;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
insertChar = text pos char \
|
|
|
|
before = slice text 0 pos;
|
|
|
|
before = slice text 0 pos;
|
|
|
|
after = slice text pos (len text);
|
|
|
|
after = slice text pos (len text);
|
|
|
|
before & char & after;
|
|
|
|
before & char & after;
|
|
|
|
|
|
|
|
|
|
|
|
deleteChar = text pos \
|
|
|
|
deleteChar = text pos \
|
|
|
|
(pos == 0
|
|
|
|
(pos == 0
|
|
|
|
| True \ text
|
|
|
|
| True \ text
|
|
|
|
| False \
|
|
|
|
| False \
|
|
|
|
@ -111,7 +116,7 @@ deleteChar = text pos \
|
|
|
|
after = slice text pos (len text);
|
|
|
|
after = slice text pos (len text);
|
|
|
|
before & after));
|
|
|
|
before & after));
|
|
|
|
|
|
|
|
|
|
|
|
calcScrollOffset = text cursorPos scrollOffset inputWidth \
|
|
|
|
calcScrollOffset = text cursorPos scrollOffset inputWidth \
|
|
|
|
textBeforeCursor = slice text 0 cursorPos;
|
|
|
|
textBeforeCursor = slice text 0 cursorPos;
|
|
|
|
cursorX = ui.measureText textBeforeCursor;
|
|
|
|
cursorX = ui.measureText textBeforeCursor;
|
|
|
|
(cursorX < scrollOffset
|
|
|
|
(cursorX < scrollOffset
|
|
|
|
@ -121,7 +126,7 @@ calcScrollOffset = text cursorPos scrollOffset inputWidth \
|
|
|
|
| True \ cursorX - inputWidth + 20
|
|
|
|
| True \ cursorX - inputWidth + 20
|
|
|
|
| False \ scrollOffset));
|
|
|
|
| False \ scrollOffset));
|
|
|
|
|
|
|
|
|
|
|
|
findPosHelper = text targetX index \
|
|
|
|
findPosHelper = text targetX index \
|
|
|
|
(index >= len text)
|
|
|
|
(index >= len text)
|
|
|
|
| True \ len text
|
|
|
|
| True \ len text
|
|
|
|
| False \ (
|
|
|
|
| False \ (
|
|
|
|
@ -133,60 +138,65 @@ findPosHelper = text targetX index \
|
|
|
|
| False \ findPosHelper text targetX (index + 1))
|
|
|
|
| False \ findPosHelper text targetX (index + 1))
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
findCursorPos = text clickX scrollOffset inputPadding \
|
|
|
|
findCursorPos = text clickX scrollOffset inputPadding \
|
|
|
|
adjustedX = clickX + scrollOffset - inputPadding;
|
|
|
|
adjustedX = clickX + scrollOffset - inputPadding;
|
|
|
|
findPosHelper text adjustedX 0;
|
|
|
|
findPosHelper text adjustedX 0;
|
|
|
|
|
|
|
|
|
|
|
|
textInput = config \ ui.stateful {
|
|
|
|
ui.stateful {
|
|
|
|
key = config.key,
|
|
|
|
key = c.key,
|
|
|
|
focusable = True,
|
|
|
|
focusable = True,
|
|
|
|
autoFocus = config.initialFocus,
|
|
|
|
autoFocus = c.initialFocus,
|
|
|
|
|
|
|
|
|
|
|
|
# init : State
|
|
|
|
# init : State
|
|
|
|
init = {
|
|
|
|
init = {
|
|
|
|
text = config.initialValue,
|
|
|
|
text = c.initialValue,
|
|
|
|
focused = config.initialFocus,
|
|
|
|
focused = c.initialFocus,
|
|
|
|
cursorPos = 0,
|
|
|
|
cursorPos = 0,
|
|
|
|
scrollOffset = 0
|
|
|
|
scrollOffset = 0
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
# update : State \ Event \ State
|
|
|
|
# update : State \ Event \ State
|
|
|
|
update = state event \ event
|
|
|
|
update = state event \ event
|
|
|
|
| Key { key = c, printable = True, meta = False, ctrl = False } \ (
|
|
|
|
| Key { key = key, printable = True, meta = False, ctrl = False } \ (
|
|
|
|
newText = insertChar state.text state.cursorPos c;
|
|
|
|
newText = insertChar state.text state.cursorPos key;
|
|
|
|
newCursorPos = state.cursorPos + 1;
|
|
|
|
newCursorPos = state.cursorPos + 1;
|
|
|
|
newScroll = calcScrollOffset newText newCursorPos state.scrollOffset config.w;
|
|
|
|
newScroll = calcScrollOffset newText newCursorPos state.scrollOffset c.w;
|
|
|
|
newState = state.{ text = newText, cursorPos = newCursorPos, scrollOffset = newScroll };
|
|
|
|
newState = state.{ text = newText, cursorPos = newCursorPos, scrollOffset = newScroll };
|
|
|
|
{ state = newState, emit = [config.onChange newText] })
|
|
|
|
{ state = newState, emit = [c.onChange newText] })
|
|
|
|
|
|
|
|
|
|
|
|
| Key { key = "ArrowLeft" } \ (
|
|
|
|
| Key { key = "ArrowLeft" } \ (
|
|
|
|
newCursorPos = max 0 (state.cursorPos - 1);
|
|
|
|
newCursorPos = max 0 (state.cursorPos - 1);
|
|
|
|
newScroll = calcScrollOffset state.text newCursorPos state.scrollOffset config.w;
|
|
|
|
newScroll = calcScrollOffset state.text newCursorPos state.scrollOffset c.w;
|
|
|
|
newState = state.{ text = state.text, cursorPos = newCursorPos, scrollOffset = newScroll };
|
|
|
|
newState = state.{ text = state.text, cursorPos = newCursorPos, scrollOffset = newScroll };
|
|
|
|
{ state = newState, emit = [] })
|
|
|
|
{ state = newState, emit = [] })
|
|
|
|
|
|
|
|
|
|
|
|
| Key { key = "ArrowRight" } \ (
|
|
|
|
| Key { key = "ArrowRight" } \ (
|
|
|
|
newCursorPos = min (len state.text) (state.cursorPos + 1);
|
|
|
|
newCursorPos = min (len state.text) (state.cursorPos + 1);
|
|
|
|
newScroll = calcScrollOffset state.text newCursorPos state.scrollOffset config.w;
|
|
|
|
newScroll = calcScrollOffset state.text newCursorPos state.scrollOffset c.w;
|
|
|
|
newState = state.{ text = state.text, cursorPos = newCursorPos, scrollOffset = newScroll };
|
|
|
|
newState = state.{ text = state.text, cursorPos = newCursorPos, scrollOffset = newScroll };
|
|
|
|
{ state = newState, emit = [] })
|
|
|
|
{ state = newState, emit = [] })
|
|
|
|
|
|
|
|
|
|
|
|
| Key { key = "Backspace" } \ (
|
|
|
|
| Key { key = "Backspace" } \ (
|
|
|
|
newText = deleteChar state.text state.cursorPos;
|
|
|
|
newText = deleteChar state.text state.cursorPos;
|
|
|
|
newCursorPos = max 0 (state.cursorPos - 1);
|
|
|
|
newCursorPos = max 0 (state.cursorPos - 1);
|
|
|
|
newScroll = calcScrollOffset newText newCursorPos state.scrollOffset config.w;
|
|
|
|
newScroll = calcScrollOffset newText newCursorPos state.scrollOffset c.w;
|
|
|
|
newState = state.{ text = newText, cursorPos = newCursorPos, scrollOffset = newScroll };
|
|
|
|
newState = state.{ text = newText, cursorPos = newCursorPos, scrollOffset = newScroll };
|
|
|
|
{ state = newState, emit = [config.onChange newText] })
|
|
|
|
{ state = newState, emit = [c.onChange newText] })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Key { key = "Enter" } \ (
|
|
|
|
|
|
|
|
# newState = state.{ text = "", cursorPos = 0, scrollOffset = 0 };
|
|
|
|
|
|
|
|
# do we blank it out here? wish parent could decide..
|
|
|
|
|
|
|
|
{ state = state, emit = [c.onSubmit state.text] })
|
|
|
|
|
|
|
|
|
|
|
|
| Clicked coords \ (
|
|
|
|
| Clicked coords \ (
|
|
|
|
newCursorPos = findCursorPos state.text coords.x state.scrollOffset 8;
|
|
|
|
newCursorPos = findCursorPos state.text coords.x state.scrollOffset 8;
|
|
|
|
newScroll = calcScrollOffset state.text newCursorPos state.scrollOffset config.w;
|
|
|
|
newScroll = calcScrollOffset state.text newCursorPos state.scrollOffset c.w;
|
|
|
|
newState = state.{ text = state.text, cursorPos = newCursorPos, scrollOffset = newScroll };
|
|
|
|
newState = state.{ text = state.text, cursorPos = newCursorPos, scrollOffset = newScroll };
|
|
|
|
{ state = newState, emit = [] })
|
|
|
|
{ state = newState, emit = [] })
|
|
|
|
|
|
|
|
|
|
|
|
| Focused \ { state = state.{ focused = True }, emit = [] }
|
|
|
|
| Focused \ { state = state.{ focused = True }, emit = [] }
|
|
|
|
| Blurred \ { state = state.{ focused = False }, emit = [] }
|
|
|
|
| Blurred \ { state = state.{ focused = False }, emit = [] }
|
|
|
|
# | Key { key = k } \ { state = state, emit = [\ config.onKeyDown k ] }
|
|
|
|
# | Key { key = k } \ { state = state, emit = [\ c.onKeyDown k ] }
|
|
|
|
| _ \ { state = state, emit = [] },
|
|
|
|
| _ \ { state = state, emit = [] },
|
|
|
|
|
|
|
|
|
|
|
|
view = state \
|
|
|
|
view = state \
|
|
|
|
@ -195,26 +205,26 @@ textInput = config \ ui.stateful {
|
|
|
|
padding = 8;
|
|
|
|
padding = 8;
|
|
|
|
|
|
|
|
|
|
|
|
ui.clip {
|
|
|
|
ui.clip {
|
|
|
|
w = config.w,
|
|
|
|
w = c.w,
|
|
|
|
h = config.h,
|
|
|
|
h = c.h,
|
|
|
|
child = ui.stack {
|
|
|
|
child = ui.stack {
|
|
|
|
children = [
|
|
|
|
children = [
|
|
|
|
ui.rect { w = config.w, h = config.h, color = config.backgroundColor, radius = 0 },
|
|
|
|
ui.rect { w = c.w, h = c.h, color = c.backgroundColor, radius = 0 },
|
|
|
|
|
|
|
|
|
|
|
|
ui.positioned {
|
|
|
|
ui.positioned {
|
|
|
|
x = 8 - state.scrollOffset,
|
|
|
|
x = 8 - state.scrollOffset,
|
|
|
|
y = 0,
|
|
|
|
y = 0,
|
|
|
|
child = ui.positioned { x = 0, y = 12, child = ui.text { content = state.text, color = config.color } }
|
|
|
|
child = ui.positioned { x = 0, y = 12, child = ui.text { content = state.text, color = c.color } }
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
(state.focused
|
|
|
|
(state.focused
|
|
|
|
| True \ ui.positioned {
|
|
|
|
| True \ ui.positioned {
|
|
|
|
x = 8 + cursorX - state.scrollOffset,
|
|
|
|
x = 8 + cursorX - state.scrollOffset,
|
|
|
|
y = 8,
|
|
|
|
y = 8,
|
|
|
|
child = ui.rect { w = 2, h = 24, color = config.color }
|
|
|
|
child = ui.rect { w = 2, h = 24, color = c.color }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
| _ \ empty)
|
|
|
|
| _ \ empty)
|
|
|
|
]
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|