Make the media pool a list you can actually read
Every row is one line now — a thumbnail at the stage's own 16:10, the name, and the one number you need before dragging it somewhere — at the timeline's own row height. Two always-open folders cost eight headings before the first row in a pane 210px wide; they are two tabs, and a search counts its hits in the scope you are not looking at so nothing can hide behind the one you did not pick. Symbols draw their own first frame, through the resolver and rasteriser the stage uses. A PLACED symbol is drawn where it is placed, with the rest of its host isolated away: rooting at a symbol renders its DRAWING, and a rotoscoped face is head-local in units of one image height, so the source-to-stage scale that makes it pixels lives on the :face group of whatever places it. Rendered rooted at itself a face is correct and under a pixel across. Thumbnails are smoothly downscaled for the same kind of reason the preview is not: at a tenth of the stage's size nearest neighbour samples one pixel in a hundred, and the silhouette is the whole of what makes a thumbnail recognisable. Names are editable, and that is two operations behind one pencil. A symbol's name is a field of this document, so it is an undoable edit and blank gives it back its id. Footage and sounds live beside projects rather than inside one, so theirs is a server write shared by every project using the row — PATCH on the existing Footage.label, and a new Sound.label kept separate from the filename, which is a fact about the upload and not somebody's name for it. No TIMELINES section beside a SYMBOLS one: every symbol here IS a timeline, so that pair named one thing twice. What is true is that exactly one of them is where the work happens, and clip/opens-on already answers which — it leads the pane as PROJECT, drawn at a size you can read a pose off, with the library under it. Still not :main being special; rename it or place it inside something else and the pool follows. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
815ce449ea
commit
7e34d0c704
11 changed files with 924 additions and 160 deletions
|
|
@ -416,67 +416,249 @@ button.share-button:hover, button.share-button.on { filter: brightness(1.1); }
|
|||
.peer.guest { background: var(--dim); }
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
media pool */
|
||||
media pool
|
||||
|
||||
/* Two folders, THIS PROJECT and ALL ASSETS, each holding groups. */
|
||||
.pool-folder { margin-bottom: 8px; }
|
||||
.pool-folder > summary {
|
||||
cursor: pointer;
|
||||
padding: 2px 0 4px;
|
||||
font-weight: 600;
|
||||
color: var(--fg);
|
||||
A FILE LIST, AND IT IS 210px WIDE. Every row is one line — a picture at the
|
||||
stage's own proportions, a name, one number — because the pane under this one
|
||||
is the timeline and a row that costs two lines costs timeline rows. The row is
|
||||
--row tall, which is a timeline row, so a pool of symbols and the rows they
|
||||
end up on are the same size object.
|
||||
|
||||
One exception, deliberately: the main timeline. See `.pool-row.main`. */
|
||||
|
||||
/* The search strip, between the pane head and the tabs. Its own band rather
|
||||
than crowded into the head, which is one line and already holds the + . */
|
||||
.pool-find {
|
||||
position: sticky;
|
||||
top: 21px;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 3px 5px;
|
||||
background: var(--chrome);
|
||||
border-bottom: 1px solid var(--hair);
|
||||
}
|
||||
.pool-folder > .pool-group { padding-left: 8px; }
|
||||
.pool-project { margin-bottom: 2px; }
|
||||
.pool-project > summary { cursor: pointer; color: var(--dim); padding: 1px 0; }
|
||||
.pool-project > .pool-item { margin-left: 10px; width: calc(100% - 10px); }
|
||||
|
||||
.pool-group { margin-bottom: 9px; }
|
||||
.pool-search {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
height: 17px;
|
||||
padding: 0 5px;
|
||||
font: inherit;
|
||||
color: var(--fg);
|
||||
background: var(--pane);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* The one-line gloss under a group heading. Small and quiet: it answers "what
|
||||
is this list" once, for someone who has not read the model. */
|
||||
.pool-group > h2 + .dim { margin-bottom: 4px; }
|
||||
/* Safari draws its own clear button inside a search input, in its own idiom and
|
||||
at its own size. The one next to it is this file's. */
|
||||
.pool-search::-webkit-search-decoration,
|
||||
.pool-search::-webkit-search-cancel-button { -webkit-appearance: none; }
|
||||
|
||||
.pool-group > h2 {
|
||||
margin: 0 0 3px;
|
||||
.pool-clear {
|
||||
flex: 0 0 auto;
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-radius: 2px;
|
||||
background: none;
|
||||
color: var(--dim);
|
||||
cursor: pointer;
|
||||
}
|
||||
.pool-clear:hover { background: var(--hair); color: var(--fg); }
|
||||
|
||||
/* The scope tabs, in the vocabulary `ui/tabs` already established for symbols —
|
||||
the same object, so two rows of tabs on one screen read as one idea. */
|
||||
.pool > .tabs { top: 45px; position: sticky; z-index: 2; }
|
||||
|
||||
/* A tally, shown only on the tab you are NOT looking at and only while a search
|
||||
is running: it says "what you asked for is over here". */
|
||||
.tab .count {
|
||||
padding: 0 4px;
|
||||
border-radius: 7px;
|
||||
background: var(--sel-bg);
|
||||
color: var(--sel);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
/* MEDIA, SOUNDS, TIMELINES. A heading is one line and it sticks, so scrolling a
|
||||
long list never leaves you looking at rows with no idea what kind they are. */
|
||||
.pool-section { margin-bottom: 7px; }
|
||||
|
||||
.pool-section > h2 {
|
||||
position: sticky;
|
||||
top: 69px;
|
||||
z-index: 1;
|
||||
margin: 0 0 2px;
|
||||
padding: 1px 5px;
|
||||
font: inherit;
|
||||
font-weight: 600;
|
||||
color: var(--dim);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .07em;
|
||||
background: var(--pane);
|
||||
}
|
||||
|
||||
.pool-item {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
padding: 2px 6px;
|
||||
.pool-section > .dim { padding: 0 5px 2px; }
|
||||
|
||||
.pool-rows { display: flex; flex-direction: column; }
|
||||
|
||||
/* What a search found nothing to say. */
|
||||
.pool-empty { padding: 6px 5px; color: var(--dim); }
|
||||
|
||||
.pool-project { margin: 0 0 1px 5px; }
|
||||
.pool-project > summary { cursor: pointer; color: var(--dim); padding: 1px 0; }
|
||||
.pool-project > .pool-rows { margin-left: 8px; }
|
||||
|
||||
/* THE ROW IS THE BUTTON. Click selects, double-click opens, and drag starts
|
||||
anywhere across it — the whole strip, not the few characters of the name. The
|
||||
wrapper carries the state classes and the frame; the button inside it fills
|
||||
that frame edge to edge, so there is no dead strip anywhere along the row. */
|
||||
.pool-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
min-width: 0;
|
||||
height: var(--row);
|
||||
padding: 0 4px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.pool-row:hover:not(.disabled) { background: #fff; }
|
||||
.pool-row.on { background: var(--sel-bg); border-color: var(--sel); }
|
||||
|
||||
/* WHICH ONE IS OPEN, as a mark and not as the word "open" — a list this narrow
|
||||
cannot spend twenty pixels of every name on a word that is true of one row.
|
||||
The accent, because selection is the only thing it is ever used for and the
|
||||
open symbol is what the rest of the screen is showing. */
|
||||
.pool-row.open { box-shadow: inset 2px 0 0 var(--sel); }
|
||||
|
||||
.pool-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
border: 0;
|
||||
background: none;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
/* Shrinks to the name, so the pencil sits against the end of the word rather
|
||||
than out at the edge of the pane — and ellipses rather than pushing the
|
||||
number off the row. */
|
||||
.pool-item .text { display: flex; flex-direction: column; flex: 0 1 auto; min-width: 0; }
|
||||
.pool-item .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
|
||||
/* The number, at the far edge and never moving: `auto` on the left is what
|
||||
pushes it there, and tabular figures are what stop it shuffling as the rows
|
||||
scroll past. */
|
||||
.pool-item > .sub {
|
||||
flex: 0 0 auto;
|
||||
margin-left: auto;
|
||||
padding-left: 4px;
|
||||
color: var(--dim);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
/* Every row leads with a picture, and they are all this box, so the names line
|
||||
up down the list whatever is beside them. 16:10 is the stage's own ratio at
|
||||
320x200 — a thumbnail that is not the picture's shape is a thumbnail you have
|
||||
to think about. */
|
||||
.pool-item .thumb {
|
||||
flex: 0 0 32px;
|
||||
width: 32px;
|
||||
height: 20px;
|
||||
object-fit: cover;
|
||||
background: var(--stage);
|
||||
border-radius: 1px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.pool-item .thumb.sound {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #d9d9d9;
|
||||
}
|
||||
|
||||
/* THE MAIN TIMELINE, under the PROJECT heading and at the top of the pane.
|
||||
`clip/opens-on`'s answer: the longest symbol nothing else places, which is
|
||||
where the work happens. The one row in the pane given size, a second line and
|
||||
a surface of its own — spent here rather than spread over every row, which is
|
||||
what keeps the list below it a list. */
|
||||
.pool-row.main {
|
||||
height: auto;
|
||||
margin-bottom: 5px;
|
||||
padding: 4px;
|
||||
background: var(--sunk);
|
||||
border-color: var(--hair);
|
||||
}
|
||||
|
||||
.pool-row.main .thumb {
|
||||
flex: 0 0 64px;
|
||||
width: 64px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.pool-row.main .name { font-weight: 600; }
|
||||
|
||||
/* Both facts on one line under the name. Beside a 64px picture there is room,
|
||||
and this is the one row where a person wants more than the length before
|
||||
they click. */
|
||||
.pool-row.main .detail {
|
||||
color: var(--dim);
|
||||
font-variant-numeric: tabular-nums;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.pool-item:hover:not(:disabled) { background: #fff; }
|
||||
.pool-item.on { background: var(--sel-bg); border-color: var(--sel); }
|
||||
.pool-item .sub { display: block; color: var(--dim); }
|
||||
.pool-item .text { display: block; overflow: hidden; text-overflow: ellipsis; }
|
||||
/* The pencil. A span and not a button — see `ui/pool`'s `row` — so it needs its
|
||||
own centring and cursor rather than inheriting a control's.
|
||||
|
||||
/* A media row leads with one frame of the video. */
|
||||
.pool-item.media { display: flex; align-items: center; gap: 6px; }
|
||||
.pool-item .thumb {
|
||||
flex: 0 0 40px;
|
||||
width: 40px;
|
||||
height: 30px;
|
||||
max-width: 40px;
|
||||
max-height: 30px;
|
||||
object-fit: cover;
|
||||
background: var(--stage);
|
||||
Hidden until the row is under the pointer or holds focus, because a column of
|
||||
twenty pencils is a column of twenty pencils; `visibility` rather than
|
||||
`display`, so it keeps its width and the name beside it does not reflow as the
|
||||
pointer crosses the list. */
|
||||
.pool-rename {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 0 0 15px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border-radius: 2px;
|
||||
color: var(--dim);
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.pool-row:hover .pool-rename,
|
||||
.pool-row:focus-within .pool-rename { visibility: visible; }
|
||||
.pool-rename:hover { background: var(--hair); color: var(--fg); }
|
||||
|
||||
/* Renaming. The input REPLACES the row at the same height, so a list does not
|
||||
jump while you type in it. */
|
||||
.pool-name {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
height: 17px;
|
||||
padding: 0 4px;
|
||||
font: inherit;
|
||||
color: var(--fg);
|
||||
background: #fff;
|
||||
border: 1px solid var(--sel);
|
||||
border-radius: 2px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* The whole pane is the drop target, so the cue has to be the pane and not a
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue