Adjust the type arrangement on ManagedViews (#3354)
Made the trait into a blanket-trait impl if you have it's two constituent pieces (FocusableView and EventEmitter) to remove the duplicated method. I also changed the struct to an enum for aesthetic reasons (EventType::EventName feels self documenting to me) and added some new `cx` APIs utilizing our new powers of dismissal. Release Notes: - N/A
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
use collections::{CommandPaletteFilter, HashMap};
|
||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||
use gpui::{
|
||||
actions, div, prelude::*, Action, AppContext, Component, Dismiss, Div, FocusHandle, Keystroke,
|
||||
ManagedView, ParentComponent, Render, Styled, View, ViewContext, VisualContext, WeakView,
|
||||
actions, div, prelude::*, Action, AppContext, Component, Div, EventEmitter, FocusHandle,
|
||||
FocusableView, Keystroke, Manager, ParentComponent, Render, Styled, View, ViewContext,
|
||||
VisualContext, WeakView,
|
||||
};
|
||||
use picker::{Picker, PickerDelegate};
|
||||
use std::{
|
||||
@@ -68,7 +69,9 @@ impl CommandPalette {
|
||||
}
|
||||
}
|
||||
|
||||
impl ManagedView for CommandPalette {
|
||||
impl EventEmitter<Manager> for CommandPalette {}
|
||||
|
||||
impl FocusableView for CommandPalette {
|
||||
fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
|
||||
self.picker.focus_handle(cx)
|
||||
}
|
||||
@@ -265,7 +268,7 @@ impl PickerDelegate for CommandPaletteDelegate {
|
||||
|
||||
fn dismissed(&mut self, cx: &mut ViewContext<Picker<Self>>) {
|
||||
self.command_palette
|
||||
.update(cx, |_, cx| cx.emit(Dismiss))
|
||||
.update(cx, |_, cx| cx.emit(Manager::Dismiss))
|
||||
.log_err();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ use collections::HashMap;
|
||||
use editor::{scroll::autoscroll::Autoscroll, Bias, Editor};
|
||||
use fuzzy::{CharBag, PathMatch, PathMatchCandidate};
|
||||
use gpui::{
|
||||
actions, div, AppContext, Component, Dismiss, Div, FocusHandle, InteractiveComponent,
|
||||
ManagedView, Model, ParentComponent, Render, Styled, Task, View, ViewContext, VisualContext,
|
||||
WeakView,
|
||||
actions, div, AppContext, Component, Div, EventEmitter, FocusHandle, FocusableView,
|
||||
InteractiveComponent, Manager, Model, ParentComponent, Render, Styled, Task, View, ViewContext,
|
||||
VisualContext, WeakView,
|
||||
};
|
||||
use picker::{Picker, PickerDelegate};
|
||||
use project::{PathMatchCandidateSet, Project, ProjectPath, WorktreeId};
|
||||
@@ -111,7 +111,8 @@ impl FileFinder {
|
||||
}
|
||||
}
|
||||
|
||||
impl ManagedView for FileFinder {
|
||||
impl EventEmitter<Manager> for FileFinder {}
|
||||
impl FocusableView for FileFinder {
|
||||
fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
|
||||
self.picker.focus_handle(cx)
|
||||
}
|
||||
@@ -688,7 +689,9 @@ impl PickerDelegate for FileFinderDelegate {
|
||||
.log_err();
|
||||
}
|
||||
}
|
||||
finder.update(&mut cx, |_, cx| cx.emit(Dismiss)).ok()?;
|
||||
finder
|
||||
.update(&mut cx, |_, cx| cx.emit(Manager::Dismiss))
|
||||
.ok()?;
|
||||
|
||||
Some(())
|
||||
})
|
||||
@@ -699,7 +702,7 @@ impl PickerDelegate for FileFinderDelegate {
|
||||
|
||||
fn dismissed(&mut self, cx: &mut ViewContext<Picker<FileFinderDelegate>>) {
|
||||
self.file_finder
|
||||
.update(cx, |_, cx| cx.emit(Dismiss))
|
||||
.update(cx, |_, cx| cx.emit(Manager::Dismiss))
|
||||
.log_err();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use editor::{display_map::ToDisplayPoint, scroll::autoscroll::Autoscroll, Editor};
|
||||
use gpui::{
|
||||
actions, div, prelude::*, AppContext, Dismiss, Div, FocusHandle, ManagedView, ParentComponent,
|
||||
Render, SharedString, Styled, Subscription, View, ViewContext, VisualContext, WindowContext,
|
||||
actions, div, prelude::*, AppContext, Div, EventEmitter, FocusHandle, FocusableView, Manager,
|
||||
ParentComponent, Render, SharedString, Styled, Subscription, View, ViewContext, VisualContext,
|
||||
WindowContext,
|
||||
};
|
||||
use text::{Bias, Point};
|
||||
use theme::ActiveTheme;
|
||||
@@ -23,11 +24,12 @@ pub struct GoToLine {
|
||||
_subscriptions: Vec<Subscription>,
|
||||
}
|
||||
|
||||
impl ManagedView for GoToLine {
|
||||
impl FocusableView for GoToLine {
|
||||
fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
|
||||
self.line_editor.focus_handle(cx)
|
||||
self.active_editor.focus_handle(cx)
|
||||
}
|
||||
}
|
||||
impl EventEmitter<Manager> for GoToLine {}
|
||||
|
||||
impl GoToLine {
|
||||
fn register(workspace: &mut Workspace, _: &mut ViewContext<Workspace>) {
|
||||
@@ -87,7 +89,7 @@ impl GoToLine {
|
||||
) {
|
||||
match event {
|
||||
// todo!() this isn't working...
|
||||
editor::Event::Blurred => cx.emit(Dismiss),
|
||||
editor::Event::Blurred => cx.emit(Manager::Dismiss),
|
||||
editor::Event::BufferEdited { .. } => self.highlight_current_line(cx),
|
||||
_ => {}
|
||||
}
|
||||
@@ -122,7 +124,7 @@ impl GoToLine {
|
||||
}
|
||||
|
||||
fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) {
|
||||
cx.emit(Dismiss);
|
||||
cx.emit(Manager::Dismiss);
|
||||
}
|
||||
|
||||
fn confirm(&mut self, _: &menu::Confirm, cx: &mut ViewContext<Self>) {
|
||||
@@ -139,7 +141,7 @@ impl GoToLine {
|
||||
self.prev_scroll_position.take();
|
||||
}
|
||||
|
||||
cx.emit(Dismiss);
|
||||
cx.emit(Manager::Dismiss);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
AnyView, AnyWindowHandle, AppCell, AppContext, BackgroundExecutor, Context, FocusableView,
|
||||
ForegroundExecutor, Model, ModelContext, Render, Result, Task, View, ViewContext,
|
||||
ForegroundExecutor, Manager, Model, ModelContext, Render, Result, Task, View, ViewContext,
|
||||
VisualContext, WindowContext, WindowHandle,
|
||||
};
|
||||
use anyhow::{anyhow, Context as _};
|
||||
@@ -320,4 +320,13 @@ impl VisualContext for AsyncWindowContext {
|
||||
view.read(cx).focus_handle(cx).clone().focus(cx);
|
||||
})
|
||||
}
|
||||
|
||||
fn dismiss_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
|
||||
where
|
||||
V: crate::ManagedView,
|
||||
{
|
||||
self.window.update(self, |_, cx| {
|
||||
view.update(cx, |_, cx| cx.emit(Manager::Dismiss))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,6 +579,17 @@ impl<'a> VisualContext for VisualTestContext<'a> {
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn dismiss_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
|
||||
where
|
||||
V: crate::ManagedView,
|
||||
{
|
||||
self.window
|
||||
.update(self.cx, |_, cx| {
|
||||
view.update(cx, |_, cx| cx.emit(crate::Manager::Dismiss))
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl AnyWindowHandle {
|
||||
|
||||
@@ -141,6 +141,10 @@ pub trait VisualContext: Context {
|
||||
fn focus_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
|
||||
where
|
||||
V: FocusableView;
|
||||
|
||||
fn dismiss_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
|
||||
where
|
||||
V: ManagedView;
|
||||
}
|
||||
|
||||
pub trait Entity<T>: Sealed {
|
||||
|
||||
@@ -193,17 +193,12 @@ pub trait FocusableView: Render {
|
||||
|
||||
/// ManagedView is a view (like a Modal, Popover, Menu, etc.)
|
||||
/// where the lifecycle of the view is handled by another view.
|
||||
pub trait ManagedView: Render {
|
||||
fn focus_handle(&self, cx: &AppContext) -> FocusHandle;
|
||||
}
|
||||
pub trait ManagedView: FocusableView + EventEmitter<Manager> {}
|
||||
|
||||
pub struct Dismiss;
|
||||
impl<T: ManagedView> EventEmitter<Dismiss> for T {}
|
||||
impl<M: FocusableView + EventEmitter<Manager>> ManagedView for M {}
|
||||
|
||||
impl<T: ManagedView> FocusableView for T {
|
||||
fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
|
||||
self.focus_handle(cx)
|
||||
}
|
||||
pub enum Manager {
|
||||
Dismiss,
|
||||
}
|
||||
|
||||
// Holds the state for a specific window.
|
||||
@@ -1582,6 +1577,13 @@ impl VisualContext for WindowContext<'_> {
|
||||
view.focus_handle(cx).clone().focus(cx);
|
||||
})
|
||||
}
|
||||
|
||||
fn dismiss_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
|
||||
where
|
||||
V: ManagedView,
|
||||
{
|
||||
self.update_view(view, |_, cx| cx.emit(Manager::Dismiss))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::ops::Deref for WindowContext<'a> {
|
||||
@@ -2275,6 +2277,13 @@ impl<'a, V: 'static> ViewContext<'a, V> {
|
||||
{
|
||||
self.defer(|view, cx| view.focus_handle(cx).focus(cx))
|
||||
}
|
||||
|
||||
pub fn dismiss_self(&mut self)
|
||||
where
|
||||
V: ManagedView,
|
||||
{
|
||||
self.defer(|_, cx| cx.emit(Manager::Dismiss))
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> Context for ViewContext<'_, V> {
|
||||
@@ -2354,6 +2363,10 @@ impl<V: 'static> VisualContext for ViewContext<'_, V> {
|
||||
fn focus_view<W: FocusableView>(&mut self, view: &View<W>) -> Self::Result<()> {
|
||||
self.window_cx.focus_view(view)
|
||||
}
|
||||
|
||||
fn dismiss_view<W: ManagedView>(&mut self, view: &View<W>) -> Self::Result<()> {
|
||||
self.window_cx.dismiss_view(view)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, V> std::ops::Deref for ViewContext<'a, V> {
|
||||
|
||||
@@ -4,9 +4,9 @@ use std::rc::Rc;
|
||||
use crate::prelude::*;
|
||||
use crate::{v_stack, Label, List, ListEntry, ListItem, ListSeparator, ListSubHeader};
|
||||
use gpui::{
|
||||
overlay, px, Action, AnchorCorner, AnyElement, Bounds, Dismiss, DispatchPhase, Div,
|
||||
FocusHandle, LayoutId, ManagedView, MouseButton, MouseDownEvent, Pixels, Point, Render, View,
|
||||
VisualContext, WeakView,
|
||||
overlay, px, Action, AnchorCorner, AnyElement, AppContext, Bounds, DispatchPhase, Div,
|
||||
EventEmitter, FocusHandle, FocusableView, LayoutId, ManagedView, Manager, MouseButton,
|
||||
MouseDownEvent, Pixels, Point, Render, View, VisualContext, WeakView,
|
||||
};
|
||||
|
||||
pub enum ContextMenuItem<V> {
|
||||
@@ -24,12 +24,14 @@ pub struct ContextMenu<V> {
|
||||
handle: WeakView<V>,
|
||||
}
|
||||
|
||||
impl<V: Render> ManagedView for ContextMenu<V> {
|
||||
fn focus_handle(&self, cx: &gpui::AppContext) -> FocusHandle {
|
||||
impl<V: Render> FocusableView for ContextMenu<V> {
|
||||
fn focus_handle(&self, _cx: &AppContext) -> FocusHandle {
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Render> EventEmitter<Manager> for ContextMenu<V> {}
|
||||
|
||||
impl<V: Render> ContextMenu<V> {
|
||||
pub fn build(
|
||||
cx: &mut ViewContext<V>,
|
||||
@@ -76,11 +78,11 @@ impl<V: Render> ContextMenu<V> {
|
||||
|
||||
pub fn confirm(&mut self, _: &menu::Confirm, cx: &mut ViewContext<Self>) {
|
||||
// todo!()
|
||||
cx.emit(Dismiss);
|
||||
cx.emit(Manager::Dismiss);
|
||||
}
|
||||
|
||||
pub fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) {
|
||||
cx.emit(Dismiss);
|
||||
cx.emit(Manager::Dismiss);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +118,7 @@ impl<V: Render> Render for ContextMenu<V> {
|
||||
let handle = self.handle.clone();
|
||||
ListItem::Entry(entry.clone().on_click(move |this, cx| {
|
||||
handle.update(cx, |view, cx| callback(view, cx)).ok();
|
||||
cx.emit(Dismiss);
|
||||
cx.emit(Manager::Dismiss);
|
||||
}))
|
||||
}
|
||||
})
|
||||
@@ -276,7 +278,7 @@ impl<V: 'static, M: ManagedView> Element<V> for MenuHandle<V, M> {
|
||||
let new_menu = (builder)(view_state, cx);
|
||||
let menu2 = menu.clone();
|
||||
cx.subscribe(&new_menu, move |this, modal, e, cx| match e {
|
||||
&Dismiss => {
|
||||
&Manager::Dismiss => {
|
||||
*menu2.borrow_mut() = None;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user