scrollable now supports horizontal scrolling. using it in os wm. putting all os stuff in os namespace

master
Dustin Swan 2 weeks ago
parent 5fc9d13f80
commit 373ec8b36b
Signed by: dustinswan
GPG Key ID: 30D46587E2100467

@ -26,25 +26,36 @@ button = config \
# scrollable # scrollable
scrollable = config \ scrollable = config \
barHeight = max 20 (config.h * config.h / config.totalHeight); showVBar = config.totalHeight > config.h;
barY = config.scrollY * config.h / config.totalHeight; vBarHeight = max 20 (config.h * config.h / config.totalHeight);
showBar = config.totalHeight > config.h; vBarY = config.scrollY * config.h / config.totalHeight;
showHBar = config.totalWidth > config.w;
vBarWidth = max 20 (config.w * config.w / config.totalWidth);
vBarX = config.scrollX * config.w / config.totalWidth;
ui.stack { ui.stack {
children = [ children = [
ui.scrollable { ui.scrollable {
w = config.w, w = config.w,
h = config.h, h = config.h,
scrollX = 0, scrollX = config.scrollX,
scrollY = config.scrollY, scrollY = config.scrollY,
onScroll = config.onScroll, onScroll = config.onScroll,
child = config.child child = config.child
}, },
...(showBar ...(showVBar
| True \ [ui.positioned { | True \ [ui.positioned {
x = config.w - 4, x = config.w - 4,
y = barY, y = vBarY,
child = ui.rect { w = 4, h = barHeight, color = "rgba(255,255,255,0.3)", radius = 2 } child = ui.rect { w = 4, h = vBarHeight, color = "rgba(255,255,255,0.3)", radius = 2 }
}]
| False \ []),
...(showHBar
| True \ [ui.positioned {
x = config.h - 4,
y = hBarX,
child = ui.rect { h = 4, w = hBarWidth, color = "rgba(255,255,255,0.3)", radius = 2 }
}] }]
| False \ []) | False \ [])
] ]

@ -126,6 +126,7 @@ palette = config \
w = contentWidth, w = contentWidth,
h = listHeight, h = listHeight,
totalHeight = totalHeight, totalHeight = totalHeight,
totalWidth = contentWidth,
scrollX = 0, scrollX = 0,
scrollY = paletteState.scrollOffset, scrollY = paletteState.scrollOffset,
onScroll = onScroll, onScroll = onScroll,

@ -9,204 +9,212 @@ osState = {
nextId = 0 nextId = 0
}; };
openPalette = _ \ osState.palette.visible := not (osState.palette.visible); os =
openPalette = _ \ osState.palette.visible := not (osState.palette.visible);
windowWidth = window \ window.fullWidth
| True \ viewport.width windowWidth = window \ window.fullWidth
| False \ window.width; | True \ viewport.width
| False \ window.width;
openWindow = title content \
id = osState.nextId; totalWidth = (sum (map windowWidth osState.windows)) + (len osState.windows - 1);
batch [
osState.nextId := id + 1, scrollToWindow = index \
osState.windows := osState.windows & [{ windows = osState.windows;
id = id, widths = map windowWidth windows;
title = title, gap = 1;
content = content, windowX = (sum (take index widths)) + (index * gap);
width = osState.wm.defaultWindowWidth, windowW = unwrapOr osState.wm.defaultWindowWidth (nth index widths);
fullWidth = False scrollOffset = osState.wm.scrollOffset;
}], vw = viewport.width;
osState.palette.visible := False, (windowX < scrollOffset
focusWindow (len osState.windows) | True \ windowX
]; | False \ (windowX + windowW > scrollOffset + vw
| True \ windowX + windowW - vw
closeWindowByIndex = i \ | False \ scrollOffset));
focused = osState.wm.focusedIndex;
newFocused = (i < focused focusWindow = index \
| True \ focused - 1 batch [
| False \ (i == focused osState.wm.focusedIndex := index,
| True \ max 0 (focused - 1) osState.wm.scrollOffset := scrollToWindow index
| False \ focused)); ];
batch [ openWindow = title content \
osState.windows := (take i osState.windows) & (drop (i + 1) osState.windows), id = osState.nextId;
focusWindow newFocused batch [
# osState.wm.focusedIndex := min newFocused (len osState.windows - 2) osState.nextId := id + 1,
]; osState.windows := osState.windows & [{
id = id,
closeFocusedWindow = _ \ closeWindowByIndex osState.wm.focusedIndex; title = title,
content = content,
closeWindowById = id \ width = osState.wm.defaultWindowWidth,
i = index id (map (w \ w.id) osState.windows); fullWidth = False
closeWindowByIndex (unwrapOr 0 i); }],
osState.palette.visible := False,
toggleMaximizeFocusedWindow = _ \ focusWindow (len osState.windows)
idx = osState.wm.focusedIndex; ];
osState.windows := updateAt idx (w \ w.{ fullWidth = not w.fullWidth }) osState.windows;
closeWindowByIndex = i \
scrollToWindow = index \ focused = osState.wm.focusedIndex;
windows = osState.windows; newFocused = (i < focused
widths = map windowWidth windows; | True \ focused - 1
gap = 1; | False \ (i == focused
windowX = (sum (take index widths)) + (index * gap); | True \ max 0 (focused - 1)
windowW = unwrapOr osState.wm.defaultWindowWidth (nth index widths); | False \ focused));
scrollOffset = osState.wm.scrollOffset;
vw = viewport.width; batch [
(windowX < scrollOffset osState.windows := (take i osState.windows) & (drop (i + 1) osState.windows),
| True \ windowX focusWindow newFocused
| False \ (windowX + windowW > scrollOffset + vw # osState.wm.focusedIndex := min newFocused (len osState.windows - 2)
| True \ windowX + windowW - vw ];
| False \ scrollOffset));
closeFocusedWindow = _ \ closeWindowByIndex osState.wm.focusedIndex;
focusWindow = index \
batch [ closeWindowById = id \
osState.wm.focusedIndex := index, i = index id (map (w \ w.id) osState.windows);
osState.wm.scrollOffset := scrollToWindow index closeWindowByIndex (unwrapOr 0 i);
];
toggleMaximizeFocusedWindow = _ \
onSelect = input \ idx = osState.wm.focusedIndex;
result = eval input; osState.windows := updateAt idx (w \ w.{ fullWidth = not w.fullWidth }) osState.windows;
result
| Value v \ openWindow input (_ \ ui.text { content = show v, color = "white" }) renderWindow = window isActive \
| Defined name \ openWindow name (_ \ inspector { name = name }) titleBarHeight = 30;
| Err msg \ openWindow "Error" (_ \ ui.text { content = msg, color = "red" });
renderWindow = window isActive \
titleBarHeight = 30;
ui.stack {
children = [
# background
ui.rect { w = (windowWidth window), h = viewport.height, color = (isActive | True \ "#0a2a3a" | False \ "#061820")},
# title bar
ui.positioned {
x = 0, y = 0,
child = ui.stack {
children = [
# background
ui.rect { w = (windowWidth window), h = titleBarHeight, color = (isActive | True \ "#a15f80" | False \ "#0f3348") },
ui.row {
children = [
# close button
ui.clickable {
onClick = _ \ closeWindowById window.id,
child = ui.stack {
children = [
# button background
ui.rect { w = titleBarHeight, h = titleBarHeight, color = "rgba(255,255,255,0.2)" },
# button text
ui.positioned {
x = 9, y = 7, child = ui.text { content = "x" }
}
]
}
},
# title
ui.positioned { x = 8, y = 8, child = ui.text { content = window.title, color = "white" } },
]
}
]
}
},
# content
ui.positioned {
x = 0, y = titleBarHeight,
child = ui.clip {
w = (windowWidth window),
h = viewport.height - titleBarHeight,
child = window.content 0
}
}
]
};
windowComponent = config \ ui.stateful {
key = "window-" & (show config.index),
focusable = True,
init = {},
update = state event \ event
| Focused \ { state = state, emit = [focusWindow config.index] }
| ChildFocused \ { state = state, emit = [focusWindow config.index] }
| _ \ { state = state, emit = [] },
view = state \ renderWindow config.window config.isActive
};
renderWindows = _ \
windows = osState.windows;
focused = osState.wm.focusedIndex;
scrollable {
w = viewport.width,
h = viewport.height,
scrollX = osState.wm.scrollOffset,
scrollY = 0,
child = ui.row {
gap = 1,
children = mapWithIndex (w i \ windowComponent { window = w, index = i, isActive = (i == focused) }) windows
}
};
search = q \
storeRes = storeSearch q;
[
Section "STORE",
...map (name \ Item { label = name }) storeRes,
Section "EVAL",
Item { label = q }
];
os = ui.stateful {
key = "os",
autoFocus = True,
init = {},
update = state event \ event
| Key { key = "p", meta = True } \
{ state = state, emit = [openPalette] }
| Key { key = "ArrowLeft", meta = True } \
(
newIndex = max 0 (osState.wm.focusedIndex - 1);
{ state = state, emit = [focusWindow newIndex] }
)
| Key { key = "ArrowRight", meta = True } \
(
newIndex = min (len osState.windows - 1) (osState.wm.focusedIndex + 1);
{ state = state, emit = [focusWindow newIndex] }
)
| Key { key = "d", meta = True } \
{ state = state, emit = [closeFocusedWindow 0] }
| Key { key = "f", meta = True } \
{ state = state, emit = [toggleMaximizeFocusedWindow 0] }
| _ \ { state = state, emit = [] },
view = state \
ui.stack { ui.stack {
children = [ children = [
ui.rect { w = viewport.width, h = viewport.height, color = "#012" }, # background
ui.rect { w = (windowWidth window), h = viewport.height, color = (isActive | True \ "#0a2a3a" | False \ "#061820")},
renderWindows 0,
# title bar
# keep palette at the end so it's on top ui.positioned {
osState.palette.visible x = 0, y = 0,
| True \ palette { child = ui.stack {
search = search, children = [
onSelect = onSelect, # background
viewport = viewport, ui.rect { w = (windowWidth window), h = titleBarHeight, color = (isActive | True \ "#a15f80" | False \ "#0f3348") },
ui.row {
children = [
# close button
ui.clickable {
onClick = _ \ closeWindowById window.id,
child = ui.stack {
children = [
# button background
ui.rect { w = titleBarHeight, h = titleBarHeight, color = "rgba(255,255,255,0.2)" },
# button text
ui.positioned {
x = 9, y = 7, child = ui.text { content = "x" }
}
]
}
},
# title
ui.positioned { x = 8, y = 8, child = ui.text { content = window.title, color = "white" } },
]
}
]
} }
| False \ empty, },
# content
ui.positioned {
x = 0, y = titleBarHeight,
child = ui.clip {
w = (windowWidth window),
h = viewport.height - titleBarHeight,
child = window.content 0
}
}
] ]
} };
windowComponent = config \ ui.stateful {
key = "window-" & (show config.index),
focusable = True,
init = {},
update = state event \ event
| Focused \ { state = state, emit = [focusWindow config.index] }
| ChildFocused \ { state = state, emit = [focusWindow config.index] }
| _ \ { state = state, emit = [] },
view = state \ renderWindow config.window config.isActive
}; };
renderWindows = _ \
windows = osState.windows;
focused = osState.wm.focusedIndex;
totalHeight = viewport.height;
scrollable {
w = viewport.width,
h = viewport.height,
scrollX = osState.wm.scrollOffset,
scrollY = 0,
onScroll = onScroll,
child = ui.row {
gap = 1,
children = mapWithIndex (w i \ windowComponent { window = w, index = i, isActive = (i == focused) }) windows
},
};
search = q \
storeRes = storeSearch q;
[
Section "STORE",
...map (name \ Item { label = name }) storeRes,
Section "EVAL",
Item { label = q }
];
onScroll = delta \
osState.wm.scrollOffset := max 0 (min (totalWidth - viewport.width) (osState.wm.scrollOffset + delta.deltaX));
onSelect = input \
result = eval input;
result
| Value v \ openWindow input (_ \ ui.text { content = show v, color = "white" })
| Defined name \ openWindow name (_ \ inspector { name = name })
| Err msg \ openWindow "Error" (_ \ ui.text { content = msg, color = "red" });
ui.stateful {
key = "os",
autoFocus = True,
init = {},
update = state event \ event
| Key { key = "p", meta = True } \
{ state = state, emit = [openPalette] }
| Key { key = "ArrowLeft", meta = True } \
(
newIndex = max 0 (osState.wm.focusedIndex - 1);
{ state = state, emit = [focusWindow newIndex] }
)
| Key { key = "ArrowRight", meta = True } \
(
newIndex = min (len osState.windows - 1) (osState.wm.focusedIndex + 1);
{ state = state, emit = [focusWindow newIndex] }
)
| Key { key = "d", meta = True } \
{ state = state, emit = [closeFocusedWindow 0] }
| Key { key = "f", meta = True } \
{ state = state, emit = [toggleMaximizeFocusedWindow 0] }
| _ \ { state = state, emit = [] },
view = state \
ui.stack {
children = [
ui.rect { w = viewport.width, h = viewport.height, color = "#012" },
renderWindows 0,
# keep palette at the end so it's on top
osState.palette.visible
| True \ palette {
search = search,
onSelect = onSelect,
viewport = viewport,
}
| False \ empty,
]
}
};

Loading…
Cancel
Save