Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions docs/settings-page.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,12 +256,16 @@ The order of the isp card on the Picture leaf is `SECTION_GROUPS.isp` in
1. the two mode switches, with no heading;
2. Clarity (dehaze);
3. Exposure and gain;
4. How it reacts;
5. For tuning engineers: the external-tuner switch.
4. For tuning engineers: the external-tuner switch;
5. How it reacts.

The last three are folded behind **More exposure settings** (`fold` on the
group, #585): eleven exposure rows under the picture read as the page's
subject. The fold opens by itself whenever a row in it holds a value away from
subject. The fold sits under the card's two columns, full width, with a pair
of columns of its own that is dealt when it opens; the rows above it are never
dealt solo, since the card is not a handful of rows but the head of a longer
one. The tuning switch comes before How it reacts so that the cut, taken only
between headings, balances. The fold opens by itself whenever a row in it holds a value away from
stock, an unsaved edit or a search hit (`openGroupFolds()`, run from
`paintStock()`), and never shuts by itself, so a setting in force is never out
of sight. Picking Manual fills three of those rows and so opens it. The body
Expand Down
66 changes: 45 additions & 21 deletions www/a/bootstrap.override.css
Original file line number Diff line number Diff line change
Expand Up @@ -2576,31 +2576,42 @@ button.mj-osd-chip,
align-items: center;
}

/* The deck's second row: Scene, Luma and Orientation side by side rather than
the 405px two-column block they used to make. Shallow enough that on a 1080p
window the whole panel is on screen again, and the picture never paid for it.
Luma takes the slack because a histogram is the one of the three that is
worth more the wider it gets. */
/* The deck's second row, in two columns: what you set on the left (Tone, then
Orientation), what the picture measures on the right (Luma, and the tone
figures under it). Three columns left Orientation a panel as tall as Tone's
for one row of four buttons, and squeezed the figures two by two into Tone's
17rem. Luma takes the slack because a histogram is worth more the wider it
gets, and its figures want a row of four. */
.mj-live-col-scene {
flex: 0 0 17rem;
flex: 0 0 40%;
}

.mj-live-col-geo {
flex: 0 0 15rem;
.mj-live-col-luma {
border-left: 1px solid var(--bs-border-color);
}

/* Orientation, under Tone in the same column rather than a column each, since
each is one short block. Its own heading's rule is the divider. */
.mj-live-geo {
margin-top: 1.25rem;
}

.mj-live-geo:first-child {
margin-top: 0;
}

.mj-live-grp + .mj-live-grp {
margin-top: 1.25rem;
}

/* A deck column's first heading has the column's own padding above it and
nothing to be separated from, so the group heading's 1.5rem of air came on
top of that: 45px of empty card over Tone, Luma and Orientation. First of
TYPE, because the
Orientation column opens with the hidden mirror and flip rows, which are
<p> and not the group's <div>. */
.mj-live-col > .mj-live-grp:first-of-type > .mj-live-grp-head {
top of that: 45px of empty card over Tone and Luma. First of TYPE, because
Orientation's wrapper opens with the hidden mirror and flip rows, which are
<p> and not the group's <div>; and that wrapper is the column's first child
on a camera with mirror and flip but no Tone. */
.mj-live-col > .mj-live-grp:first-of-type > .mj-live-grp-head,
.mj-live-col > .mj-live-geo:first-child > .mj-live-grp:first-of-type > .mj-live-grp-head {
margin-top: 0;
}

Expand Down Expand Up @@ -2906,13 +2917,14 @@ button.mj-osd-chip,
font-weight: 600;
}

/* The measurement under the verdict. `auto-fit` rather than a fixed four:
the set of figures is whatever the camera publishes, and a part that never
states its gain publishes three -- which should read as a row of three, not
as four with a hole where the fourth would be. */
/* The measurement under the histogram: one row, however many figures the
camera publishes -- a part that never states its gain publishes three, which
should read as a row of three, not as four with a hole. Flex rather than an
auto-fit grid: each figure starts at its own width, so at full width every
label is on one line, and narrower the labels wrap inside a row that stays a
row. The grid broke into three and one at 1100px. */
.mj-tone-figs {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(6.5rem, 1fr));
display: flex;
gap: 0.5rem 0.75rem;
margin-top: 0.75rem;
padding-top: 0.7rem;
Expand All @@ -2921,15 +2933,27 @@ button.mj-osd-chip,

.mj-tone-fig {
display: flex;
flex: 1 1 auto;
flex-direction: column;
gap: 0.15rem;
min-width: 0;
}

/* A phone's single column is too narrow for four: two by two. */
@media (max-width: 575.98px) {
.mj-tone-figs {
flex-wrap: wrap;
}

.mj-tone-fig {
flex-basis: 40%;
}
}

.mj-tone-fig-k {
color: var(--bs-tertiary-color);
font-size: 0.6875rem;
letter-spacing: 0.04em;
letter-spacing: 0.02em;
text-transform: uppercase;
}

Expand Down Expand Up @@ -3205,7 +3229,7 @@ button.mj-osd-chip,
}

.mj-live-col-b,
.mj-live-col-geo {
.mj-live-col-luma {
flex: 1 1 auto;
border-left: 0;
border-top: 1px solid var(--bs-border-color);
Expand Down
59 changes: 47 additions & 12 deletions www/a/mj-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -2851,16 +2851,21 @@
if (hasTone) form.appendChild(strip);

// The second card carries what is worth having but not worth the
// picture's height: Scene, Luma and Orientation, side by side rather
// than as the 405px two-column block they used to make. Shallow enough
// that on a 1080p window the whole panel is on screen again.
// picture's height, in two columns: what you set on the left -- Tone,
// then Orientation under it -- and what the picture measures on the
// right -- Luma, with the tone figures under the histogram they are
// readings of. Orientation had a column of its own once, as tall as
// Tone's for one row of four buttons; the figures sat two by two in
// Tone's narrow column with their labels wrapped and half of every
// cell empty.
const deck = el('div', 'mj-live-deck');
const colScene = el('div', 'mj-live-col mj-live-col-scene');
const colLuma = el('div', 'mj-live-col');
const colGeo = el('div', 'mj-live-col mj-live-col-geo');
const colLuma = el('div', 'mj-live-col mj-live-col-luma');
// Filled while the fields are placed (the hidden mirror and flip
// checkboxes land here first), and put under Tone once Tone is drawn.
const colGeo = el('div', 'mj-live-geo');
deck.appendChild(colScene);
deck.appendChild(colLuma);
deck.appendChild(colGeo);
form.appendChild(deck);

// Under the deck: one card per section, holding what the deck has no
Expand Down Expand Up @@ -3091,6 +3096,7 @@
liveGroup(colScene, 'Tone', 'automatic or by hand'),
toneFields);
}
colScene.appendChild(colGeo);

if (preview) {
// The group's note slot carries the running mean rather than a
Expand All @@ -3100,6 +3106,12 @@
const note = lumaBody.parentNode.querySelector('.mj-live-note');
if (note) note.className = 'mj-live-note mj-luma-mean';
renderLuma(lumaBody, preview);
// The tone figures -- range used, lost in shadows and highlights,
// light to spare -- are readings of this histogram, so they sit
// under it, four across. renderScene built them and still drives
// them; only their place changes.
const figs = colScene.querySelector('.mj-tone-figs');
if (figs) lumaBody.appendChild(figs);
}

if (useGeo) {
Expand All @@ -3120,8 +3132,8 @@
// stacked. Drop whatever came out empty instead of enumerating the
// combinations. colGeo is judged on what is VISIBLE in it: with the pad
// mounted it holds the two hidden checkboxes as well, and without the
// pad it may hold nothing but them — a cell that renders as a divider
// and 15rem of nothing.
// pad it may hold nothing but them — a block that renders as a rule and
// a gap under Tone with nothing in it.
if (!colGeo.querySelector('.mj-live-grp, .mj-live-row:not([hidden])')) {
// The hidden fields go with it. They are detached, not destroyed:
// state.fields still holds them, and getValue()/Save read the
Expand Down Expand Up @@ -9609,8 +9621,18 @@
// A button and a body under it. The body is hidden="until-found" rather
// than display:none, so the browser's own find-in-page reaches a setting
// inside it and opens it on the way (beforematch), the same as the "?"
// folds. Returns the body, which is where the group's rows are drawn.
// folds.
//
// It goes UNDER the card's two columns, full width, and holds a pair of
// columns of its own, dealt like any other card's when it opens. Inside
// the first column it made the whole card one narrow column: the rows
// above it fell under SOLO_MAX, and the fold's eleven rows then ran down
// that same column when opened. For the same reason the rows above it are
// never solo -- they are not a card of a handful of rows, they are the
// head of one whose rest is folded. Returns the column the group's rows
// are drawn into.
function groupFold(box, sec, name) {
const outer = box.parentNode;
const wrap = el('div', 'mj-grp-fold');
const btn = el('button', 'mj-grp-fold-btn');
btn.type = 'button';
Expand All @@ -9619,14 +9641,20 @@
const body = el('div', 'mj-grp-fold-body');
body.id = 'mj-fold-' + sec + '-' + name.toLowerCase().replace(/[^a-z0-9]+/g, '-');
btn.setAttribute('aria-controls', body.id);
const cols = el('div', 'mj-cols');
cols.appendChild(el('div', 'mj-col'));
cols.appendChild(el('div', 'mj-col'));
body.appendChild(cols);
state.cols.push(cols);
wrap.appendChild(btn);
wrap.appendChild(body);
box.appendChild(wrap);
outer.dataset.solo = 'off';
outer.after(wrap);
setGroupFold(wrap, false);
btn.addEventListener('click', () =>
setGroupFold(wrap, btn.getAttribute('aria-expanded') !== 'true'));
body.addEventListener('beforematch', () => setGroupFold(wrap, true));
return body;
return cols.firstElementChild;
}

function setGroupFold(wrap, open) {
Expand All @@ -9636,6 +9664,13 @@
btn.setAttribute('aria-expanded', String(open));
if (open) body.removeAttribute('hidden');
else body.setAttribute('hidden', 'until-found');
// Shut, the rows measure nothing and were dealt as nothing; open, they
// are dealt now that they have a height. Moving them cannot move the
// button, which is above them.
if (open) {
dealCols(body.querySelector(':scope > .mj-cols'));
foldHints();
}
}

// Opens, never shuts: a fold holding a row that is set away from stock, or
Expand Down Expand Up @@ -10011,7 +10046,7 @@
// heading would be dealt into two columns while claiming to be under the
// limit.
const shown = items.filter(it => it.offsetHeight && it.classList.contains('mj-row')).length;
const solo = shown <= SOLO_MAX;
const solo = box.dataset.solo !== 'off' && shown <= SOLO_MAX;
box.classList.toggle('mj-solo', solo);
if (solo) {
if (b.childElementCount) {
Expand Down
8 changes: 6 additions & 2 deletions www/a/mj-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,12 @@
{ id: 'picture', label: 'Clarity', keys: ['dehaze'] },
{ id: 'exposure', label: 'Exposure and gain', fold: 'More exposure settings',
keys: ['exposure', 'aGain', 'dGain', 'ispGain'] },
// Ahead of How it reacts, not after it: the fold is dealt into two
// columns and cut only between headings, and last it left four
// rows beside seven -- 560px of column beside 1030. Here it closes
// the first column under the gains.
{ id: 'tuning', label: 'For tuning engineers', fold: 'More exposure settings',
keys: ['externalTuner'] },
// `activeWhen` is the note's claim as a condition: the page sets
// these rows back while the mode says otherwise. They stay
// editable -- the daemon writes them in manual too, so a value is
Expand All @@ -376,8 +382,6 @@
fold: 'More exposure settings',
activeWhen: { field: 'aeMode', equals: 'auto' },
keys: ['meterRect', 'aeStrategy', 'aeSpeed', 'aeTolerance', 'aeBlackDelay', 'aeWhiteDelay'] },
{ id: 'tuning', label: 'For tuning engineers', fold: 'More exposure settings',
keys: ['externalTuner'] },
],
};
function sectionGroups(section) { return SECTION_GROUPS[section] || null; }
Expand Down
Loading