Os module is now generated by CG. modularizing palette

This commit is contained in:
Dustin Swan 2026-04-02 16:59:50 -06:00
parent fa999b70fe
commit f2c381cad7
No known key found for this signature in database
GPG key ID: 30D46587E2100467
2 changed files with 159 additions and 167 deletions

View file

@ -1,3 +1,5 @@
@palette
paletteState = { paletteState = {
query = "", query = "",
focusedIndex = 0, focusedIndex = 0,
@ -5,6 +7,8 @@ paletteState = {
opacity = 0.95 opacity = 0.95
}; };
paletteHistory = [];
palette = config \ palette = config \
windowHeight = 400; windowHeight = 400;
windowWidth = 600; windowWidth = 600;
@ -172,3 +176,4 @@ palette = config \
} }
} }
}; };
@

View file

@ -3,7 +3,7 @@
osState = { osState = {
palette = { visible = True }, palette = { visible = True },
windows = [], windows = [],
blah = 3, blah = 53,
wm = { wm = {
focusedIndex = 0, focusedIndex = 0,
scrollOffset = 0, scrollOffset = 0,
@ -12,14 +12,14 @@ osState = {
nextId = 0 nextId = 0
}; };
os = os = openPalette = _ \ osState.palette.visible := not osState.palette.visible;
openPalette = _ \ osState.palette.visible := not (osState.palette.visible);
windowWidth = window \ window.fullWidth windowWidth = window \
window.fullWidth
| True \ viewport.width | True \ viewport.width
| False \ window.width; | False \ window.width;
scrollToWindow = index \ scrollToWindow = index \
windows = osState.windows; windows = osState.windows;
widths = map windowWidth windows; widths = map windowWidth windows;
gap = 1; gap = 1;
@ -27,136 +27,134 @@ os =
windowW = unwrapOr osState.wm.defaultWindowWidth (nth index widths); windowW = unwrapOr osState.wm.defaultWindowWidth (nth index widths);
scrollOffset = osState.wm.scrollOffset; scrollOffset = osState.wm.scrollOffset;
vw = viewport.width; vw = viewport.width;
(windowX < scrollOffset windowX < scrollOffset
| True \ windowX | True \ windowX
| False \ (windowX + windowW > scrollOffset + vw | False \ ((windowX + windowW) > (scrollOffset + vw)
| True \ windowX + windowW - vw | True \ (windowX + windowW) - vw
| False \ scrollOffset)); | False \ scrollOffset);
focusWindow = index \ focusWindow = index \ batch [
batch [
osState.palette.visible := False, osState.palette.visible := False,
osState.wm.focusedIndex := index, osState.wm.focusedIndex := index,
osState.wm.scrollOffset := scrollToWindow index osState.wm.scrollOffset := scrollToWindow index
]; ];
openWindow = title content width \ openWindow = title content width \
id = osState.nextId; id = osState.nextId;
batch [ batch [
osState.nextId := id + 1, osState.nextId := id + 1,
osState.windows := osState.windows & [{ osState.windows := osState.windows & [{
id = id, id = id,
title = title, title = title,
content = content, content = content,
width = width, width = width,
fullWidth = False fullWidth = False
}], }],
osState.palette.visible := False, osState.palette.visible := False,
focusWindow (len osState.windows) focusWindow (len osState.windows)
]; ];
closeWindowByIndex = i \ closeWindowByIndex = i \
focused = osState.wm.focusedIndex; focused = osState.wm.focusedIndex;
newFocused = (i < focused newFocused = i < focused
| True \ focused - 1 | True \ focused - 1
| False \ (i == focused | False \ (i == focused
| True \ max 0 (focused - 1) | True \ max 0 (focused - 1)
| False \ focused)); | False \ focused);
batch [ batch [
osState.windows := (take i osState.windows) & (drop (i + 1) osState.windows), osState.windows := (take i osState.windows) & (drop (i + 1) osState.windows),
focusWindow newFocused focusWindow newFocused
# osState.wm.focusedIndex := min newFocused (len osState.windows - 2)
]; ];
closeFocusedWindow = _ \ closeWindowByIndex osState.wm.focusedIndex; closeFocusedWindow = _ \ closeWindowByIndex osState.wm.focusedIndex;
closeWindowById = id \ closeWindowById = id \
i = index id (map (w \ w.id) osState.windows); i = index id (map (w \ w.id) osState.windows);
closeWindowByIndex (unwrapOr 0 i); closeWindowByIndex (unwrapOr 0 i);
toggleMaximizeFocusedWindow = _ \ toggleMaximizeFocusedWindow = _ \
idx = osState.wm.focusedIndex; idx = osState.wm.focusedIndex;
osState.windows := updateAt idx (w \ w.{ fullWidth = not w.fullWidth }) osState.windows; osState.windows := updateAt idx (w \ w.{ fullWidth = not w.fullWidth }) osState.windows;
openOrFocus = title content width \ openOrFocus = title content width \
index title (map (w \ w.title) osState.windows) index title (map (w \ w.title) osState.windows)
| Some i \ focusWindow i | (Some i) \ focusWindow i
| None \ openWindow title content width; | None \ openWindow title content width;
renderWindow = window isActive \ renderWindow = window isActive \
titleBarHeight = 36; titleBarHeight = 36;
ui.stack { children = [
ui.stack { ui.rect {
children = [ w = windowWidth window,
# background h = viewport.height,
ui.rect { w = (windowWidth window), h = viewport.height, color = (isActive | True \ "#0a2a3a" | False \ "#061820")}, color = isActive
| True \ "#0a2a3a"
# title bar | False \ "#061820"
},
ui.positioned { ui.positioned {
x = 0, y = 0, x = 0,
child = ui.stack { y = 0,
children = [ child = ui.stack { children = [
# background ui.rect {
ui.rect { w = (windowWidth window), h = titleBarHeight, color = (isActive | True \ "#a15f80" | False \ "#0f3348") }, w = windowWidth window,
ui.row { h = titleBarHeight,
children = [ color = isActive
# close button | True \ "#a15f80"
| False \ "#0f3348"
},
ui.row { children = [
ui.clickable { ui.clickable {
onClick = _ \ closeWindowById window.id, onClick = _ \ closeWindowById window.id,
child = ui.stack { child = ui.stack { children = [
children = [ ui.rect {
# button background w = titleBarHeight,
ui.rect { w = titleBarHeight, h = titleBarHeight, color = "rgba(255,255,255,0.2)" }, h = titleBarHeight,
# button text color = "rgba(255,255,255,0.2)"
ui.positioned { },
x = 12, y = 5, child = text "x" ui.positioned { x = 12, y = 5, child = text "x" }
} ] }
]
}
}, },
ui.positioned {
# title x = 8,
ui.positioned { x = 8, y = 8, child = renderText { content = window.title, color = "white" } }, y = 8,
] child = renderText { content = window.title, color = "white" }
} }
] ] }
} ] }
}, },
# content
ui.positioned { ui.positioned {
x = 0, y = titleBarHeight, x = 0,
y = titleBarHeight,
child = ui.clip { child = ui.clip {
w = (windowWidth window), w = windowWidth window,
h = viewport.height - titleBarHeight, h = viewport.height - titleBarHeight,
child = window.content { child = window.content {
w = (windowWidth window), w = windowWidth window,
h = viewport.height - titleBarHeight, h = viewport.height - titleBarHeight,
openApp = openOrFocus, openApp = openOrFocus,
close = _ \ closeWindowById window.id close = _ \ closeWindowById window.id
} }
} }
} }
] ] };
windowComponent = config \ ui.stateful {
key = "window-" & (show config.window.id),
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 emit \ renderWindow config.window config.isActive
}; };
windowComponent = config \ ui.stateful { onScroll = delta \
key = "window-" & (show config.window.id), totalWidth = (sum (map windowWidth osState.windows)) + (max 0 ((len osState.windows) - 1));
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 emit \ renderWindow config.window config.isActive
};
onScroll = delta \
totalWidth = (sum (map windowWidth osState.windows)) + (max 0 (len osState.windows - 1));
osState.wm.scrollOffset := max 0 (min (totalWidth - viewport.width) (osState.wm.scrollOffset + delta.deltaX)); osState.wm.scrollOffset := max 0 (min (totalWidth - viewport.width) (osState.wm.scrollOffset + delta.deltaX));
renderWindows = _ \ renderWindows = _ \
windows = osState.windows; windows = osState.windows;
focused = osState.wm.focusedIndex; focused = osState.wm.focusedIndex;
totalHeight = viewport.height; totalHeight = viewport.height;
@ -168,11 +166,11 @@ os =
onScroll = onScroll, onScroll = onScroll,
child = ui.row { child = ui.row {
gap = 1, gap = 1,
children = mapWithIndex (w i \ windowComponent { window = w, index = i, isActive = (i == focused) }) windows children = mapWithIndex (w i \ windowComponent { window = w, index = i, isActive = i == focused }) windows
}, }
}; };
search = q \ search = q \
storeRes = storeSearch q; storeRes = storeSearch q;
historyRes = filter (h \ fuzzyMatch q h) paletteHistory; historyRes = filter (h \ fuzzyMatch q h) paletteHistory;
[ [
@ -184,112 +182,101 @@ os =
Item { label = q } Item { label = q }
]; ];
onSelect = input \ onSelect = input \
historyEvent = paletteHistory := take 50 [input, ...(filter (e \ e != input) paletteHistory)]; historyEvent = paletteHistory := take 50 [input, ...filter (e \ e != input) paletteHistory];
dw = osState.wm.defaultWindowWidth;
appWidth = app \ hasField "width" app | True \ app.width | false \ dw;
openEvent = eval! input
| Defined name \ (
app = inspector { name = name };
openOrFocus name app.view (appWidth app))
| Value v \ (hasField "_tag" v dw = osState.wm.defaultWindowWidth;
appWidth = app \
hasField "width" app
| True \ app.width
| false \ dw;
openEvent = eval! input
| (Defined name) \ (app = inspector { name = name };
openOrFocus name app.view (appWidth app))
| (Value v) \ (hasField "_tag" v
| True \ batch [historyEvent, v] | True \ batch [historyEvent, v]
| False \ (hasField "view" v | False \ (hasField "view" v
| True \ openOrFocus input v.view (appWidth v) | True \ openOrFocus input v.view (appWidth v)
| False \ (getSource input == "" | False \ ((getSource input) == ""
| True \ openOrFocus input (_ \ renderText { content = show v, color = "white" }) dw | True \ openOrFocus input (_ \ renderText { content = show v, color = "white" }) dw
| False \ ( | False \ (app = inspector { name = input };
app = inspector { name = input };
openOrFocus input app.view (appWidth app))))) openOrFocus input app.view (appWidth app)))))
| (Err msg) \ (_ = debug! "OS Error" msg;
| Err msg \ (_ = debug! "OS Error" msg; noOp); noOp);
batch [historyEvent, openEvent]; batch [historyEvent, openEvent];
handleFocusLeftEvent = state \ handleFocusLeftEvent = state \
newIndex = max 0 (osState.wm.focusedIndex - 1); newIndex = max 0 (osState.wm.focusedIndex - 1);
{ state = state, emit = [focusWindow newIndex] }; { state = state, emit = [focusWindow newIndex] };
handleFocusRightEvent = state \ handleFocusRightEvent = state \
newIndex = min (len osState.windows - 1) (osState.wm.focusedIndex + 1); newIndex = min ((len osState.windows) - 1) (osState.wm.focusedIndex + 1);
{ state = state, emit = [focusWindow newIndex] }; { state = state, emit = [focusWindow newIndex] };
handleMoveLeftEvent = state \ handleMoveLeftEvent = state \
idx = osState.wm.focusedIndex; idx = osState.wm.focusedIndex;
idx == 0 idx == 0
| True \ { state = state, emit = [] } | True \ { state = state, emit = [] }
| False \ ( | False \ (newIdx = idx - 1;
newIdx = idx - 1;
windows = osState.windows; windows = osState.windows;
newWindows = [ newWindows = [
...take newIdx windows, ...take newIdx windows,
nth idx windows ~ unwrapOr {}, unwrapOr { } (nth idx windows),
nth newIdx windows ~ unwrapOr {}, unwrapOr { } (nth newIdx windows),
...drop (idx + 1) windows ...drop (idx + 1) windows
]; ];
{ state = state, emit = [osState.windows := newWindows, focusWindow newIdx] } {
); state = state,
emit = [osState.windows := newWindows, focusWindow newIdx]
});
handleMoveRightEvent = state \ handleMoveRightEvent = state \
idx = osState.wm.focusedIndex; idx = osState.wm.focusedIndex;
idx == len osState.windows - 1 idx == ((len osState.windows) - 1)
| True \ { state = state, emit = [] } | True \ { state = state, emit = [] }
| False \ ( | False \ (newIdx = idx + 1;
newIdx = idx + 1;
windows = osState.windows; windows = osState.windows;
newWindows = [ newWindows = [
...take idx windows, ...take idx windows,
nth newIdx windows ~ unwrapOr {}, unwrapOr { } (nth newIdx windows),
nth idx windows ~ unwrapOr {}, unwrapOr { } (nth idx windows),
...drop (newIdx + 1) windows ...drop (newIdx + 1) windows
]; ];
{ state = state, emit = [osState.windows := newWindows, focusWindow newIdx] } {
); state = state,
emit = [osState.windows := newWindows, focusWindow newIdx]
});
ui.stateful { ui.stateful {
key = "os", key = "os",
autoFocus = True, autoFocus = True,
init = { },
update = state event \
event
| (Key {key = "p", meta = True}) \ { state = state, emit = [openPalette] }
| (Key {key = "ArrowLeft", meta = True, shift = True}) \ handleMoveLeftEvent state
| (Key {key = "h", meta = True, shift = True}) \ handleMoveLeftEvent state
| (Key {key = "ArrowRight", meta = True, shift = True}) \ handleMoveRightEvent state
| (Key {key = "l", meta = True, shift = True}) \ handleMoveRightEvent state
| (Key {key = "ArrowLeft", meta = True}) \ handleFocusLeftEvent state
| (Key {key = "h", meta = True}) \ handleFocusLeftEvent state
| (Key {key = "ArrowRight", meta = True}) \ handleFocusRightEvent state
| (Key {key = "l", meta = True}) \ handleFocusRightEvent state
| (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 emit \ ui.stack { children = [
ui.rect { w = viewport.width, h = viewport.height, color = "#012" },
renderWindows 0,
osState.palette.visible
| True \ palette {
search = search,
onSelect = onSelect,
viewport = viewport
}
| False \ empty
] }
};
init = {},
update = state event \ event
| Key { key = "p", meta = True } \
{ state = state, emit = [openPalette] }
| Key { key = "ArrowLeft", meta = True, shift = True } \ handleMoveLeftEvent state
| Key { key = "h", meta = True, shift = True } \ handleMoveLeftEvent state
| Key { key = "ArrowRight", meta = True, shift = True } \ handleMoveRightEvent state
| Key { key = "l", meta = True, shift = True } \ handleMoveRightEvent state
| Key { key = "ArrowLeft", meta = True } \ handleFocusLeftEvent state
| Key { key = "h", meta = True } \ handleFocusLeftEvent state
| Key { key = "ArrowRight", meta = True } \ handleFocusRightEvent state
| Key { key = "l", meta = True } \ handleFocusRightEvent state
| 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 emit \
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,
]
}
};
@ @