settings_ui: Filter to get project settings (#39730)
Closes #ISSUE Release Notes: - N/A *or* Added/Fixed/Improved ... --------- Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Co-authored-by: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
co-authored by
Danilo Leal
Mikayla Maki
parent
69ac003bc9
commit
f652c3a14d
+1250
-1648
File diff suppressed because it is too large
Load Diff
@@ -673,6 +673,55 @@ struct SettingItem {
|
||||
description: &'static str,
|
||||
field: Box<dyn AnySettingField>,
|
||||
metadata: Option<Box<SettingsFieldMetadata>>,
|
||||
files: FileMask,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
struct FileMask(u8);
|
||||
|
||||
impl std::fmt::Debug for FileMask {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "FileMask(")?;
|
||||
let mut items = vec![];
|
||||
|
||||
if self.contains(USER) {
|
||||
items.push("USER");
|
||||
}
|
||||
if self.contains(LOCAL) {
|
||||
items.push("LOCAL");
|
||||
}
|
||||
if self.contains(SERVER) {
|
||||
items.push("SERVER");
|
||||
}
|
||||
|
||||
write!(f, "{})", items.join(" | "))
|
||||
}
|
||||
}
|
||||
|
||||
const USER: FileMask = FileMask(1 << 0);
|
||||
const LOCAL: FileMask = FileMask(1 << 2);
|
||||
const SERVER: FileMask = FileMask(1 << 3);
|
||||
|
||||
impl std::ops::BitAnd for FileMask {
|
||||
type Output = Self;
|
||||
|
||||
fn bitand(self, other: Self) -> Self {
|
||||
Self(self.0 & other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::BitOr for FileMask {
|
||||
type Output = Self;
|
||||
|
||||
fn bitor(self, other: Self) -> Self {
|
||||
Self(self.0 | other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl FileMask {
|
||||
fn contains(&self, other: FileMask) -> bool {
|
||||
self.0 & other.0 != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for SettingItem {
|
||||
@@ -690,6 +739,7 @@ impl PartialEq for SettingItem {
|
||||
#[derive(Clone)]
|
||||
struct SubPageLink {
|
||||
title: &'static str,
|
||||
files: FileMask,
|
||||
render: Arc<
|
||||
dyn Fn(&mut SettingsWindow, &mut Window, &mut Context<SettingsWindow>) -> AnyElement
|
||||
+ 'static
|
||||
@@ -713,14 +763,6 @@ enum SettingsUiFile {
|
||||
}
|
||||
|
||||
impl SettingsUiFile {
|
||||
fn pages(&self) -> Vec<SettingsPage> {
|
||||
match self {
|
||||
SettingsUiFile::User => page_data::user_settings_data(),
|
||||
SettingsUiFile::Local(_) => page_data::project_settings_data(),
|
||||
SettingsUiFile::Server(_) => page_data::user_settings_data(),
|
||||
}
|
||||
}
|
||||
|
||||
fn name(&self) -> SharedString {
|
||||
match self {
|
||||
SettingsUiFile::User => SharedString::new_static("User"),
|
||||
@@ -748,6 +790,14 @@ impl SettingsUiFile {
|
||||
SettingsUiFile::Server(_) => settings::SettingsFile::Server,
|
||||
}
|
||||
}
|
||||
|
||||
fn mask(&self) -> FileMask {
|
||||
match self {
|
||||
SettingsUiFile::User => USER,
|
||||
SettingsUiFile::Local(_) => LOCAL,
|
||||
SettingsUiFile::Server(_) => SERVER,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SettingsWindow {
|
||||
@@ -939,6 +989,45 @@ impl SettingsWindow {
|
||||
})
|
||||
}
|
||||
|
||||
fn filter_matches_to_file(&mut self) {
|
||||
let current_file = self.current_file.mask();
|
||||
for (page, page_filter) in std::iter::zip(&self.pages, &mut self.search_matches) {
|
||||
let mut header_index = 0;
|
||||
let mut any_found_since_last_header = true;
|
||||
|
||||
for (index, item) in page.items.iter().enumerate() {
|
||||
match item {
|
||||
SettingsPageItem::SectionHeader(_) => {
|
||||
if !any_found_since_last_header {
|
||||
page_filter[header_index] = false;
|
||||
}
|
||||
header_index = index;
|
||||
any_found_since_last_header = false;
|
||||
}
|
||||
SettingsPageItem::SettingItem(setting_item) => {
|
||||
if !setting_item.files.contains(current_file) {
|
||||
page_filter[index] = false;
|
||||
} else {
|
||||
any_found_since_last_header = true;
|
||||
}
|
||||
}
|
||||
SettingsPageItem::SubPageLink(sub_page_link) => {
|
||||
if !sub_page_link.files.contains(current_file) {
|
||||
page_filter[index] = false;
|
||||
} else {
|
||||
any_found_since_last_header = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(last_header) = page_filter.get_mut(header_index)
|
||||
&& !any_found_since_last_header
|
||||
{
|
||||
*last_header = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_matches(&mut self, cx: &mut Context<SettingsWindow>) {
|
||||
self.search_task.take();
|
||||
let query = self.search_bar.read(cx).text(cx);
|
||||
@@ -946,6 +1035,7 @@ impl SettingsWindow {
|
||||
for page in &mut self.search_matches {
|
||||
page.fill(true);
|
||||
}
|
||||
self.filter_matches_to_file();
|
||||
cx.notify();
|
||||
return;
|
||||
}
|
||||
@@ -1011,6 +1101,7 @@ impl SettingsWindow {
|
||||
page[header_index] = true;
|
||||
page[item_index] = true;
|
||||
}
|
||||
this.filter_matches_to_file();
|
||||
let first_navbar_entry_index = this
|
||||
.visible_navbar_entries()
|
||||
.next()
|
||||
@@ -1032,13 +1123,13 @@ impl SettingsWindow {
|
||||
}
|
||||
|
||||
fn build_ui(&mut self, cx: &mut Context<SettingsWindow>) {
|
||||
self.pages = self.current_file.pages();
|
||||
if self.pages.is_empty() {
|
||||
self.pages = page_data::settings_data();
|
||||
}
|
||||
self.build_search_matches();
|
||||
self.build_navbar();
|
||||
|
||||
if !self.search_bar.read(cx).is_empty(cx) {
|
||||
self.update_matches(cx);
|
||||
}
|
||||
self.update_matches(cx);
|
||||
|
||||
cx.notify();
|
||||
}
|
||||
@@ -1878,6 +1969,7 @@ mod test {
|
||||
impl SettingsPageItem {
|
||||
fn basic_item(title: &'static str, description: &'static str) -> Self {
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
files: USER,
|
||||
title,
|
||||
description,
|
||||
field: Box::new(SettingField {
|
||||
|
||||
Reference in New Issue
Block a user