fix(compact): size the window to the strip instead of a tuned constant
compactH was 158px, "tuned so the compact entry strip fits in a single row". A constant tuned against a layout stops being true the moment the layout changes, and this one outlived a strip that had since shrunk — leaving about 70px of empty window under the fields. The frontend now measures what it rendered and asks for that height, watched by a ResizeObserver so a strip that wraps at a narrow width is followed too. The topbar is added as its declared h-8 rather than measured, since it is fixed. Bounded in the backend: a measurement of zero — a layout not yet painted — must not collapse the window, and the call is ignored unless compact is on so nothing can shrink the normal window. Rounded to whole pixels so a sub-pixel reflow cannot start a resize loop.
This commit is contained in:
@@ -17774,3 +17774,29 @@ func (a *App) SetSpotTTLMinutes(min int) error {
|
|||||||
a.setSetting(keyClusterSpotTTL, strconv.Itoa(min))
|
a.setSetting(keyClusterSpotTTL, strconv.Itoa(min))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetCompactHeight resizes the compact window to fit its content.
|
||||||
|
//
|
||||||
|
// The height used to be a constant "tuned so the compact entry strip fits in a
|
||||||
|
// single row". Constants tuned against a layout stop being true the moment the
|
||||||
|
// layout changes, and this one outlived a strip that had since lost a row —
|
||||||
|
// leaving a band of empty window under the fields. The frontend measures what
|
||||||
|
// it actually rendered and says so.
|
||||||
|
//
|
||||||
|
// Ignored unless compact is on, so nothing can shrink the normal window.
|
||||||
|
func (a *App) SetCompactHeight(h int) {
|
||||||
|
if a.ctx == nil || !a.compact {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Bounded: a measurement of zero (a layout not yet painted) must not collapse
|
||||||
|
// the window to nothing, and no strip is ever 600px tall.
|
||||||
|
if h < 80 || h > 600 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w, _ := wruntime.WindowGetSize(a.ctx)
|
||||||
|
if w <= 0 {
|
||||||
|
w = compactW
|
||||||
|
}
|
||||||
|
wruntime.WindowSetMinSize(a.ctx, 900, h)
|
||||||
|
wruntime.WindowSetSize(a.ctx, w, h)
|
||||||
|
}
|
||||||
|
|||||||
+4
-2
@@ -7,14 +7,16 @@
|
|||||||
"DX Cluster: a spot lifetime can be set — 5, 10, 15 minutes or your own value — after which spots leave the list and the band maps.",
|
"DX Cluster: a spot lifetime can be set — 5, 10, 15 minutes or your own value — after which spots leave the list and the band maps.",
|
||||||
"Call lookup: QRZ.com now fills Name with the first name only, and optionally with the operator nickname instead.",
|
"Call lookup: QRZ.com now fills Name with the first name only, and optionally with the operator nickname instead.",
|
||||||
"Entry form: a narrower left column, State beside the locator, and a new line with County, CQ, ITU and DXCC.",
|
"Entry form: a narrower left column, State beside the locator, and a new line with County, CQ, ITU and DXCC.",
|
||||||
"Station Control: the short and long path headings are repeated under the compass, at a readable size and clickable."
|
"Station Control: the short and long path headings are repeated under the compass, at a readable size and clickable.",
|
||||||
|
"Compact mode: the window now fits the entry strip instead of leaving a band of empty space below it."
|
||||||
],
|
],
|
||||||
"fr": [
|
"fr": [
|
||||||
"Cluster : « Masquer les contactés » ne masque plus un spot qui est un nouveau préfixe, comté, carré ou parc dans une contrée déjà faite.",
|
"Cluster : « Masquer les contactés » ne masque plus un spot qui est un nouveau préfixe, comté, carré ou parc dans une contrée déjà faite.",
|
||||||
"Cluster DX : on peut fixer une durée de vie des spots — 5, 10, 15 minutes ou une valeur libre — au-delà de laquelle ils quittent la liste et les band maps.",
|
"Cluster DX : on peut fixer une durée de vie des spots — 5, 10, 15 minutes ou une valeur libre — au-delà de laquelle ils quittent la liste et les band maps.",
|
||||||
"Recherche d indicatif : QRZ.com remplit désormais Nom avec le seul prénom, et au choix avec le surnom de l opérateur.",
|
"Recherche d indicatif : QRZ.com remplit désormais Nom avec le seul prénom, et au choix avec le surnom de l opérateur.",
|
||||||
"Saisie : colonne de gauche plus étroite, État à côté du locator, et une nouvelle ligne Comté, CQ, ITU et DXCC.",
|
"Saisie : colonne de gauche plus étroite, État à côté du locator, et une nouvelle ligne Comté, CQ, ITU et DXCC.",
|
||||||
"Contrôle station : les azimuts court et long chemin sont repris sous la boussole, lisibles et cliquables."
|
"Contrôle station : les azimuts court et long chemin sont repris sous la boussole, lisibles et cliquables.",
|
||||||
|
"Mode compact : la fenêtre épouse la bande de saisie au lieu de laisser une bande vide en dessous."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
+24
-2
@@ -16,7 +16,7 @@ import {
|
|||||||
GetStartupStatus, CheckForUpdate, DownloadAndApplyUpdate, GetLiveStations, GetWhatsNew, GetChangelog,
|
GetStartupStatus, CheckForUpdate, DownloadAndApplyUpdate, GetLiveStations, GetWhatsNew, GetChangelog,
|
||||||
SMTPConfigured, SendLogToDeveloper,
|
SMTPConfigured, SendLogToDeveloper,
|
||||||
WorkedBefore,
|
WorkedBefore,
|
||||||
SetCompactMode,
|
SetCompactMode, SetCompactHeight,
|
||||||
GetCATState, SetCATFrequency, SetCATMode, SwitchCATRig, FlexApplyBandAntenna, FlexApplyBandPower,
|
GetCATState, SetCATFrequency, SetCATMode, SwitchCATRig, FlexApplyBandAntenna, FlexApplyBandPower,
|
||||||
GetSecretStatus, UnlockSecrets,
|
GetSecretStatus, UnlockSecrets,
|
||||||
RefreshCtyDat, DownloadAllReferenceLists,
|
RefreshCtyDat, DownloadAllReferenceLists,
|
||||||
@@ -529,6 +529,28 @@ export default function App() {
|
|||||||
setCompact(next);
|
setCompact(next);
|
||||||
SetCompactMode(next);
|
SetCompactMode(next);
|
||||||
}
|
}
|
||||||
|
// Fit the compact window to what was actually rendered.
|
||||||
|
//
|
||||||
|
// The height was a constant "tuned so the compact entry strip fits in a single
|
||||||
|
// row". A constant tuned against a layout stops being true the moment the
|
||||||
|
// layout changes, and this one outlived a strip that had since lost a row —
|
||||||
|
// leaving a band of empty window under the fields. Measure instead.
|
||||||
|
const compactRootRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!compact) return;
|
||||||
|
const fit = () => {
|
||||||
|
const el = compactRootRef.current;
|
||||||
|
if (!el) return;
|
||||||
|
// Rounded, so a sub-pixel reflow cannot start a resize loop.
|
||||||
|
// + the compact topbar, which is a fixed h-8 (32px), + a couple of pixels
|
||||||
|
// for the border so the strip is never clipped by one row of anti-aliasing.
|
||||||
|
SetCompactHeight(Math.round(el.getBoundingClientRect().height) + 32 + 2);
|
||||||
|
};
|
||||||
|
const id = window.setTimeout(fit, 60); // let the strip paint first
|
||||||
|
const ro = new ResizeObserver(fit);
|
||||||
|
if (compactRootRef.current) ro.observe(compactRootRef.current);
|
||||||
|
return () => { window.clearTimeout(id); ro.disconnect(); };
|
||||||
|
}, [compact]);
|
||||||
|
|
||||||
// CAT — receives live rig state via Wails events.
|
// CAT — receives live rig state via Wails events.
|
||||||
const [catState, setCatState] = useState<CATState>({ enabled: false, connected: false } as any);
|
const [catState, setCatState] = useState<CATState>({ enabled: false, connected: false } as any);
|
||||||
@@ -5892,7 +5914,7 @@ export default function App() {
|
|||||||
Enter from any <input> inside the strip logs the QSO. Radix Selects
|
Enter from any <input> inside the strip logs the QSO. Radix Selects
|
||||||
render as <button> elements and are ignored by this handler — they
|
render as <button> elements and are ignored by this handler — they
|
||||||
keep their own keyboard behaviour. */}
|
keep their own keyboard behaviour. */}
|
||||||
<div className={cn(!compact && 'flex gap-2.5 items-stretch px-2.5 pt-2.5 shrink-0')}>
|
<div ref={compactRootRef} className={cn(!compact && 'flex gap-2.5 items-stretch px-2.5 pt-2.5 shrink-0')}>
|
||||||
<section
|
<section
|
||||||
className={cn('bg-card shadow-sm border-border',
|
className={cn('bg-card shadow-sm border-border',
|
||||||
compact
|
compact
|
||||||
|
|||||||
Vendored
+2
@@ -988,6 +988,8 @@ export function SetClublogMostWantedEnabled(arg1:boolean):Promise<void>;
|
|||||||
|
|
||||||
export function SetClusterAutoConnect(arg1:boolean):Promise<void>;
|
export function SetClusterAutoConnect(arg1:boolean):Promise<void>;
|
||||||
|
|
||||||
|
export function SetCompactHeight(arg1:number):Promise<void>;
|
||||||
|
|
||||||
export function SetCompactMode(arg1:boolean):Promise<void>;
|
export function SetCompactMode(arg1:boolean):Promise<void>;
|
||||||
|
|
||||||
export function SetDVKLabel(arg1:number,arg2:string):Promise<void>;
|
export function SetDVKLabel(arg1:number,arg2:string):Promise<void>;
|
||||||
|
|||||||
@@ -1918,6 +1918,10 @@ export function SetClusterAutoConnect(arg1) {
|
|||||||
return window['go']['main']['App']['SetClusterAutoConnect'](arg1);
|
return window['go']['main']['App']['SetClusterAutoConnect'](arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function SetCompactHeight(arg1) {
|
||||||
|
return window['go']['main']['App']['SetCompactHeight'](arg1);
|
||||||
|
}
|
||||||
|
|
||||||
export function SetCompactMode(arg1) {
|
export function SetCompactMode(arg1) {
|
||||||
return window['go']['main']['App']['SetCompactMode'](arg1);
|
return window['go']['main']['App']['SetCompactMode'](arg1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user