Merge followup mess

This commit is contained in:
Conrad Irwin 2023-11-20 09:58:05 -07:00
parent 0798cfd58c
commit f86480ba5d
18 changed files with 90 additions and 97 deletions

View file

@ -1,4 +1,4 @@
use gpui::{div, Div, EventEmitter, ParentComponent, Render, SemanticVersion, ViewContext}; use gpui::{div, Div, EventEmitter, ParentElement, Render, SemanticVersion, ViewContext};
use menu::Cancel; use menu::Cancel;
use workspace::notifications::NotificationEvent; use workspace::notifications::NotificationEvent;
@ -8,7 +8,7 @@ pub struct UpdateNotification {
impl EventEmitter<NotificationEvent> for UpdateNotification {} impl EventEmitter<NotificationEvent> for UpdateNotification {}
impl Render for UpdateNotification { impl Render<Self> for UpdateNotification {
type Element = Div<Self>; type Element = Div<Self>;
fn render(&mut self, _cx: &mut gpui::ViewContext<Self>) -> Self::Element { fn render(&mut self, _cx: &mut gpui::ViewContext<Self>) -> Self::Element {

View file

@ -1,9 +1,8 @@
use collections::{CommandPaletteFilter, HashMap}; use collections::{CommandPaletteFilter, HashMap};
use fuzzy::{StringMatch, StringMatchCandidate}; use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{ use gpui::{
actions, actions, div, prelude::*, prelude::*, Action, AppContext, Component, Dismiss, Div, actions, div, prelude::*, Action, AppContext, Div, EventEmitter, FocusHandle, FocusableView,
EventEmitter, FocusHandle, FocusableView, Keystroke, ManagedView, Manager, ParentComponent, Keystroke, Manager, ParentElement, Render, Styled, View, ViewContext, VisualContext, WeakView,
ParentElement, Render, Render, Styled, View, ViewContext, VisualContext, WeakView,
}; };
use picker::{Picker, PickerDelegate}; use picker::{Picker, PickerDelegate};
use std::{ use std::{

View file

@ -14,8 +14,8 @@ use editor::{
use futures::future::try_join_all; use futures::future::try_join_all;
use gpui::{ use gpui::{
actions, div, AnyElement, AnyView, AppContext, Component, Context, Div, EventEmitter, actions, div, AnyElement, AnyView, AppContext, Component, Context, Div, EventEmitter,
FocusEvent, FocusHandle, Focusable, FocusableComponent, FocusableView, InteractiveComponent, FocusEvent, FocusHandle, Focusable, FocusableElement, FocusableView, InteractiveElement, Model,
Model, ParentComponent, Render, SharedString, Styled, Subscription, Task, View, ViewContext, ParentElement, Render, RenderOnce, SharedString, Styled, Subscription, Task, View, ViewContext,
VisualContext, WeakView, VisualContext, WeakView,
}; };
use language::{ use language::{
@ -90,7 +90,7 @@ struct DiagnosticGroupState {
impl EventEmitter<ItemEvent> for ProjectDiagnosticsEditor {} impl EventEmitter<ItemEvent> for ProjectDiagnosticsEditor {}
impl Render for ProjectDiagnosticsEditor { impl Render<Self> for ProjectDiagnosticsEditor {
type Element = Focusable<Self, Div<Self>>; type Element = Focusable<Self, Div<Self>>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
@ -792,13 +792,15 @@ fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock {
.when_some(diagnostic.code.as_ref(), |stack, code| { .when_some(diagnostic.code.as_ref(), |stack, code| {
stack.child(Label::new(code.clone())) stack.child(Label::new(code.clone()))
}) })
.render() .render_into_any()
}) })
} }
pub(crate) fn render_summary<T: 'static>(summary: &DiagnosticSummary) -> AnyElement<T> { pub(crate) fn render_summary<T: 'static>(summary: &DiagnosticSummary) -> AnyElement<T> {
if summary.error_count == 0 && summary.warning_count == 0 { if summary.error_count == 0 && summary.warning_count == 0 {
Label::new("No problems").render() let label = Label::new("No problems");
label.render_into_any()
//.render()
} else { } else {
h_stack() h_stack()
.bg(gpui::red()) .bg(gpui::red())
@ -806,7 +808,7 @@ pub(crate) fn render_summary<T: 'static>(summary: &DiagnosticSummary) -> AnyElem
.child(Label::new(summary.error_count.to_string())) .child(Label::new(summary.error_count.to_string()))
.child(IconElement::new(Icon::ExclamationTriangle)) .child(IconElement::new(Icon::ExclamationTriangle))
.child(Label::new(summary.warning_count.to_string())) .child(Label::new(summary.warning_count.to_string()))
.render() .render_into_any()
} }
} }

View file

@ -1,8 +1,8 @@
use collections::HashSet; use collections::HashSet;
use editor::{Editor, GoToDiagnostic}; use editor::{Editor, GoToDiagnostic};
use gpui::{ use gpui::{
rems, Div, EventEmitter, InteractiveComponent, ParentComponent, Render, Stateful, rems, Div, EventEmitter, InteractiveElement, ParentElement, Render, Stateful,
StatefulInteractiveComponent, Styled, Subscription, View, ViewContext, WeakView, StatefulInteractiveElement, Styled, Subscription, View, ViewContext, WeakView,
}; };
use language::Diagnostic; use language::Diagnostic;
use lsp::LanguageServerId; use lsp::LanguageServerId;
@ -21,7 +21,7 @@ pub struct DiagnosticIndicator {
_observe_active_editor: Option<Subscription>, _observe_active_editor: Option<Subscription>,
} }
impl Render for DiagnosticIndicator { impl Render<Self> for DiagnosticIndicator {
type Element = Stateful<Self, Div<Self>>; type Element = Stateful<Self, Div<Self>>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {

View file

@ -1,5 +1,5 @@
use crate::ProjectDiagnosticsEditor; use crate::ProjectDiagnosticsEditor;
use gpui::{div, Div, EventEmitter, ParentComponent, Render, ViewContext, WeakView}; use gpui::{div, Div, EventEmitter, ParentElement, Render, ViewContext, WeakView};
use ui::{Icon, IconButton, Tooltip}; use ui::{Icon, IconButton, Tooltip};
use workspace::{item::ItemHandle, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView}; use workspace::{item::ItemHandle, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView};
@ -7,7 +7,7 @@ pub struct ToolbarControls {
editor: Option<WeakView<ProjectDiagnosticsEditor>>, editor: Option<WeakView<ProjectDiagnosticsEditor>>,
} }
impl Render for ToolbarControls { impl Render<Self> for ToolbarControls {
type Element = Div<Self>; type Element = Div<Self>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {

View file

@ -4403,7 +4403,6 @@ impl Editor {
} }
}) })
.color(ui::TextColor::Muted) .color(ui::TextColor::Muted)
.render()
}) })
}) })
.flatten() .flatten()

View file

@ -2,10 +2,9 @@ use collections::HashMap;
use editor::{scroll::autoscroll::Autoscroll, Bias, Editor}; use editor::{scroll::autoscroll::Autoscroll, Bias, Editor};
use fuzzy::{CharBag, PathMatch, PathMatchCandidate}; use fuzzy::{CharBag, PathMatch, PathMatchCandidate};
use gpui::{ use gpui::{
actions, div, AppContext, Component, Dismiss, Div, EventEmitter, FocusHandle, FocusableView, actions, div, AppContext, Div, EventEmitter, FocusHandle, FocusableView, InteractiveElement,
InteractiveComponent, InteractiveElement, ManagedView, Manager, Model, ParentComponent, Manager, Model, ParentElement, Render, RenderOnce, Styled, Task, View, ViewContext,
ParentElement, Render, RenderOnce, Styled, Styled, Task, View, ViewContext, VisualContext, VisualContext, WeakView,
WeakView,
}; };
use picker::{Picker, PickerDelegate}; use picker::{Picker, PickerDelegate};
use project::{PathMatchCandidateSet, Project, ProjectPath, WorktreeId}; use project::{PathMatchCandidateSet, Project, ProjectPath, WorktreeId};

View file

@ -1,8 +1,7 @@
use editor::{display_map::ToDisplayPoint, scroll::autoscroll::Autoscroll, Editor}; use editor::{display_map::ToDisplayPoint, scroll::autoscroll::Autoscroll, Editor};
use gpui::{ use gpui::{
actions, div, prelude::*, AppContext, Div, EventEmitter, FocusHandle, FocusableView, Manager, actions, div, prelude::*, AppContext, Div, EventEmitter, FocusHandle, FocusableView, Manager,
ParentComponent, Render, SharedString, Styled, Subscription, View, ViewContext, VisualContext, Render, SharedString, Styled, Subscription, View, ViewContext, VisualContext, WindowContext,
WindowContext,
}; };
use text::{Bias, Point}; use text::{Bias, Point};
use theme::ActiveTheme; use theme::ActiveTheme;

View file

@ -256,19 +256,35 @@ impl TextState {
let layout_id = cx.request_measured_layout(Default::default(), rem_size, { let layout_id = cx.request_measured_layout(Default::default(), rem_size, {
let element_state = self.clone(); let element_state = self.clone();
move |known_dimensions, _| {
move |known_dimensions, available_space| {
let wrap_width = known_dimensions.width.or(match available_space.width {
crate::AvailableSpace::Definite(x) => Some(x),
_ => None,
});
if let Some(text_state) = element_state.0.lock().as_ref() {
if text_state.size.is_some()
&& (wrap_width.is_none() || wrap_width == text_state.wrap_width)
{
return text_state.size.unwrap();
}
}
let Some(lines) = text_system let Some(lines) = text_system
.shape_text( .shape_text(
&text, &text,
font_size, font_size,
&runs[..], &runs[..],
known_dimensions.width, // Wrap if we know the width. wrap_width, // Wrap if we know the width.
) )
.log_err() .log_err()
else { else {
element_state.lock().replace(TextStateInner { element_state.lock().replace(TextStateInner {
lines: Default::default(), lines: Default::default(),
line_height, line_height,
wrap_width,
size: Some(Size::default()),
}); });
return Size::default(); return Size::default();
}; };
@ -280,9 +296,12 @@ impl TextState {
size.width = size.width.max(line_size.width); size.width = size.width.max(line_size.width);
} }
element_state element_state.lock().replace(TextStateInner {
.lock() lines,
.replace(TextStateInner { lines, line_height }); line_height,
wrap_width,
size: Some(size),
});
size size
} }

View file

@ -2,14 +2,14 @@ use crate::{
key_dispatch::DispatchActionListener, px, size, Action, AnyDrag, AnyView, AppContext, key_dispatch::DispatchActionListener, px, size, Action, AnyDrag, AnyView, AppContext,
AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle, AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle,
DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId, DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId,
EventEmitter, FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla, ImageData, EventEmitter, FileDropEvent, Flatten, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla,
InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, LayoutId, Model, ModelContext, ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, LayoutId, Model,
Modifiers, MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent,
Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler,
PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams, PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams,
RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, SubscriberSet, RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size,
Subscription, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext, Style, SubscriberSet, Subscription, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View,
WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS, VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
}; };
use anyhow::{anyhow, Context as _, Result}; use anyhow::{anyhow, Context as _, Result};
use collections::HashMap; use collections::HashMap;

View file

@ -247,7 +247,6 @@ impl ProjectPanel {
let mut old_dock_position = this.position(cx); let mut old_dock_position = this.position(cx);
ProjectPanelSettings::register(cx); ProjectPanelSettings::register(cx);
cx.observe_global::<SettingsStore>(move |this, cx| { cx.observe_global::<SettingsStore>(move |this, cx| {
dbg!("OLA!");
let new_dock_position = this.position(cx); let new_dock_position = this.position(cx);
if new_dock_position != old_dock_position { if new_dock_position != old_dock_position {
old_dock_position = new_dock_position; old_dock_position = new_dock_position;

View file

@ -755,7 +755,7 @@ impl Item for TerminalView {
div() div()
.child(IconElement::new(Icon::Terminal)) .child(IconElement::new(Icon::Terminal))
.child(title) .child(Label::new(title))
.into_any() .into_any()
} }

View file

@ -1,7 +1,7 @@
use std::sync::Arc; use std::sync::Arc;
use gpui::{ use gpui::{
div, DefiniteLength, Div, Hsla, MouseButton, RenderOnce, Stateful, StatefulInteractiveElement, DefiniteLength, Div, Hsla, MouseButton, RenderOnce, Stateful, StatefulInteractiveElement,
WindowContext, WindowContext,
}; };

View file

@ -1,18 +1,12 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use crate::prelude::*; use crate::{prelude::*, v_stack, List, ListItem};
use crate::{v_stack, Label, List, ListEntry, ListItem, ListSeparator, ListSubHeader}; use crate::{ListEntry, ListSeparator, ListSubHeader};
use gpui::{ use gpui::{
<<<<<<< HEAD
overlay, px, Action, AnchorCorner, AnyElement, Bounds, Dismiss, DispatchPhase, Div,
FocusHandle, LayoutId, ManagedView, MouseButton, MouseDownEvent, Pixels, Point, Render,
RenderOnce, View,
=======
overlay, px, Action, AnchorCorner, AnyElement, AppContext, Bounds, DispatchPhase, Div, overlay, px, Action, AnchorCorner, AnyElement, AppContext, Bounds, DispatchPhase, Div,
EventEmitter, FocusHandle, FocusableView, LayoutId, ManagedView, Manager, MouseButton, EventEmitter, FocusHandle, FocusableView, LayoutId, ManagedView, Manager, MouseButton,
MouseDownEvent, Pixels, Point, Render, View, VisualContext, WeakView, MouseDownEvent, Pixels, Point, Render, RenderOnce, View, VisualContext, WeakView,
>>>>>>> main
}; };
pub enum ContextMenuItem<V> { pub enum ContextMenuItem<V> {
@ -30,15 +24,15 @@ pub struct ContextMenu<V> {
handle: WeakView<V>, handle: WeakView<V>,
} }
impl<V: Render> FocusableView for ContextMenu<V> { impl<V: 'static> FocusableView for ContextMenu<V> {
fn focus_handle(&self, _cx: &AppContext) -> FocusHandle { fn focus_handle(&self, _cx: &AppContext) -> FocusHandle {
self.focus_handle.clone() self.focus_handle.clone()
} }
} }
impl<V: Render> EventEmitter<Manager> for ContextMenu<V> {} impl<V: 'static> EventEmitter<Manager> for ContextMenu<V> {}
impl<V: Render> ContextMenu<V> { impl<V: 'static> ContextMenu<V> {
pub fn build( pub fn build(
cx: &mut ViewContext<V>, cx: &mut ViewContext<V>,
f: impl FnOnce(Self, &mut ViewContext<Self>) -> Self, f: impl FnOnce(Self, &mut ViewContext<Self>) -> Self,
@ -92,11 +86,7 @@ impl<V: Render> ContextMenu<V> {
} }
} }
<<<<<<< HEAD impl<V: 'static> Render<Self> for ContextMenu<V> {
impl Render<Self> for ContextMenu {
=======
impl<V: Render> Render for ContextMenu<V> {
>>>>>>> main
type Element = Div<Self>; type Element = Div<Self>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
@ -324,7 +314,7 @@ mod stories {
actions!(PrintCurrentDate, PrintBestFood); actions!(PrintCurrentDate, PrintBestFood);
fn build_menu<V: Render>( fn build_menu<V: Render<V>>(
cx: &mut ViewContext<V>, cx: &mut ViewContext<V>,
header: impl Into<SharedString>, header: impl Into<SharedString>,
) -> View<ContextMenu<V>> { ) -> View<ContextMenu<V>> {

View file

@ -58,7 +58,10 @@ impl<V: 'static> Component<V> for IconButton<V> {
.p_1() .p_1()
.bg(bg_color) .bg(bg_color)
.cursor_pointer() .cursor_pointer()
.hover(|style| style.bg(bg_hover_color)) // Nate: Trying to figure out the right places we want to show a
// hover state here. I think it is a bit heavy to have it on every
// place we use an icon button.
// .hover(|style| style.bg(bg_hover_color))
.active(|style| style.bg(bg_active_color)) .active(|style| style.bg(bg_active_color))
.child(IconElement::new(self.icon).color(icon_color)); .child(IconElement::new(self.icon).color(icon_color));

View file

@ -1,6 +1,5 @@
use crate::prelude::*; use crate::prelude::*;
use gpui::{Action, Div, RenderOnce}; use gpui::{Action, Div, RenderOnce};
use strum::EnumIter;
#[derive(RenderOnce, Clone)] #[derive(RenderOnce, Clone)]
pub struct KeyBinding { pub struct KeyBinding {
@ -72,22 +71,6 @@ impl Key {
} }
} }
// NOTE: The order the modifier keys appear in this enum impacts the order in
// which they are rendered in the UI.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]
pub enum ModifierKey {
Control,
Alt,
Command,
Shift,
}
actions!(NoAction);
pub fn binding(key: &str) -> gpui::KeyBinding {
gpui::KeyBinding::new(key, NoAction {}, None)
}
#[cfg(feature = "stories")] #[cfg(feature = "stories")]
pub use stories::*; pub use stories::*;
@ -95,7 +78,7 @@ pub use stories::*;
mod stories { mod stories {
use super::*; use super::*;
pub use crate::KeyBinding; pub use crate::KeyBinding;
use crate::{binding, Story}; use crate::Story;
use gpui::{actions, Div, Render}; use gpui::{actions, Div, Render};
use itertools::Itertools; use itertools::Itertools;
pub struct KeybindingStory; pub struct KeybindingStory;
@ -106,7 +89,7 @@ mod stories {
gpui::KeyBinding::new(key, NoAction {}, None) gpui::KeyBinding::new(key, NoAction {}, None)
} }
impl Render for KeybindingStory { impl Render<Self> for KeybindingStory {
type Element = Div<Self>; type Element = Div<Self>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {

View file

@ -1,4 +1,4 @@
use gpui::{div, Action, Div, RenderOnce}; use gpui::{div, Div, RenderOnce, Stateful, StatefulInteractiveElement};
use std::rc::Rc; use std::rc::Rc;
use crate::settings::user_settings; use crate::settings::user_settings;
@ -232,7 +232,7 @@ pub enum ListEntrySize {
Medium, Medium,
} }
#[derive(RenderOnce, Clone)] #[derive(Clone)]
pub enum ListItem<V: 'static> { pub enum ListItem<V: 'static> {
Entry(ListEntry<V>), Entry(ListEntry<V>),
Separator(ListSeparator), Separator(ListSeparator),
@ -257,19 +257,7 @@ impl<V: 'static> From<ListSubHeader> for ListItem<V> {
} }
} }
impl<V: 'static> Component<V> for ListItem<V> { impl<V: 'static> ListItem<V> {
type Rendered = Div<V>;
fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered {
match self {
ListItem::Entry(entry) => div().child(entry.render(ix, cx)),
ListItem::Separator(separator) => div().child(separator.render(view, cx)),
ListItem::Header(header) => div().child(header.render(view, cx)),
}
}
}
impl ListItem {
pub fn new(label: Label) -> Self { pub fn new(label: Label) -> Self {
Self::Entry(ListEntry::new(label)) Self::Entry(ListEntry::new(label))
} }
@ -281,6 +269,14 @@ impl ListItem {
None None
} }
} }
fn render(self, view: &mut V, ix: usize, cx: &mut ViewContext<V>) -> Div<V> {
match self {
ListItem::Entry(entry) => div().child(entry.render(ix, cx)),
ListItem::Separator(separator) => div().child(separator.render(view, cx)),
ListItem::Header(header) => div().child(header.render(view, cx)),
}
}
} }
// #[derive(RenderOnce)] // #[derive(RenderOnce)]
@ -458,7 +454,7 @@ impl<V: 'static> Component<V> for ListSeparator {
#[derive(RenderOnce)] #[derive(RenderOnce)]
pub struct List<V: 'static> { pub struct List<V: 'static> {
items: Vec<ListItem>, items: Vec<ListItem<V>>,
/// Message to display when the list is empty /// Message to display when the list is empty
/// Defaults to "No items" /// Defaults to "No items"
empty_message: SharedString, empty_message: SharedString,
@ -471,7 +467,12 @@ impl<V: 'static> Component<V> for List<V> {
fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered { fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered {
let list_content = match (self.items.is_empty(), self.toggle) { let list_content = match (self.items.is_empty(), self.toggle) {
(false, _) => div().children(self.items), (false, _) => div().children(
self.items
.into_iter()
.enumerate()
.map(|(ix, item)| item.render(view, ix, cx)),
),
(true, Toggle::Toggled(false)) => div(), (true, Toggle::Toggled(false)) => div(),
(true, _) => { (true, _) => {
div().child(Label::new(self.empty_message.clone()).color(TextColor::Muted)) div().child(Label::new(self.empty_message.clone()).color(TextColor::Muted))
@ -487,7 +488,7 @@ impl<V: 'static> Component<V> for List<V> {
} }
impl<V: 'static> List<V> { impl<V: 'static> List<V> {
pub fn new(items: Vec<ListItem>) -> Self { pub fn new(items: Vec<ListItem<V>>) -> Self {
Self { Self {
items, items,
empty_message: "No items".into(), empty_message: "No items".into(),
@ -511,7 +512,7 @@ impl<V: 'static> List<V> {
self self
} }
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> { fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
let list_content = match (self.items.is_empty(), self.toggle) { let list_content = match (self.items.is_empty(), self.toggle) {
(false, _) => div().children( (false, _) => div().children(
self.items self.items

View file

@ -15,7 +15,7 @@ pub enum NotificationEvent {
pub trait Notification: EventEmitter<NotificationEvent> + Render<Self> {} pub trait Notification: EventEmitter<NotificationEvent> + Render<Self> {}
impl<V: EventEmitter<NotificationEvent> + Render> Notification for V {} impl<V: EventEmitter<NotificationEvent> + Render<Self>> Notification for V {}
pub trait NotificationHandle: Send { pub trait NotificationHandle: Send {
fn id(&self) -> EntityId; fn id(&self) -> EntityId;