Get workspace compiling with new event emitters
This commit is contained in:
parent
26fc36ee0e
commit
a97c8bf58f
24 changed files with 224 additions and 319 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -6109,7 +6109,6 @@ dependencies = [
|
||||||
"settings2",
|
"settings2",
|
||||||
"theme2",
|
"theme2",
|
||||||
"util",
|
"util",
|
||||||
"workspace2",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -17,6 +17,7 @@ use gpui::{
|
||||||
};
|
};
|
||||||
use postage::watch;
|
use postage::watch;
|
||||||
use project::Project;
|
use project::Project;
|
||||||
|
use room::Event;
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -85,9 +86,7 @@ pub struct ActiveCall {
|
||||||
_subscriptions: Vec<client::Subscription>,
|
_subscriptions: Vec<client::Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for ActiveCall {
|
impl EventEmitter<Event> for ActiveCall {}
|
||||||
type Event = room::Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ActiveCall {
|
impl ActiveCall {
|
||||||
fn new(client: Arc<Client>, user_store: Model<UserStore>, cx: &mut ModelContext<Self>) -> Self {
|
fn new(client: Arc<Client>, user_store: Model<UserStore>, cx: &mut ModelContext<Self>) -> Self {
|
||||||
|
|
|
@ -79,9 +79,7 @@ pub struct Room {
|
||||||
maintain_connection: Option<Task<Option<()>>>,
|
maintain_connection: Option<Task<Option<()>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for Room {
|
impl EventEmitter<Event> for Room {}
|
||||||
type Event = Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Room {
|
impl Room {
|
||||||
pub fn channel_id(&self) -> Option<u64> {
|
pub fn channel_id(&self) -> Option<u64> {
|
||||||
|
|
|
@ -38,9 +38,7 @@ pub enum ChannelBufferEvent {
|
||||||
ChannelChanged,
|
ChannelChanged,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for ChannelBuffer {
|
impl EventEmitter<ChannelBufferEvent> for ChannelBuffer {}
|
||||||
type Event = ChannelBufferEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ChannelBuffer {
|
impl ChannelBuffer {
|
||||||
pub(crate) async fn new(
|
pub(crate) async fn new(
|
||||||
|
|
|
@ -76,9 +76,7 @@ pub enum ChannelChatEvent {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for ChannelChat {
|
impl EventEmitter<ChannelChatEvent> for ChannelChat {}
|
||||||
type Event = ChannelChatEvent;
|
|
||||||
}
|
|
||||||
pub fn init(client: &Arc<Client>) {
|
pub fn init(client: &Arc<Client>) {
|
||||||
client.add_model_message_handler(ChannelChat::handle_message_sent);
|
client.add_model_message_handler(ChannelChat::handle_message_sent);
|
||||||
client.add_model_message_handler(ChannelChat::handle_message_removed);
|
client.add_model_message_handler(ChannelChat::handle_message_removed);
|
||||||
|
|
|
@ -114,9 +114,7 @@ pub enum ChannelEvent {
|
||||||
ChannelRenamed(ChannelId),
|
ChannelRenamed(ChannelId),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for ChannelStore {
|
impl EventEmitter<ChannelEvent> for ChannelStore {}
|
||||||
type Event = ChannelEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum OpenedModelHandle<E> {
|
enum OpenedModelHandle<E> {
|
||||||
Open(WeakModel<E>),
|
Open(WeakModel<E>),
|
||||||
|
|
|
@ -103,9 +103,7 @@ pub enum ContactEventKind {
|
||||||
Cancelled,
|
Cancelled,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for UserStore {
|
impl EventEmitter<Event> for UserStore {}
|
||||||
type Event = Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum UpdateContacts {
|
enum UpdateContacts {
|
||||||
Update(proto::UpdateContacts),
|
Update(proto::UpdateContacts),
|
||||||
|
|
|
@ -284,9 +284,7 @@ pub enum Event {
|
||||||
CopilotLanguageServerStarted,
|
CopilotLanguageServerStarted,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for Copilot {
|
impl EventEmitter<Event> for Copilot {}
|
||||||
type Event = Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Copilot {
|
impl Copilot {
|
||||||
pub fn global(cx: &AppContext) -> Option<Model<Self>> {
|
pub fn global(cx: &AppContext) -> Option<Model<Self>> {
|
||||||
|
|
|
@ -9407,9 +9407,7 @@ pub struct EditorReleased(pub WeakView<Editor>);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
impl EventEmitter for Editor {
|
impl EventEmitter<Event> for Editor {}
|
||||||
type Event = Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Render for Editor {
|
impl Render for Editor {
|
||||||
type Element = EditorElement;
|
type Element = EditorElement;
|
||||||
|
|
|
@ -201,7 +201,7 @@ pub struct AppContext {
|
||||||
pub(crate) pending_notifications: HashSet<EntityId>,
|
pub(crate) pending_notifications: HashSet<EntityId>,
|
||||||
pub(crate) pending_global_notifications: HashSet<TypeId>,
|
pub(crate) pending_global_notifications: HashSet<TypeId>,
|
||||||
pub(crate) observers: SubscriberSet<EntityId, Handler>,
|
pub(crate) observers: SubscriberSet<EntityId, Handler>,
|
||||||
// (Entity, Event Type)
|
// TypeId is the type of the event that the listener callback expects
|
||||||
pub(crate) event_listeners: SubscriberSet<EntityId, (TypeId, Listener)>,
|
pub(crate) event_listeners: SubscriberSet<EntityId, (TypeId, Listener)>,
|
||||||
pub(crate) release_listeners: SubscriberSet<EntityId, ReleaseListener>,
|
pub(crate) release_listeners: SubscriberSet<EntityId, ReleaseListener>,
|
||||||
pub(crate) global_observers: SubscriberSet<TypeId, Handler>,
|
pub(crate) global_observers: SubscriberSet<TypeId, Handler>,
|
||||||
|
|
|
@ -1813,24 +1813,6 @@ impl<'a, V: 'static> ViewContext<'a, V> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options for simplifying this new event API:
|
|
||||||
//
|
|
||||||
// - Make a new stlye of API which does partial application of the arguments to capture
|
|
||||||
// the types involved e.g.
|
|
||||||
// `cx.for_entity(handle).subscribe::<ItemEvents>(..)`
|
|
||||||
//
|
|
||||||
// - Make it so there are less types:
|
|
||||||
// - Bail on this idea all together, go back to associated types.
|
|
||||||
// causes our event enums to be a blob of anything that could happen ever, and
|
|
||||||
// makes applications have some translation boilerplate
|
|
||||||
//
|
|
||||||
// - Move some of the types into the method names,
|
|
||||||
// `cx.subscribe_model::<_, ItemEvents>(handle)`
|
|
||||||
//
|
|
||||||
// - Do something drastic like removing views and models, or removing the multiple
|
|
||||||
// kind of contexts. (Not going to happen, we already tried this before.)
|
|
||||||
//
|
|
||||||
// - Accept it, and use `cx.subscribe::<_, _, ItemEvents>(handle, ...)`
|
|
||||||
pub fn subscribe<V2, E, Evt>(
|
pub fn subscribe<V2, E, Evt>(
|
||||||
&mut self,
|
&mut self,
|
||||||
entity: &E,
|
entity: &E,
|
||||||
|
|
|
@ -1815,9 +1815,7 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for Buffer {
|
impl EventEmitter<Event> for Buffer {}
|
||||||
type Event = Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for Buffer {
|
impl Deref for Buffer {
|
||||||
type Target = TextBuffer;
|
type Target = TextBuffer;
|
||||||
|
|
|
@ -1872,9 +1872,7 @@ impl MultiBuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for MultiBuffer {
|
impl EventEmitter<Event> for MultiBuffer {}
|
||||||
type Event = Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MultiBufferSnapshot {
|
impl MultiBufferSnapshot {
|
||||||
pub fn text(&self) -> String {
|
pub fn text(&self) -> String {
|
||||||
|
|
|
@ -15,7 +15,6 @@ menu = { package = "menu2", path = "../menu2" }
|
||||||
settings = { package = "settings2", path = "../settings2" }
|
settings = { package = "settings2", path = "../settings2" }
|
||||||
util = { path = "../util" }
|
util = { path = "../util" }
|
||||||
theme = { package = "theme2", path = "../theme2" }
|
theme = { package = "theme2", path = "../theme2" }
|
||||||
workspace = { package = "workspace2", path = "../workspace2" }
|
|
||||||
|
|
||||||
parking_lot.workspace = true
|
parking_lot.workspace = true
|
||||||
|
|
||||||
|
@ -23,6 +22,5 @@ parking_lot.workspace = true
|
||||||
editor = { package = "editor2", path = "../editor2", features = ["test-support"] }
|
editor = { package = "editor2", path = "../editor2", features = ["test-support"] }
|
||||||
gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
|
gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
workspace = { package = "workspace2", path = "../workspace2", features = ["test-support"] }
|
|
||||||
ctor.workspace = true
|
ctor.workspace = true
|
||||||
env_logger.workspace = true
|
env_logger.workspace = true
|
||||||
|
|
|
@ -9062,9 +9062,7 @@ impl<'a> Iterator for PathMatchCandidateSetIter<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for Project {
|
impl EventEmitter<Event> for Project {}
|
||||||
type Event = Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P: AsRef<Path>> From<(WorktreeId, P)> for ProjectPath {
|
impl<P: AsRef<Path>> From<(WorktreeId, P)> for ProjectPath {
|
||||||
fn from((worktree_id, path): (WorktreeId, P)) -> Self {
|
fn from((worktree_id, path): (WorktreeId, P)) -> Self {
|
||||||
|
|
|
@ -281,9 +281,7 @@ pub enum Event {
|
||||||
UpdatedGitRepositories(UpdatedGitRepositoriesSet),
|
UpdatedGitRepositories(UpdatedGitRepositoriesSet),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for Worktree {
|
impl EventEmitter<Event> for Worktree {}
|
||||||
type Event = Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Worktree {
|
impl Worktree {
|
||||||
pub async fn local(
|
pub async fn local(
|
||||||
|
|
|
@ -1351,9 +1351,7 @@ impl Drop for Terminal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for Terminal {
|
impl EventEmitter<Event> for Terminal {}
|
||||||
type Event = Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Based on alacritty/src/display/hint.rs > regex_match_at
|
/// Based on alacritty/src/display/hint.rs > regex_match_at
|
||||||
/// Retrieve the match, if the specified point is inside the content matching the regex.
|
/// Retrieve the match, if the specified point is inside the content matching the regex.
|
||||||
|
|
|
@ -7,7 +7,16 @@ use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub trait Panel: Render + EventEmitter {
|
pub enum PanelEvent {
|
||||||
|
ChangePosition,
|
||||||
|
ZoomIn,
|
||||||
|
ZoomOut,
|
||||||
|
Activate,
|
||||||
|
Close,
|
||||||
|
Focus,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Panel: Render + EventEmitter<PanelEvent> {
|
||||||
fn persistent_name(&self) -> &'static str;
|
fn persistent_name(&self) -> &'static str;
|
||||||
fn position(&self, cx: &WindowContext) -> DockPosition;
|
fn position(&self, cx: &WindowContext) -> DockPosition;
|
||||||
fn position_is_valid(&self, position: DockPosition) -> bool;
|
fn position_is_valid(&self, position: DockPosition) -> bool;
|
||||||
|
@ -19,26 +28,12 @@ pub trait Panel: Render + EventEmitter {
|
||||||
fn icon_label(&self, _: &WindowContext) -> Option<String> {
|
fn icon_label(&self, _: &WindowContext) -> Option<String> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
fn should_change_position_on_event(_: &Self::Event) -> bool;
|
|
||||||
fn should_zoom_in_on_event(_: &Self::Event) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
fn should_zoom_out_on_event(_: &Self::Event) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
fn is_zoomed(&self, _cx: &WindowContext) -> bool {
|
fn is_zoomed(&self, _cx: &WindowContext) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
fn set_zoomed(&mut self, _zoomed: bool, _cx: &mut ViewContext<Self>) {}
|
fn set_zoomed(&mut self, _zoomed: bool, _cx: &mut ViewContext<Self>) {}
|
||||||
fn set_active(&mut self, _active: bool, _cx: &mut ViewContext<Self>) {}
|
fn set_active(&mut self, _active: bool, _cx: &mut ViewContext<Self>) {}
|
||||||
fn should_activate_on_event(_: &Self::Event) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
fn should_close_on_event(_: &Self::Event) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
fn has_focus(&self, cx: &WindowContext) -> bool;
|
fn has_focus(&self, cx: &WindowContext) -> bool;
|
||||||
fn is_focus_event(_: &Self::Event) -> bool;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PanelHandle: Send + Sync {
|
pub trait PanelHandle: Send + Sync {
|
||||||
|
@ -268,21 +263,37 @@ impl Dock {
|
||||||
let subscriptions = [
|
let subscriptions = [
|
||||||
cx.observe(&panel, |_, _, cx| cx.notify()),
|
cx.observe(&panel, |_, _, cx| cx.notify()),
|
||||||
cx.subscribe(&panel, |this, panel, event, cx| {
|
cx.subscribe(&panel, |this, panel, event, cx| {
|
||||||
if T::should_activate_on_event(event) {
|
match event {
|
||||||
if let Some(ix) = this
|
PanelEvent::ChangePosition => {
|
||||||
.panel_entries
|
//todo!()
|
||||||
.iter()
|
// see: Workspace::add_panel_with_extra_event_handler
|
||||||
.position(|entry| entry.panel.id() == panel.id())
|
|
||||||
{
|
|
||||||
this.set_open(true, cx);
|
|
||||||
this.activate_panel(ix, cx);
|
|
||||||
// todo!()
|
|
||||||
// cx.focus(&panel);
|
|
||||||
}
|
}
|
||||||
} else if T::should_close_on_event(event)
|
PanelEvent::ZoomIn => {
|
||||||
&& this.visible_panel().map_or(false, |p| p.id() == panel.id())
|
//todo!()
|
||||||
{
|
// see: Workspace::add_panel_with_extra_event_handler
|
||||||
this.set_open(false, cx);
|
}
|
||||||
|
PanelEvent::ZoomOut => {
|
||||||
|
// todo!()
|
||||||
|
// // see: Workspace::add_panel_with_extra_event_handler
|
||||||
|
}
|
||||||
|
PanelEvent::Activate => {
|
||||||
|
if let Some(ix) = this
|
||||||
|
.panel_entries
|
||||||
|
.iter()
|
||||||
|
.position(|entry| entry.panel.id() == panel.id())
|
||||||
|
{
|
||||||
|
this.set_open(true, cx);
|
||||||
|
this.activate_panel(ix, cx);
|
||||||
|
//` todo!()
|
||||||
|
// cx.focus(&panel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PanelEvent::Close => {
|
||||||
|
if this.visible_panel().map_or(false, |p| p.id() == panel.id()) {
|
||||||
|
this.set_open(false, cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PanelEvent::Focus => todo!(),
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
@ -452,10 +463,6 @@ impl PanelButtons {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for PanelButtons {
|
|
||||||
type Event = ();
|
|
||||||
}
|
|
||||||
|
|
||||||
// impl Render for PanelButtons {
|
// impl Render for PanelButtons {
|
||||||
// type Element = ();
|
// type Element = ();
|
||||||
|
|
||||||
|
@ -625,7 +632,7 @@ impl StatusItemView for PanelButtons {
|
||||||
_active_pane_item: Option<&dyn crate::ItemHandle>,
|
_active_pane_item: Option<&dyn crate::ItemHandle>,
|
||||||
_cx: &mut ViewContext<Self>,
|
_cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
// todo!(This is empty in the old `workspace::dock`)
|
// Nothing to do, panel buttons don't depend on the active center item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,16 +641,6 @@ pub mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use gpui::{div, Div, ViewContext, WindowContext};
|
use gpui::{div, Div, ViewContext, WindowContext};
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum TestPanelEvent {
|
|
||||||
PositionChanged,
|
|
||||||
Activated,
|
|
||||||
Closed,
|
|
||||||
ZoomIn,
|
|
||||||
ZoomOut,
|
|
||||||
Focus,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TestPanel {
|
pub struct TestPanel {
|
||||||
pub position: DockPosition,
|
pub position: DockPosition,
|
||||||
pub zoomed: bool,
|
pub zoomed: bool,
|
||||||
|
@ -652,9 +649,7 @@ pub mod test {
|
||||||
pub size: f32,
|
pub size: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for TestPanel {
|
impl EventEmitter<PanelEvent> for TestPanel {}
|
||||||
type Event = TestPanelEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TestPanel {
|
impl TestPanel {
|
||||||
pub fn new(position: DockPosition) -> Self {
|
pub fn new(position: DockPosition) -> Self {
|
||||||
|
@ -691,7 +686,7 @@ pub mod test {
|
||||||
|
|
||||||
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>) {
|
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>) {
|
||||||
self.position = position;
|
self.position = position;
|
||||||
cx.emit(TestPanelEvent::PositionChanged);
|
cx.emit(PanelEvent::ChangePosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self, _: &WindowContext) -> f32 {
|
fn size(&self, _: &WindowContext) -> f32 {
|
||||||
|
@ -710,18 +705,6 @@ pub mod test {
|
||||||
("Test Panel".into(), None)
|
("Test Panel".into(), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_change_position_on_event(event: &Self::Event) -> bool {
|
|
||||||
matches!(event, TestPanelEvent::PositionChanged)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn should_zoom_in_on_event(event: &Self::Event) -> bool {
|
|
||||||
matches!(event, TestPanelEvent::ZoomIn)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn should_zoom_out_on_event(event: &Self::Event) -> bool {
|
|
||||||
matches!(event, TestPanelEvent::ZoomOut)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_zoomed(&self, _: &WindowContext) -> bool {
|
fn is_zoomed(&self, _: &WindowContext) -> bool {
|
||||||
self.zoomed
|
self.zoomed
|
||||||
}
|
}
|
||||||
|
@ -734,20 +717,8 @@ pub mod test {
|
||||||
self.active = active;
|
self.active = active;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_activate_on_event(event: &Self::Event) -> bool {
|
|
||||||
matches!(event, TestPanelEvent::Activated)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn should_close_on_event(event: &Self::Event) -> bool {
|
|
||||||
matches!(event, TestPanelEvent::Closed)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_focus(&self, _cx: &WindowContext) -> bool {
|
fn has_focus(&self, _cx: &WindowContext) -> bool {
|
||||||
self.has_focus
|
self.has_focus
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_focus_event(event: &Self::Event) -> bool {
|
|
||||||
matches!(event, TestPanelEvent::Focus)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ pub struct BreadcrumbText {
|
||||||
pub highlights: Option<Vec<(Range<usize>, HighlightStyle)>>,
|
pub highlights: Option<Vec<(Range<usize>, HighlightStyle)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Item: Render + EventEmitter {
|
pub trait Item: Render + EventEmitter<ItemEvent> {
|
||||||
fn focus_handle(&self) -> FocusHandle;
|
fn focus_handle(&self) -> FocusHandle;
|
||||||
fn deactivated(&mut self, _: &mut ViewContext<Self>) {}
|
fn deactivated(&mut self, _: &mut ViewContext<Self>) {}
|
||||||
fn workspace_deactivated(&mut self, _: &mut ViewContext<Self>) {}
|
fn workspace_deactivated(&mut self, _: &mut ViewContext<Self>) {}
|
||||||
|
@ -106,12 +106,13 @@ pub trait Item: Render + EventEmitter {
|
||||||
}
|
}
|
||||||
fn tab_content<V: 'static>(&self, detail: Option<usize>, cx: &AppContext) -> AnyElement<V>;
|
fn tab_content<V: 'static>(&self, detail: Option<usize>, cx: &AppContext) -> AnyElement<V>;
|
||||||
|
|
||||||
|
/// (model id, Item)
|
||||||
fn for_each_project_item(
|
fn for_each_project_item(
|
||||||
&self,
|
&self,
|
||||||
_: &AppContext,
|
_: &AppContext,
|
||||||
_: &mut dyn FnMut(EntityId, &dyn project2::Item),
|
_: &mut dyn FnMut(EntityId, &dyn project2::Item),
|
||||||
) {
|
) {
|
||||||
} // (model id, Item)
|
}
|
||||||
fn is_singleton(&self, _cx: &AppContext) -> bool {
|
fn is_singleton(&self, _cx: &AppContext) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -153,15 +154,6 @@ pub trait Item: Render + EventEmitter {
|
||||||
) -> Task<Result<()>> {
|
) -> Task<Result<()>> {
|
||||||
unimplemented!("reload() must be implemented if can_save() returns true")
|
unimplemented!("reload() must be implemented if can_save() returns true")
|
||||||
}
|
}
|
||||||
fn to_item_events(_event: &Self::Event) -> SmallVec<[ItemEvent; 2]> {
|
|
||||||
SmallVec::new()
|
|
||||||
}
|
|
||||||
fn should_close_item_on_event(_: &Self::Event) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
fn should_update_tab_on_event(_: &Self::Event) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn act_as_type<'a>(
|
fn act_as_type<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
|
@ -218,7 +210,7 @@ pub trait ItemHandle: 'static + Send {
|
||||||
fn subscribe_to_item_events(
|
fn subscribe_to_item_events(
|
||||||
&self,
|
&self,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
handler: Box<dyn Fn(ItemEvent, &mut WindowContext) + Send>,
|
handler: Box<dyn Fn(&ItemEvent, &mut WindowContext) + Send>,
|
||||||
) -> gpui::Subscription;
|
) -> gpui::Subscription;
|
||||||
fn tab_tooltip_text(&self, cx: &AppContext) -> Option<SharedString>;
|
fn tab_tooltip_text(&self, cx: &AppContext) -> Option<SharedString>;
|
||||||
fn tab_description(&self, detail: usize, cx: &AppContext) -> Option<SharedString>;
|
fn tab_description(&self, detail: usize, cx: &AppContext) -> Option<SharedString>;
|
||||||
|
@ -300,12 +292,10 @@ impl<T: Item> ItemHandle for View<T> {
|
||||||
fn subscribe_to_item_events(
|
fn subscribe_to_item_events(
|
||||||
&self,
|
&self,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
handler: Box<dyn Fn(ItemEvent, &mut WindowContext) + Send>,
|
handler: Box<dyn Fn(&ItemEvent, &mut WindowContext) + Send>,
|
||||||
) -> gpui::Subscription {
|
) -> gpui::Subscription {
|
||||||
cx.subscribe(self, move |_, event, cx| {
|
cx.subscribe(self, move |_, event, cx| {
|
||||||
for item_event in T::to_item_events(event) {
|
handler(event, cx);
|
||||||
handler(item_event, cx)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,7 +423,10 @@ impl<T: Item> ItemHandle for View<T> {
|
||||||
let is_project_item = item.is_project_item(cx);
|
let is_project_item = item.is_project_item(cx);
|
||||||
let leader_id = workspace.leader_for_pane(&pane);
|
let leader_id = workspace.leader_for_pane(&pane);
|
||||||
|
|
||||||
if leader_id.is_some() && item.should_unfollow_on_event(event, cx) {
|
let follow_event = item.to_follow_event(event);
|
||||||
|
if leader_id.is_some()
|
||||||
|
&& matches!(follow_event, Some(FollowEvent::Unfollow))
|
||||||
|
{
|
||||||
workspace.unfollow(&pane, cx);
|
workspace.unfollow(&pane, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,36 +460,34 @@ impl<T: Item> ItemHandle for View<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for item_event in T::to_item_events(event).into_iter() {
|
match event {
|
||||||
match item_event {
|
ItemEvent::CloseItem => {
|
||||||
ItemEvent::CloseItem => {
|
pane.update(cx, |pane, cx| {
|
||||||
pane.update(cx, |pane, cx| {
|
pane.close_item_by_id(item.id(), crate::SaveIntent::Close, cx)
|
||||||
pane.close_item_by_id(item.id(), crate::SaveIntent::Close, cx)
|
})
|
||||||
})
|
.detach_and_log_err(cx);
|
||||||
.detach_and_log_err(cx);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ItemEvent::UpdateTab => {
|
ItemEvent::UpdateTab => {
|
||||||
pane.update(cx, |_, cx| {
|
pane.update(cx, |_, cx| {
|
||||||
cx.emit(pane::Event::ChangeItemTitle);
|
cx.emit(pane::Event::ChangeItemTitle);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemEvent::Edit => {
|
||||||
|
let autosave = WorkspaceSettings::get_global(cx).autosave;
|
||||||
|
if let AutosaveSetting::AfterDelay { milliseconds } = autosave {
|
||||||
|
let delay = Duration::from_millis(milliseconds);
|
||||||
|
let item = item.clone();
|
||||||
|
pending_autosave.fire_new(delay, cx, move |workspace, cx| {
|
||||||
|
Pane::autosave_item(&item, workspace.project().clone(), cx)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemEvent::Edit => {
|
|
||||||
let autosave = WorkspaceSettings::get_global(cx).autosave;
|
|
||||||
if let AutosaveSetting::AfterDelay { milliseconds } = autosave {
|
|
||||||
let delay = Duration::from_millis(milliseconds);
|
|
||||||
let item = item.clone();
|
|
||||||
pending_autosave.fire_new(delay, cx, move |workspace, cx| {
|
|
||||||
Pane::autosave_item(&item, workspace.project().clone(), cx)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -660,7 +651,16 @@ pub trait ProjectItem: Item {
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum FollowEvent {
|
||||||
|
Unfollow,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait FollowableEvents {
|
||||||
|
fn to_follow_event(&self) -> Option<FollowEvent>;
|
||||||
|
}
|
||||||
|
|
||||||
pub trait FollowableItem: Item {
|
pub trait FollowableItem: Item {
|
||||||
|
type FollowableEvent: FollowableEvents;
|
||||||
fn remote_id(&self) -> Option<ViewId>;
|
fn remote_id(&self) -> Option<ViewId>;
|
||||||
fn to_state_proto(&self, cx: &AppContext) -> Option<proto::view::Variant>;
|
fn to_state_proto(&self, cx: &AppContext) -> Option<proto::view::Variant>;
|
||||||
fn from_state_proto(
|
fn from_state_proto(
|
||||||
|
@ -672,7 +672,7 @@ pub trait FollowableItem: Item {
|
||||||
) -> Option<Task<Result<View<Self>>>>;
|
) -> Option<Task<Result<View<Self>>>>;
|
||||||
fn add_event_to_update_proto(
|
fn add_event_to_update_proto(
|
||||||
&self,
|
&self,
|
||||||
event: &Self::Event,
|
event: &Self::FollowableEvent,
|
||||||
update: &mut Option<proto::update_view::Variant>,
|
update: &mut Option<proto::update_view::Variant>,
|
||||||
cx: &AppContext,
|
cx: &AppContext,
|
||||||
) -> bool;
|
) -> bool;
|
||||||
|
@ -685,7 +685,6 @@ pub trait FollowableItem: Item {
|
||||||
fn is_project_item(&self, cx: &AppContext) -> bool;
|
fn is_project_item(&self, cx: &AppContext) -> bool;
|
||||||
|
|
||||||
fn set_leader_peer_id(&mut self, leader_peer_id: Option<PeerId>, cx: &mut ViewContext<Self>);
|
fn set_leader_peer_id(&mut self, leader_peer_id: Option<PeerId>, cx: &mut ViewContext<Self>);
|
||||||
fn should_unfollow_on_event(event: &Self::Event, cx: &AppContext) -> bool;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FollowableItemHandle: ItemHandle {
|
pub trait FollowableItemHandle: ItemHandle {
|
||||||
|
@ -698,13 +697,13 @@ pub trait FollowableItemHandle: ItemHandle {
|
||||||
update: &mut Option<proto::update_view::Variant>,
|
update: &mut Option<proto::update_view::Variant>,
|
||||||
cx: &AppContext,
|
cx: &AppContext,
|
||||||
) -> bool;
|
) -> bool;
|
||||||
|
fn to_follow_event(&self, event: &dyn Any) -> Option<FollowEvent>;
|
||||||
fn apply_update_proto(
|
fn apply_update_proto(
|
||||||
&self,
|
&self,
|
||||||
project: &Model<Project>,
|
project: &Model<Project>,
|
||||||
message: proto::update_view::Variant,
|
message: proto::update_view::Variant,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
) -> Task<Result<()>>;
|
) -> Task<Result<()>>;
|
||||||
fn should_unfollow_on_event(&self, event: &dyn Any, cx: &AppContext) -> bool;
|
|
||||||
fn is_project_item(&self, cx: &AppContext) -> bool;
|
fn is_project_item(&self, cx: &AppContext) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,6 +738,13 @@ impl<T: FollowableItem> FollowableItemHandle for View<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn to_follow_event(&self, event: &dyn Any) -> Option<FollowEvent> {
|
||||||
|
event
|
||||||
|
.downcast_ref()
|
||||||
|
.map(T::FollowableEvent::to_follow_event)
|
||||||
|
.flatten()
|
||||||
|
}
|
||||||
|
|
||||||
fn apply_update_proto(
|
fn apply_update_proto(
|
||||||
&self,
|
&self,
|
||||||
project: &Model<Project>,
|
project: &Model<Project>,
|
||||||
|
@ -748,14 +754,6 @@ impl<T: FollowableItem> FollowableItemHandle for View<T> {
|
||||||
self.update(cx, |this, cx| this.apply_update_proto(project, message, cx))
|
self.update(cx, |this, cx| this.apply_update_proto(project, message, cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_unfollow_on_event(&self, event: &dyn Any, cx: &AppContext) -> bool {
|
|
||||||
if let Some(event) = event.downcast_ref() {
|
|
||||||
T::should_unfollow_on_event(event, cx)
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_project_item(&self, cx: &AppContext) -> bool {
|
fn is_project_item(&self, cx: &AppContext) -> bool {
|
||||||
self.read(cx).is_project_item(cx)
|
self.read(cx).is_project_item(cx)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,12 @@ pub fn init(cx: &mut AppContext) {
|
||||||
// simple_message_notification::init(cx);
|
// simple_message_notification::init(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Notification: EventEmitter + Render {
|
pub enum NotificationEvent {
|
||||||
fn should_dismiss_notification_on_event(&self, event: &Self::Event) -> bool;
|
Dismiss,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Notification: EventEmitter<NotificationEvent> + Render {}
|
||||||
|
|
||||||
pub trait NotificationHandle: Send {
|
pub trait NotificationHandle: Send {
|
||||||
fn id(&self) -> EntityId;
|
fn id(&self) -> EntityId;
|
||||||
fn to_any(&self) -> AnyView;
|
fn to_any(&self) -> AnyView;
|
||||||
|
@ -101,11 +103,14 @@ impl Workspace {
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
let notification = build_notification(cx);
|
let notification = build_notification(cx);
|
||||||
cx.subscribe(¬ification, move |this, handle, event, cx| {
|
cx.subscribe(
|
||||||
if handle.read(cx).should_dismiss_notification_on_event(event) {
|
¬ification,
|
||||||
this.dismiss_notification_internal(type_id, id, cx);
|
move |this, handle, event: &NotificationEvent, cx| match event {
|
||||||
}
|
NotificationEvent::Dismiss => {
|
||||||
})
|
this.dismiss_notification_internal(type_id, id, cx);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
.detach();
|
.detach();
|
||||||
self.notifications
|
self.notifications
|
||||||
.push((type_id, id, Box::new(notification)));
|
.push((type_id, id, Box::new(notification)));
|
||||||
|
@ -159,7 +164,7 @@ impl Workspace {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod simple_message_notification {
|
pub mod simple_message_notification {
|
||||||
use super::Notification;
|
use super::{Notification, NotificationEvent};
|
||||||
use gpui::{AnyElement, AppContext, Div, EventEmitter, Render, TextStyle, ViewContext};
|
use gpui::{AnyElement, AppContext, Div, EventEmitter, Render, TextStyle, ViewContext};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::{borrow::Cow, sync::Arc};
|
use std::{borrow::Cow, sync::Arc};
|
||||||
|
@ -200,13 +205,7 @@ pub mod simple_message_notification {
|
||||||
click_message: Option<Cow<'static, str>>,
|
click_message: Option<Cow<'static, str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum MessageNotificationEvent {
|
impl EventEmitter<NotificationMessage> for MessageNotification {}
|
||||||
Dismiss,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EventEmitter for MessageNotification {
|
|
||||||
type Event = MessageNotificationEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MessageNotification {
|
impl MessageNotification {
|
||||||
pub fn new<S>(message: S) -> MessageNotification
|
pub fn new<S>(message: S) -> MessageNotification
|
||||||
|
@ -359,13 +358,8 @@ pub mod simple_message_notification {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
impl Notification for MessageNotification {
|
impl EventEmitter<NotificationEvent> for MessageNotification {}
|
||||||
fn should_dismiss_notification_on_event(&self, event: &Self::Event) -> bool {
|
impl Notification for MessageNotification {}
|
||||||
match event {
|
|
||||||
MessageNotificationEvent::Dismiss => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait NotifyResultExt {
|
pub trait NotifyResultExt {
|
||||||
|
|
|
@ -9,8 +9,9 @@ use crate::{
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use collections::{HashMap, HashSet, VecDeque};
|
use collections::{HashMap, HashSet, VecDeque};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
AppContext, AsyncWindowContext, Component, Div, EntityId, EventEmitter, FocusHandle, Model,
|
actions, register_action, AppContext, AsyncWindowContext, Component, Div, EntityId,
|
||||||
PromptLevel, Render, Task, View, ViewContext, VisualContext, WeakView, WindowContext,
|
EventEmitter, FocusHandle, Model, PromptLevel, Render, Task, View, ViewContext, VisualContext,
|
||||||
|
WeakView, WindowContext,
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use project2::{Project, ProjectEntryId, ProjectPath};
|
use project2::{Project, ProjectEntryId, ProjectPath};
|
||||||
|
@ -48,8 +49,10 @@ pub enum SaveIntent {
|
||||||
Skip,
|
Skip,
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[derive(Clone, Deserialize, PartialEq)]
|
//todo!("Do we need the default bound on actions? Decide soon")
|
||||||
// pub struct ActivateItem(pub usize);
|
// #[register_action]
|
||||||
|
#[derive(Clone, Deserialize, PartialEq, Debug)]
|
||||||
|
pub struct ActivateItem(pub usize);
|
||||||
|
|
||||||
// #[derive(Clone, PartialEq)]
|
// #[derive(Clone, PartialEq)]
|
||||||
// pub struct CloseItemById {
|
// pub struct CloseItemById {
|
||||||
|
@ -69,40 +72,37 @@ pub enum SaveIntent {
|
||||||
// pub pane: WeakView<Pane>,
|
// pub pane: WeakView<Pane>,
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// #[derive(Clone, PartialEq, Debug, Deserialize, Default)]
|
#[register_action]
|
||||||
// #[serde(rename_all = "camelCase")]
|
#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
|
||||||
// pub struct CloseActiveItem {
|
#[serde(rename_all = "camelCase")]
|
||||||
// pub save_intent: Option<SaveIntent>,
|
pub struct CloseActiveItem {
|
||||||
// }
|
pub save_intent: Option<SaveIntent>,
|
||||||
|
}
|
||||||
|
|
||||||
// #[derive(Clone, PartialEq, Debug, Deserialize)]
|
#[register_action]
|
||||||
// #[serde(rename_all = "camelCase")]
|
#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
|
||||||
// pub struct CloseAllItems {
|
#[serde(rename_all = "camelCase")]
|
||||||
// pub save_intent: Option<SaveIntent>,
|
pub struct CloseAllItems {
|
||||||
// }
|
pub save_intent: Option<SaveIntent>,
|
||||||
|
}
|
||||||
|
|
||||||
// todo!()
|
// todo!(These used to be under pane::{Action}. Are they now workspace::pane::{Action}?)
|
||||||
// actions!(
|
actions!(
|
||||||
// pane,
|
ActivatePrevItem,
|
||||||
// [
|
ActivateNextItem,
|
||||||
// ActivatePrevItem,
|
ActivateLastItem,
|
||||||
// ActivateNextItem,
|
CloseInactiveItems,
|
||||||
// ActivateLastItem,
|
CloseCleanItems,
|
||||||
// CloseInactiveItems,
|
CloseItemsToTheLeft,
|
||||||
// CloseCleanItems,
|
CloseItemsToTheRight,
|
||||||
// CloseItemsToTheLeft,
|
GoBack,
|
||||||
// CloseItemsToTheRight,
|
GoForward,
|
||||||
// GoBack,
|
ReopenClosedItem,
|
||||||
// GoForward,
|
SplitLeft,
|
||||||
// ReopenClosedItem,
|
SplitUp,
|
||||||
// SplitLeft,
|
SplitRight,
|
||||||
// SplitUp,
|
SplitDown,
|
||||||
// SplitRight,
|
);
|
||||||
// SplitDown,
|
|
||||||
// ]
|
|
||||||
// );
|
|
||||||
|
|
||||||
// impl_actions!(pane, [ActivateItem, CloseActiveItem, CloseAllItems]);
|
|
||||||
|
|
||||||
const MAX_NAVIGATION_HISTORY_LEN: usize = 1024;
|
const MAX_NAVIGATION_HISTORY_LEN: usize = 1024;
|
||||||
|
|
||||||
|
@ -310,9 +310,7 @@ pub struct NavigationEntry {
|
||||||
// .into_any_named("nav button")
|
// .into_any_named("nav button")
|
||||||
// }
|
// }
|
||||||
|
|
||||||
impl EventEmitter for Pane {
|
impl EventEmitter<Event> for Pane {}
|
||||||
type Event = Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Pane {
|
impl Pane {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use std::{any::Any, sync::Arc};
|
use std::{any::Any, sync::Arc};
|
||||||
|
|
||||||
use gpui::{AnyView, AppContext, Subscription, Task, View, ViewContext, WindowContext};
|
use gpui::{
|
||||||
|
AnyView, AppContext, EventEmitter, Subscription, Task, View, ViewContext, WindowContext,
|
||||||
|
};
|
||||||
use project2::search::SearchQuery;
|
use project2::search::SearchQuery;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -29,7 +31,7 @@ pub struct SearchOptions {
|
||||||
pub replacement: bool,
|
pub replacement: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SearchableItem: Item {
|
pub trait SearchableItem: Item + EventEmitter<SearchEvent> {
|
||||||
type Match: Any + Sync + Send + Clone;
|
type Match: Any + Sync + Send + Clone;
|
||||||
|
|
||||||
fn supported_options() -> SearchOptions {
|
fn supported_options() -> SearchOptions {
|
||||||
|
@ -40,11 +42,7 @@ pub trait SearchableItem: Item {
|
||||||
replacement: true,
|
replacement: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn to_search_event(
|
|
||||||
&mut self,
|
|
||||||
event: &Self::Event,
|
|
||||||
cx: &mut ViewContext<Self>,
|
|
||||||
) -> Option<SearchEvent>;
|
|
||||||
fn clear_matches(&mut self, cx: &mut ViewContext<Self>);
|
fn clear_matches(&mut self, cx: &mut ViewContext<Self>);
|
||||||
fn update_matches(&mut self, matches: Vec<Self::Match>, cx: &mut ViewContext<Self>);
|
fn update_matches(&mut self, matches: Vec<Self::Match>, cx: &mut ViewContext<Self>);
|
||||||
fn query_suggestion(&mut self, cx: &mut ViewContext<Self>) -> String;
|
fn query_suggestion(&mut self, cx: &mut ViewContext<Self>) -> String;
|
||||||
|
@ -95,7 +93,7 @@ pub trait SearchableItemHandle: ItemHandle {
|
||||||
fn subscribe_to_search_events(
|
fn subscribe_to_search_events(
|
||||||
&self,
|
&self,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
handler: Box<dyn Fn(SearchEvent, &mut WindowContext) + Send>,
|
handler: Box<dyn Fn(&SearchEvent, &mut WindowContext) + Send>,
|
||||||
) -> Subscription;
|
) -> Subscription;
|
||||||
fn clear_matches(&self, cx: &mut WindowContext);
|
fn clear_matches(&self, cx: &mut WindowContext);
|
||||||
fn update_matches(&self, matches: &Vec<Box<dyn Any + Send>>, cx: &mut WindowContext);
|
fn update_matches(&self, matches: &Vec<Box<dyn Any + Send>>, cx: &mut WindowContext);
|
||||||
|
@ -146,14 +144,9 @@ impl<T: SearchableItem> SearchableItemHandle for View<T> {
|
||||||
fn subscribe_to_search_events(
|
fn subscribe_to_search_events(
|
||||||
&self,
|
&self,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
handler: Box<dyn Fn(SearchEvent, &mut WindowContext) + Send>,
|
handler: Box<dyn Fn(&SearchEvent, &mut WindowContext) + Send>,
|
||||||
) -> Subscription {
|
) -> Subscription {
|
||||||
cx.subscribe(self, move |handle, event, cx| {
|
cx.subscribe(self, move |_, event: &SearchEvent, cx| handler(event, cx))
|
||||||
let search_event = handle.update(cx, |handle, cx| handle.to_search_event(event, cx));
|
|
||||||
if let Some(search_event) = search_event {
|
|
||||||
handler(search_event, cx)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear_matches(&self, cx: &mut WindowContext) {
|
fn clear_matches(&self, cx: &mut WindowContext) {
|
||||||
|
|
|
@ -1,24 +1,17 @@
|
||||||
use crate::ItemHandle;
|
use crate::ItemHandle;
|
||||||
use gpui::{
|
use gpui::{AnyView, Entity, EntityId, EventEmitter, Render, View, ViewContext, WindowContext};
|
||||||
AnyView, AppContext, Entity, EntityId, EventEmitter, Render, View, ViewContext, WindowContext,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub trait ToolbarItemView: Render + EventEmitter {
|
pub enum ToolbarItemEvent {
|
||||||
|
ChangeLocation(ToolbarItemLocation),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ToolbarItemView: Render + EventEmitter<ToolbarItemEvent> {
|
||||||
fn set_active_pane_item(
|
fn set_active_pane_item(
|
||||||
&mut self,
|
&mut self,
|
||||||
active_pane_item: Option<&dyn crate::ItemHandle>,
|
active_pane_item: Option<&dyn crate::ItemHandle>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> ToolbarItemLocation;
|
) -> ToolbarItemLocation;
|
||||||
|
|
||||||
fn location_for_event(
|
|
||||||
&self,
|
|
||||||
_event: &Self::Event,
|
|
||||||
current_location: ToolbarItemLocation,
|
|
||||||
_cx: &AppContext,
|
|
||||||
) -> ToolbarItemLocation {
|
|
||||||
current_location
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pane_focus_update(&mut self, _pane_focused: bool, _cx: &mut ViewContext<Self>) {}
|
fn pane_focus_update(&mut self, _pane_focused: bool, _cx: &mut ViewContext<Self>) {}
|
||||||
|
|
||||||
/// Number of times toolbar's height will be repeated to get the effective height.
|
/// Number of times toolbar's height will be repeated to get the effective height.
|
||||||
|
@ -211,12 +204,13 @@ impl Toolbar {
|
||||||
if let Some((_, current_location)) =
|
if let Some((_, current_location)) =
|
||||||
this.items.iter_mut().find(|(i, _)| i.id() == item.id())
|
this.items.iter_mut().find(|(i, _)| i.id() == item.id())
|
||||||
{
|
{
|
||||||
let new_location = item
|
match event {
|
||||||
.read(cx)
|
ToolbarItemEvent::ChangeLocation(new_location) => {
|
||||||
.location_for_event(event, *current_location, cx);
|
if new_location != current_location {
|
||||||
if new_location != *current_location {
|
*current_location = *new_location;
|
||||||
*current_location = new_location;
|
cx.notify();
|
||||||
cx.notify();
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -36,7 +36,7 @@ use futures::{
|
||||||
Future, FutureExt, StreamExt,
|
Future, FutureExt, StreamExt,
|
||||||
};
|
};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, point, rems, size, AnyModel, AnyView, AnyWeakView, AppContext, AsyncAppContext,
|
actions, div, point, rems, size, AnyModel, AnyView, AnyWeakView, AppContext, AsyncAppContext,
|
||||||
AsyncWindowContext, Bounds, Component, Div, Entity, EntityId, EventEmitter, FocusHandle,
|
AsyncWindowContext, Bounds, Component, Div, Entity, EntityId, EventEmitter, FocusHandle,
|
||||||
GlobalPixels, Model, ModelContext, ParentElement, Point, Render, Size, StatefulInteractive,
|
GlobalPixels, Model, ModelContext, ParentElement, Point, Render, Size, StatefulInteractive,
|
||||||
Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowBounds,
|
Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowBounds,
|
||||||
|
@ -88,35 +88,32 @@ lazy_static! {
|
||||||
// #[derive(Clone, PartialEq)]
|
// #[derive(Clone, PartialEq)]
|
||||||
// pub struct RemoveWorktreeFromProject(pub WorktreeId);
|
// pub struct RemoveWorktreeFromProject(pub WorktreeId);
|
||||||
|
|
||||||
// actions!(
|
actions!(
|
||||||
// workspace,
|
Open,
|
||||||
// [
|
NewFile,
|
||||||
// Open,
|
NewWindow,
|
||||||
// NewFile,
|
CloseWindow,
|
||||||
// NewWindow,
|
CloseInactiveTabsAndPanes,
|
||||||
// CloseWindow,
|
AddFolderToProject,
|
||||||
// CloseInactiveTabsAndPanes,
|
Unfollow,
|
||||||
// AddFolderToProject,
|
SaveAs,
|
||||||
// Unfollow,
|
ReloadActiveItem,
|
||||||
// SaveAs,
|
ActivatePreviousPane,
|
||||||
// ReloadActiveItem,
|
ActivateNextPane,
|
||||||
// ActivatePreviousPane,
|
FollowNextCollaborator,
|
||||||
// ActivateNextPane,
|
NewTerminal,
|
||||||
// FollowNextCollaborator,
|
NewCenterTerminal,
|
||||||
// NewTerminal,
|
ToggleTerminalFocus,
|
||||||
// NewCenterTerminal,
|
NewSearch,
|
||||||
// ToggleTerminalFocus,
|
Feedback,
|
||||||
// NewSearch,
|
Restart,
|
||||||
// Feedback,
|
Welcome,
|
||||||
// Restart,
|
ToggleZoom,
|
||||||
// Welcome,
|
ToggleLeftDock,
|
||||||
// ToggleZoom,
|
ToggleRightDock,
|
||||||
// ToggleLeftDock,
|
ToggleBottomDock,
|
||||||
// ToggleRightDock,
|
CloseAllDocks,
|
||||||
// ToggleBottomDock,
|
);
|
||||||
// CloseAllDocks,
|
|
||||||
// ]
|
|
||||||
// );
|
|
||||||
|
|
||||||
// #[derive(Clone, PartialEq)]
|
// #[derive(Clone, PartialEq)]
|
||||||
// pub struct OpenPaths {
|
// pub struct OpenPaths {
|
||||||
|
@ -964,6 +961,9 @@ impl Workspace {
|
||||||
// let mut prev_position = panel.position(cx);
|
// let mut prev_position = panel.position(cx);
|
||||||
// move |this, panel, event, cx| {
|
// move |this, panel, event, cx| {
|
||||||
// if T::should_change_position_on_event(event) {
|
// if T::should_change_position_on_event(event) {
|
||||||
|
// THIS HAS BEEN MOVED TO NORMAL EVENT EMISSION
|
||||||
|
// See: Dock::add_panel
|
||||||
|
//
|
||||||
// let new_position = panel.read(cx).position(cx);
|
// let new_position = panel.read(cx).position(cx);
|
||||||
// let mut was_visible = false;
|
// let mut was_visible = false;
|
||||||
// dock.update(cx, |dock, cx| {
|
// dock.update(cx, |dock, cx| {
|
||||||
|
@ -994,6 +994,9 @@ impl Workspace {
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
// } else if T::should_zoom_in_on_event(event) {
|
// } else if T::should_zoom_in_on_event(event) {
|
||||||
|
// THIS HAS BEEN MOVED TO NORMAL EVENT EMISSION
|
||||||
|
// See: Dock::add_panel
|
||||||
|
//
|
||||||
// dock.update(cx, |dock, cx| dock.set_panel_zoomed(&panel, true, cx));
|
// dock.update(cx, |dock, cx| dock.set_panel_zoomed(&panel, true, cx));
|
||||||
// if !panel.has_focus(cx) {
|
// if !panel.has_focus(cx) {
|
||||||
// cx.focus(&panel);
|
// cx.focus(&panel);
|
||||||
|
@ -1001,6 +1004,9 @@ impl Workspace {
|
||||||
// this.zoomed = Some(panel.downgrade().into_any());
|
// this.zoomed = Some(panel.downgrade().into_any());
|
||||||
// this.zoomed_position = Some(panel.read(cx).position(cx));
|
// this.zoomed_position = Some(panel.read(cx).position(cx));
|
||||||
// } else if T::should_zoom_out_on_event(event) {
|
// } else if T::should_zoom_out_on_event(event) {
|
||||||
|
// THIS HAS BEEN MOVED TO NORMAL EVENT EMISSION
|
||||||
|
// See: Dock::add_panel
|
||||||
|
//
|
||||||
// dock.update(cx, |dock, cx| dock.set_panel_zoomed(&panel, false, cx));
|
// dock.update(cx, |dock, cx| dock.set_panel_zoomed(&panel, false, cx));
|
||||||
// if this.zoomed_position == Some(prev_position) {
|
// if this.zoomed_position == Some(prev_position) {
|
||||||
// this.zoomed = None;
|
// this.zoomed = None;
|
||||||
|
@ -1008,6 +1014,9 @@ impl Workspace {
|
||||||
// }
|
// }
|
||||||
// cx.notify();
|
// cx.notify();
|
||||||
// } else if T::is_focus_event(event) {
|
// } else if T::is_focus_event(event) {
|
||||||
|
// THIS HAS BEEN MOVED TO NORMAL EVENT EMISSION
|
||||||
|
// See: Dock::add_panel
|
||||||
|
//
|
||||||
// let position = panel.read(cx).position(cx);
|
// let position = panel.read(cx).position(cx);
|
||||||
// this.dismiss_zoomed_items_to_reveal(Some(position), cx);
|
// this.dismiss_zoomed_items_to_reveal(Some(position), cx);
|
||||||
// if panel.is_zoomed(cx) {
|
// if panel.is_zoomed(cx) {
|
||||||
|
@ -3691,9 +3700,7 @@ fn notify_if_database_failed(workspace: WindowHandle<Workspace>, cx: &mut AsyncA
|
||||||
.log_err();
|
.log_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for Workspace {
|
impl EventEmitter<Event> for Workspace {}
|
||||||
type Event = Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Render for Workspace {
|
impl Render for Workspace {
|
||||||
type Element = Div<Self>;
|
type Element = Div<Self>;
|
||||||
|
@ -4135,10 +4142,6 @@ impl WorkspaceStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter for WorkspaceStore {
|
|
||||||
type Event = ();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ViewId {
|
impl ViewId {
|
||||||
pub(crate) fn from_proto(message: proto::ViewId) -> Result<Self> {
|
pub(crate) fn from_proto(message: proto::ViewId) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue