34 lines
1.6 KiB
Dart
34 lines
1.6 KiB
Dart
/// 한 줄 · 두 줄 배치 판단 (관리자 지시 10/21: 화면마다 따로 재지 않고 이것 하나를 부른다 - d3 설계의 AdaptiveRow 자리).
|
|
///
|
|
/// 약속
|
|
/// - 입력: [maxWidth] 쓸 수 있는 폭, [first] · [second] 앞 · 뒤 묶음 아이템의 최소 폭 (단추는 기본 누를 자리 그대로),
|
|
/// [gap] 한 줄일 때 두 묶음 사이, 줄일 수 있는 아이템 하나의 폭 범위 [flexMin] ~ [flexMax] (없으면 0 · 0).
|
|
/// - 출력: [RowFit.split] 이면 두 줄 (위 = first, 아래 = second + 줄일 수 있는 아이템), [RowFit.flexWidth] 줄일 수 있는 아이템의 폭
|
|
/// (0 이면 그 줄에 넣지 않는다 - 같은 일을 하는 다른 단추가 남아 있어야 한다).
|
|
/// - 오류: 없음. 두 줄로도 [second] 가 들지 않으면 split = true · flexWidth = 0 이고 [RowFit.overflow] 에 모자란 폭.
|
|
class RowFit {
|
|
final bool split;
|
|
final double flexWidth;
|
|
final double overflow;
|
|
const RowFit(this.split, this.flexWidth, this.overflow);
|
|
}
|
|
|
|
RowFit fitRow({
|
|
required double maxWidth,
|
|
required List<double> first,
|
|
required List<double> second,
|
|
double gap = 0,
|
|
double flexMin = 0,
|
|
double flexMax = 0,
|
|
bool forceSplit = false,
|
|
}) {
|
|
double sum(List<double> xs) => xs.fold(0.0, (a, b) => a + b);
|
|
final a = sum(first), b = sum(second);
|
|
final split = forceSplit || a + gap + b + flexMax > maxWidth;
|
|
final room = maxWidth - b - (split ? 0 : a + gap);
|
|
var flex = room.clamp(0.0, flexMax);
|
|
if (flex < flexMin) flex = 0;
|
|
final over = (split ? [a, b].reduce((x, y) => x > y ? x : y) : a + gap + b) - maxWidth;
|
|
return RowFit(split, flex, over > 0 ? over : 0);
|
|
}
|