Files
playpen/src/style.css
T
Greyson Parrelli 918ccec6e1 Split tree layouts, resizable dividers, and live drag preview
Replaces the flat pane list with a binary split tree, so a view can hold
layouts a single shared orientation could not express. Three panes in a row
with the rightmost dragged to the bottom now gives two on top and one
spanning the full width beneath them.

Each split node owns a GtkPaned, which brings draggable dividers. Positions
are stored as ratios and re-applied whenever the available space changes, so
proportions survive window resizes while user drags still update them.

Drop placement depends on proximity to the view's own border: near an edge
the pane is placed against the whole layout and spans it, anywhere else it
splits only the pane under the pointer.

Drags now rearrange live rather than on release, so the layout under the
cursor is always the result. Cancelling restores the original arrangement,
which works because only the dragged pane moves: the rest of the tree keeps
its shape, so re-inserting beside the original sibling is enough.

Fixes a latent ownership bug the tree exposed: panes did not hold a
reference to their own widget, so detaching one during a rebuild dropped the
last reference and finalized it, producing GTK_IS_WIDGET assertion failures.
Panes and split nodes now each own a reference to their widget.
2026-08-11 11:25:44 -04:00

140 lines
2.5 KiB
CSS

/* Zen-style vertical tabs: a dark sidebar column with the terminal inset
to its right. */
.vtabs-window {
background-color: #0f0d14;
}
.vtabs-sidebar {
background-color: #1b1823;
border-right: 1px solid #2a2536;
}
.vtabs-sidebar headerbar {
background: none;
box-shadow: none;
min-height: 38px;
}
.vtabs-list {
background: none;
padding: 4px 6px;
}
.vtabs-list > row {
border-radius: 8px;
margin: 1px 0;
padding: 5px 8px;
color: #b6afc7;
transition: background-color 120ms ease;
}
.vtabs-list > row:hover {
background-color: #262133;
}
.vtabs-list > row:selected {
background-color: #342c4a;
color: #f0ecf8;
}
.vtabs-list > row:selected image {
color: #b29df5;
}
/* Keep the close button unobtrusive until the row is hovered or current. */
.vtabs-close {
opacity: 0;
min-width: 20px;
min-height: 20px;
padding: 0;
}
.vtabs-list > row:hover .vtabs-close,
.vtabs-list > row:selected .vtabs-close {
opacity: 0.65;
}
.vtabs-close:hover {
opacity: 1;
}
.vtabs-content {
background-color: #0f0d14;
}
/* A view is the container for one tab's terminals. */
.vtabs-view {
padding: 6px 6px 6px 0;
}
/* Paned itself draws nothing; the panes inside it carry the styling. */
.vtabs-view paned {
background: none;
}
/* Each terminal sits in its own rounded frame so multiple panes in a view
read as distinct surfaces. */
.vtabs-pane {
background-color: #16141c;
border-radius: 10px;
border: 1px solid #2a2536;
}
.vtabs-pane.active {
border-color: #5b4d80;
}
.vtabs-pane-header {
padding: 2px 4px 2px 10px;
background-color: #1c1926;
border-bottom: 1px solid #262133;
}
.vtabs-pane.active .vtabs-pane-header {
background-color: #241f33;
}
.vtabs-pane-title {
font-size: 0.82em;
color: #8f87a3;
}
.vtabs-pane.active .vtabs-pane-title {
color: #ded7ef;
}
.vtabs-pane-button {
min-width: 22px;
min-height: 22px;
padding: 0;
opacity: 0;
}
.vtabs-pane:hover .vtabs-pane-button,
.vtabs-pane.active .vtabs-pane-button {
opacity: 0.55;
}
.vtabs-pane-button:hover {
opacity: 1;
}
/* The pane being dragged. There is no separate drop indicator: the layout
rearranges live during the drag, so the view itself is the preview. */
.vtabs-pane.dragging {
opacity: 0.65;
border-color: #b29df5;
}
/* Divider between panes. Wide enough to grab without hunting for it. */
.vtabs-view paned > separator {
background-color: #0f0d14;
min-width: 6px;
min-height: 6px;
}
.vtabs-view paned > separator:hover {
background-color: #4a3f6b;
}