
There's still a bit more work to do on this, but this PR is compiling (with warnings) after eliminating the key types. When the tasks below are complete, this will be the new narrative for GPUI: - `Entity<T>` - This replaces `View<T>`/`Model<T>`. It represents a unit of state, and if `T` implements `Render`, then `Entity<T>` implements `Element`. - `&mut App` This replaces `AppContext` and represents the app. - `&mut Context<T>` This replaces `ModelContext` and derefs to `App`. It is provided by the framework when updating an entity. - `&mut Window` Broken out of `&mut WindowContext` which no longer exists. Every method that once took `&mut WindowContext` now takes `&mut Window, &mut App` and every method that took `&mut ViewContext<T>` now takes `&mut Window, &mut Context<T>` Not pictured here are the two other failed attempts. It's been quite a month! Tasks: - [x] Remove `View`, `ViewContext`, `WindowContext` and thread through `Window` - [x] [@cole-miller @mikayla-maki] Redraw window when entities change - [x] [@cole-miller @mikayla-maki] Get examples and Zed running - [x] [@cole-miller @mikayla-maki] Fix Zed rendering - [x] [@mikayla-maki] Fix todo! macros and comments - [x] Fix a bug where the editor would not be redrawn because of view caching - [x] remove publicness window.notify() and replace with `AppContext::notify` - [x] remove `observe_new_window_models`, replace with `observe_new_models` with an optional window - [x] Fix a bug where the project panel would not be redrawn because of the wrong refresh() call being used - [x] Fix the tests - [x] Fix warnings by eliminating `Window` params or using `_` - [x] Fix conflicts - [x] Simplify generic code where possible - [x] Rename types - [ ] Update docs ### issues post merge - [x] Issues switching between normal and insert mode - [x] Assistant re-rendering failure - [x] Vim test failures - [x] Mac build issue Release Notes: - N/A --------- Co-authored-by: Antonio Scandurra <me@as-cii.com> Co-authored-by: Cole Miller <cole@zed.dev> Co-authored-by: Mikayla <mikayla@zed.dev> Co-authored-by: Joseph <joseph@zed.dev> Co-authored-by: max <max@zed.dev> Co-authored-by: Michael Sloan <michael@zed.dev> Co-authored-by: Mikayla Maki <mikaylamaki@Mikaylas-MacBook-Pro.local> Co-authored-by: Mikayla <mikayla.c.maki@gmail.com> Co-authored-by: joão <joao@zed.dev>
196 lines
5 KiB
Rust
196 lines
5 KiB
Rust
use crate::{Action, App, Platform, SharedString};
|
|
use util::ResultExt;
|
|
|
|
/// A menu of the application, either a main menu or a submenu
|
|
pub struct Menu {
|
|
/// The name of the menu
|
|
pub name: SharedString,
|
|
|
|
/// The items in the menu
|
|
pub items: Vec<MenuItem>,
|
|
}
|
|
|
|
impl Menu {
|
|
/// Create an OwnedMenu from this Menu
|
|
pub fn owned(self) -> OwnedMenu {
|
|
OwnedMenu {
|
|
name: self.name.to_string().into(),
|
|
items: self.items.into_iter().map(|item| item.owned()).collect(),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// The different kinds of items that can be in a menu
|
|
pub enum MenuItem {
|
|
/// A separator between items
|
|
Separator,
|
|
|
|
/// A submenu
|
|
Submenu(Menu),
|
|
|
|
/// An action that can be performed
|
|
Action {
|
|
/// The name of this menu item
|
|
name: SharedString,
|
|
|
|
/// the action to perform when this menu item is selected
|
|
action: Box<dyn Action>,
|
|
|
|
/// The OS Action that corresponds to this action, if any
|
|
/// See [`OsAction`] for more information
|
|
os_action: Option<OsAction>,
|
|
},
|
|
}
|
|
|
|
impl MenuItem {
|
|
/// Creates a new menu item that is a separator
|
|
pub fn separator() -> Self {
|
|
Self::Separator
|
|
}
|
|
|
|
/// Creates a new menu item that is a submenu
|
|
pub fn submenu(menu: Menu) -> Self {
|
|
Self::Submenu(menu)
|
|
}
|
|
|
|
/// Creates a new menu item that invokes an action
|
|
pub fn action(name: impl Into<SharedString>, action: impl Action) -> Self {
|
|
Self::Action {
|
|
name: name.into(),
|
|
action: Box::new(action),
|
|
os_action: None,
|
|
}
|
|
}
|
|
|
|
/// Creates a new menu item that invokes an action and has an OS action
|
|
pub fn os_action(
|
|
name: impl Into<SharedString>,
|
|
action: impl Action,
|
|
os_action: OsAction,
|
|
) -> Self {
|
|
Self::Action {
|
|
name: name.into(),
|
|
action: Box::new(action),
|
|
os_action: Some(os_action),
|
|
}
|
|
}
|
|
|
|
/// Create an OwnedMenuItem from this MenuItem
|
|
pub fn owned(self) -> OwnedMenuItem {
|
|
match self {
|
|
MenuItem::Separator => OwnedMenuItem::Separator,
|
|
MenuItem::Submenu(submenu) => OwnedMenuItem::Submenu(submenu.owned()),
|
|
MenuItem::Action {
|
|
name,
|
|
action,
|
|
os_action,
|
|
} => OwnedMenuItem::Action {
|
|
name: name.into(),
|
|
action,
|
|
os_action,
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
/// A menu of the application, either a main menu or a submenu
|
|
#[derive(Clone)]
|
|
pub struct OwnedMenu {
|
|
/// The name of the menu
|
|
pub name: SharedString,
|
|
|
|
/// The items in the menu
|
|
pub items: Vec<OwnedMenuItem>,
|
|
}
|
|
|
|
/// The different kinds of items that can be in a menu
|
|
pub enum OwnedMenuItem {
|
|
/// A separator between items
|
|
Separator,
|
|
|
|
/// A submenu
|
|
Submenu(OwnedMenu),
|
|
|
|
/// An action that can be performed
|
|
Action {
|
|
/// The name of this menu item
|
|
name: String,
|
|
|
|
/// the action to perform when this menu item is selected
|
|
action: Box<dyn Action>,
|
|
|
|
/// The OS Action that corresponds to this action, if any
|
|
/// See [`OsAction`] for more information
|
|
os_action: Option<OsAction>,
|
|
},
|
|
}
|
|
|
|
impl Clone for OwnedMenuItem {
|
|
fn clone(&self) -> Self {
|
|
match self {
|
|
OwnedMenuItem::Separator => OwnedMenuItem::Separator,
|
|
OwnedMenuItem::Submenu(submenu) => OwnedMenuItem::Submenu(submenu.clone()),
|
|
OwnedMenuItem::Action {
|
|
name,
|
|
action,
|
|
os_action,
|
|
} => OwnedMenuItem::Action {
|
|
name: name.clone(),
|
|
action: action.boxed_clone(),
|
|
os_action: *os_action,
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO: As part of the global selections refactor, these should
|
|
// be moved to GPUI-provided actions that make this association
|
|
// without leaking the platform details to GPUI users
|
|
|
|
/// OS actions are actions that are recognized by the operating system
|
|
/// This allows the operating system to provide specialized behavior for
|
|
/// these actions
|
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
|
pub enum OsAction {
|
|
/// The 'cut' action
|
|
Cut,
|
|
|
|
/// The 'copy' action
|
|
Copy,
|
|
|
|
/// The 'paste' action
|
|
Paste,
|
|
|
|
/// The 'select all' action
|
|
SelectAll,
|
|
|
|
/// The 'undo' action
|
|
Undo,
|
|
|
|
/// The 'redo' action
|
|
Redo,
|
|
}
|
|
|
|
pub(crate) fn init_app_menus(platform: &dyn Platform, cx: &App) {
|
|
platform.on_will_open_app_menu(Box::new({
|
|
let cx = cx.to_async();
|
|
move || {
|
|
cx.update(|cx| cx.clear_pending_keystrokes()).ok();
|
|
}
|
|
}));
|
|
|
|
platform.on_validate_app_menu_command(Box::new({
|
|
let cx = cx.to_async();
|
|
move |action| {
|
|
cx.update(|cx| cx.is_action_available(action))
|
|
.unwrap_or(false)
|
|
}
|
|
}));
|
|
|
|
platform.on_app_menu_action(Box::new({
|
|
let cx = cx.to_async();
|
|
move |action| {
|
|
cx.update(|cx| cx.dispatch_action(action)).log_err();
|
|
}
|
|
}));
|
|
}
|