use unicode_width::UnicodeWidthStr;
use super::super::OptionalRepos;
use super::types::{
ArtixVisibilityContext, CoreFilterLabels, OptionalReposLabels, TitleI18nStrings,
TitleLayoutInfo,
};
use super::width::{
calculate_base_consumed_space, calculate_consumed_without_specific,
calculate_optional_repos_width, create_repos_without_specific,
};
fn determine_initial_artix_visibility(
base_consumed: u16,
consumed_left: u16,
inner_width: u16,
right_w: u16,
optional_repos: &OptionalRepos,
optional_labels: &OptionalReposLabels,
) -> (bool, u16, u16) {
let pad = inner_width.saturating_sub(consumed_left.saturating_add(right_w));
if pad >= 1 {
return (true, consumed_left, pad);
}
let repos_without_specific = create_repos_without_specific(optional_repos);
let consumed_without_specific = calculate_consumed_without_specific(
base_consumed,
&repos_without_specific,
optional_labels,
optional_repos.has_artix,
);
let new_pad = inner_width.saturating_sub(consumed_without_specific.saturating_add(right_w));
if new_pad >= 1 {
(false, consumed_without_specific, new_pad)
} else {
(true, consumed_left, pad)
}
}
fn adjust_artix_visibility_for_collapsed_menu(
show_artix_specific_repos: bool,
ctx: &ArtixVisibilityContext,
optional_repos: &OptionalRepos,
optional_labels: &OptionalReposLabels,
) -> (bool, u16) {
if !show_artix_specific_repos {
return (false, ctx.final_consumed_left);
}
let space_with_filters = ctx
.consumed_left
.saturating_add(ctx.menu_w)
.saturating_add(1);
let repos_without_specific = create_repos_without_specific(optional_repos);
let consumed_without_specific = calculate_consumed_without_specific(
ctx.base_consumed,
&repos_without_specific,
optional_labels,
optional_repos.has_artix,
);
let space_without_filters = consumed_without_specific
.saturating_add(ctx.menu_w)
.saturating_add(1);
if ctx.inner_width < space_with_filters && ctx.inner_width >= space_without_filters {
(false, consumed_without_specific)
} else {
(show_artix_specific_repos, ctx.final_consumed_left)
}
}
fn finalize_artix_visibility_when_menu_cant_fit(
show_artix_specific_repos: bool,
consumed_left: u16,
inner_width: u16,
menu_w: u16,
base_consumed: u16,
optional_repos: &OptionalRepos,
optional_labels: &OptionalReposLabels,
) -> (bool, u16) {
if !show_artix_specific_repos {
return (false, consumed_left);
}
let space_needed_with_filters = consumed_left.saturating_add(menu_w).saturating_add(1);
if inner_width >= space_needed_with_filters {
return (true, consumed_left);
}
let repos_without_specific = create_repos_without_specific(optional_repos);
let consumed_without_specific = calculate_consumed_without_specific(
base_consumed,
&repos_without_specific,
optional_labels,
optional_repos.has_artix,
);
(false, consumed_without_specific)
}
pub(super) fn calculate_title_layout_info(
i18n: &TitleI18nStrings,
results_len: usize,
inner_width: u16,
optional_repos: &OptionalRepos,
custom_repos_chip_label: Option<String>,
reserve_right_menu_cluster: bool,
) -> TitleLayoutInfo {
let results_title_text = format!("{} ({})", i18n.results_title, results_len);
let sort_button_label = format!("{} v", i18n.sort_button);
let options_button_label = format!("{} v", i18n.options_button);
let panels_button_label = format!("{} v", i18n.panels_button);
let config_button_label = format!("{} v", i18n.config_button);
let menu_button_label = format!("{} v", i18n.menu_button);
let core_labels = CoreFilterLabels {
aur: format!("[{}]", i18n.filter_aur),
core: format!("[{}]", i18n.filter_core),
extra: format!("[{}]", i18n.filter_extra),
multilib: format!("[{}]", i18n.filter_multilib),
};
let optional_labels = OptionalReposLabels {
eos: format!("[{}]", i18n.filter_eos),
cachyos: format!("[{}]", i18n.filter_cachyos),
artix: format!("[{}]", i18n.filter_artix),
artix_omniverse: format!("[{}]", i18n.filter_artix_omniverse),
artix_universe: format!("[{}]", i18n.filter_artix_universe),
artix_lib32: format!("[{}]", i18n.filter_artix_lib32),
artix_galaxy: format!("[{}]", i18n.filter_artix_galaxy),
artix_world: format!("[{}]", i18n.filter_artix_world),
artix_system: format!("[{}]", i18n.filter_artix_system),
blackarch: format!("[{}]", i18n.filter_blackarch),
manjaro: format!("[{}]", i18n.filter_manjaro),
};
let base_consumed =
calculate_base_consumed_space(&results_title_text, &sort_button_label, &core_labels);
let optional_consumed = calculate_optional_repos_width(optional_repos, &optional_labels);
let custom_extra = custom_repos_chip_label.as_ref().map_or(0u16, |s| {
1u16.saturating_add(u16::try_from(s.width()).unwrap_or(u16::MAX))
});
let consumed_left = base_consumed
.saturating_add(optional_consumed)
.saturating_add(custom_extra);
let options_w = u16::try_from(options_button_label.width()).unwrap_or(u16::MAX);
let panels_w = u16::try_from(panels_button_label.width()).unwrap_or(u16::MAX);
let config_w = u16::try_from(config_button_label.width()).unwrap_or(u16::MAX);
let menu_w = u16::try_from(menu_button_label.width()).unwrap_or(u16::MAX);
let right_w = if reserve_right_menu_cluster {
config_w
.saturating_add(1)
.saturating_add(panels_w)
.saturating_add(1)
.saturating_add(options_w)
} else {
0
};
let (mut show_artix_specific_repos, mut final_consumed_left, pad) =
determine_initial_artix_visibility(
base_consumed,
consumed_left,
inner_width,
right_w,
optional_repos,
&optional_labels,
);
if pad < 1 && show_artix_specific_repos {
let ctx = ArtixVisibilityContext {
consumed_left,
final_consumed_left,
inner_width,
menu_w,
base_consumed,
};
let (new_show, new_consumed) = adjust_artix_visibility_for_collapsed_menu(
show_artix_specific_repos,
&ctx,
optional_repos,
&optional_labels,
);
show_artix_specific_repos = new_show;
final_consumed_left = new_consumed;
}
let use_collapsed_menu = if pad < 1 {
let space_needed_for_menu = final_consumed_left.saturating_add(menu_w).saturating_add(1);
inner_width >= space_needed_for_menu
} else {
false
};
if !use_collapsed_menu && pad < 1 {
let (new_show, _new_consumed) = finalize_artix_visibility_when_menu_cant_fit(
show_artix_specific_repos,
consumed_left,
inner_width,
menu_w,
base_consumed,
optional_repos,
&optional_labels,
);
show_artix_specific_repos = new_show;
}
TitleLayoutInfo {
results_title_text,
sort_button_label,
core_labels,
optional_labels,
show_artix_specific_repos,
custom_repos_chip_label,
}
}