diff --git a/Cargo.lock b/Cargo.lock index 5ad448cc148d5d077c756515717853ffe2d09186..371ab812a66652f6e6915a0b4198dfcba9b0bd78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20027,6 +20027,7 @@ dependencies = [ "nix 0.29.0", "node_runtime", "notifications", + "onboarding_ui", "outline", "outline_panel", "parking_lot", diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 5f0b5b9345a79d2af996c3a783c5e4e7dade616c..75a060da6a4367e1b16700b726bed7383920795d 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -4,7 +4,10 @@ use feature_flags::FeatureFlagAppExt as _; use gpui::{Entity, EventEmitter, FocusHandle, Focusable, WeakEntity, actions, prelude::*}; use settings_ui::SettingsUiFeatureFlag; use ui::prelude::*; -use workspace::Workspace; +use workspace::{ + Workspace, WorkspaceId, + item::{Item, ItemEvent}, +}; actions!( onboarding, @@ -21,6 +24,71 @@ actions!( ] ); +pub fn init(cx: &mut App) { + cx.observe_new(|workspace: &mut Workspace, _, _cx| { + workspace.register_action(|workspace, _: &ShowOnboarding, window, cx| { + let onboarding = cx.new(|cx| OnboardingUI::new(workspace, cx)); + workspace.add_item_to_active_pane(Box::new(onboarding), None, true, window, cx); + }); + + workspace.register_action(|_workspace, _: &JumpToBasics, _window, _cx| { + // Jump to basics implementation + }); + + workspace.register_action(|_workspace, _: &JumpToEditing, _window, _cx| { + // Jump to editing implementation + }); + + workspace.register_action(|_workspace, _: &JumpToAiSetup, _window, _cx| { + // Jump to AI setup implementation + }); + + workspace.register_action(|_workspace, _: &JumpToWelcome, _window, _cx| { + // Jump to welcome implementation + }); + + workspace.register_action(|_workspace, _: &NextPage, _window, _cx| { + // Next page implementation + }); + + workspace.register_action(|_workspace, _: &PreviousPage, _window, _cx| { + // Previous page implementation + }); + + workspace.register_action(|_workspace, _: &ToggleFocus, _window, _cx| { + // Toggle focus implementation + }); + + workspace.register_action(|_workspace, _: &ResetOnboarding, _window, _cx| { + // Reset onboarding implementation + }); + }) + .detach(); + + feature_gate_onboarding_ui_actions(cx); +} + +fn feature_gate_onboarding_ui_actions(cx: &mut App) { + const ONBOARDING_ACTION_NAMESPACE: &str = "onboarding"; + + CommandPaletteFilter::update_global(cx, |filter, _cx| { + filter.hide_namespace(ONBOARDING_ACTION_NAMESPACE); + }); + + cx.observe_flag::({ + move |is_enabled, cx| { + CommandPaletteFilter::update_global(cx, |filter, _cx| { + if is_enabled { + filter.show_namespace(ONBOARDING_ACTION_NAMESPACE); + } else { + filter.hide_namespace(ONBOARDING_ACTION_NAMESPACE); + } + }); + } + }) + .detach(); +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum OnboardingPage { Basics, @@ -60,10 +128,23 @@ pub struct OnboardingUI { current_page: OnboardingPage, current_focus: OnboardingFocus, completed_pages: [bool; 4], + + // Page entities basics_page: Entity, editing_page: Entity, ai_setup_page: Entity, welcome_page: Entity, + + // Workspace reference for Item trait + workspace: WeakEntity, +} + +impl EventEmitter for OnboardingUI {} + +impl Focusable for OnboardingUI { + fn focus_handle(&self, _: &App) -> gpui::FocusHandle { + self.focus_handle.clone() + } } pub struct BasicsPage { @@ -93,19 +174,11 @@ pub enum OnboardingEvent { } // Implement EventEmitter for all entities -impl EventEmitter for OnboardingUI {} impl EventEmitter for BasicsPage {} impl EventEmitter for EditingPage {} impl EventEmitter for AiSetupPage {} impl EventEmitter for WelcomePage {} -// Implement Focusable for all entities -impl Focusable for OnboardingUI { - fn focus_handle(&self, _cx: &App) -> FocusHandle { - self.focus_handle.clone() - } -} - impl Focusable for BasicsPage { fn focus_handle(&self, _cx: &App) -> FocusHandle { self.focus_handle.clone() @@ -138,6 +211,9 @@ impl Render for OnboardingUI { _cx: &mut Context, ) -> impl gpui::IntoElement { h_flex() + .id("onboarding-ui") + .key_context("Onboarding") + .track_focus(&self.focus_handle) .w(px(904.)) .h(px(500.)) .gap(px(48.)) @@ -186,7 +262,7 @@ impl Render for WelcomePage { } impl OnboardingUI { - pub fn new(cx: &mut Context) -> Self { + pub fn new(workspace: &Workspace, cx: &mut Context) -> Self { let parent_handle = cx.entity().downgrade(); let basics_page = cx.new(|cx| BasicsPage { @@ -218,6 +294,7 @@ impl OnboardingUI { editing_page, ai_setup_page, welcome_page, + workspace: workspace.weak_handle(), } } @@ -277,66 +354,34 @@ impl OnboardingUI { } } -pub fn init(cx: &mut App) { - cx.observe_new(|workspace: &mut Workspace, _, _cx| { - workspace.register_action(|_workspace, _: &ShowOnboarding, _window, _cx| { - // Show onboarding implementation will go here - }); - - workspace.register_action(|_workspace, _: &JumpToBasics, _window, _cx| { - // Jump to basics implementation - }); - - workspace.register_action(|_workspace, _: &JumpToEditing, _window, _cx| { - // Jump to editing implementation - }); - - workspace.register_action(|_workspace, _: &JumpToAiSetup, _window, _cx| { - // Jump to AI setup implementation - }); - - workspace.register_action(|_workspace, _: &JumpToWelcome, _window, _cx| { - // Jump to welcome implementation - }); - - workspace.register_action(|_workspace, _: &NextPage, _window, _cx| { - // Next page implementation - }); - - workspace.register_action(|_workspace, _: &PreviousPage, _window, _cx| { - // Previous page implementation - }); - - workspace.register_action(|_workspace, _: &ToggleFocus, _window, _cx| { - // Toggle focus implementation - }); +impl Item for OnboardingUI { + type Event = ItemEvent; - workspace.register_action(|_workspace, _: &ResetOnboarding, _window, _cx| { - // Reset onboarding implementation - }); - }) - .detach(); - - feature_gate_onboarding_ui_actions(cx); -} + fn tab_content_text(&self, _detail: usize, _cx: &App) -> SharedString { + "Onboarding".into() + } -fn feature_gate_onboarding_ui_actions(cx: &mut App) { - const ONBOARDING_ACTION_NAMESPACE: &str = "onboarding"; + fn to_item_events(event: &Self::Event, mut f: impl FnMut(ItemEvent)) { + f(event.clone()) + } - CommandPaletteFilter::update_global(cx, |filter, _cx| { - filter.hide_namespace(ONBOARDING_ACTION_NAMESPACE); - }); + fn show_toolbar(&self) -> bool { + false + } - cx.observe_flag::({ - move |is_enabled, cx| { - CommandPaletteFilter::update_global(cx, |filter, _cx| { - if is_enabled { - filter.show_namespace(ONBOARDING_ACTION_NAMESPACE); - } else { - filter.hide_namespace(ONBOARDING_ACTION_NAMESPACE); - } - }); + fn clone_on_split( + &self, + _workspace_id: Option, + window: &mut Window, + cx: &mut Context, + ) -> Option> { + let weak_workspace = self.workspace.clone(); + if let Some(workspace) = weak_workspace.upgrade() { + workspace.update(cx, |workspace, cx| { + Some(cx.new(|cx| OnboardingUI::new(workspace, cx))) + }) + } else { + None } - }) - .detach(); + } } diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index 4e426c3837f969802d0dc75de872412cae0567a5..2b89e65c57c8f03a8854df03e4546ac19a8e9246 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -21,8 +21,8 @@ path = "src/main.rs" [dependencies] activity_indicator.workspace = true agent.workspace = true -agent_ui.workspace = true agent_settings.workspace = true +agent_ui.workspace = true anyhow.workspace = true askpass.workspace = true assets.workspace = true @@ -65,7 +65,6 @@ git_ui.workspace = true go_to_line.workspace = true gpui = { workspace = true, features = ["wayland", "x11", "font-kit"] } gpui_tokio.workspace = true - http_client.workspace = true image_viewer.workspace = true indoc.workspace = true @@ -85,13 +84,13 @@ libc.workspace = true log.workspace = true markdown.workspace = true markdown_preview.workspace = true -svg_preview.workspace = true menu.workspace = true migrator.workspace = true mimalloc = { version = "0.1", optional = true } nix = { workspace = true, features = ["pthread", "signal"] } node_runtime.workspace = true notifications.workspace = true +onboarding_ui.workspace = true outline.workspace = true outline_panel.workspace = true parking_lot.workspace = true @@ -120,6 +119,7 @@ smol.workspace = true snippet_provider.workspace = true snippets_ui.workspace = true supermaven.workspace = true +svg_preview.workspace = true sysinfo.workspace = true tab_switcher.workspace = true task.workspace = true diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 00a1f150eae5bb87e62fd52f1464101e3a9fd750..9d6a497e999490ab9df0de8a668701c94b1a926d 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -580,6 +580,7 @@ pub fn main() { collab_ui::init(&app_state, cx); git_ui::init(cx); jj_ui::init(cx); + onboarding_ui::init(cx); feedback::init(cx); markdown_preview::init(cx); svg_preview::init(cx);