Merge branch 'gpui2-ui' into gpui2

Marshall Bowers created

Change summary

crates/ui2/src/components/buffer_search.rs | 49 ++++++++++++++++++-----
crates/ui2/src/components/editor_pane.rs   |  7 ++
crates/ui2/src/elements/button.rs          |  2 
crates/ui2/src/elements/icon.rs            |  4 +
crates/ui2/src/static_data.rs              | 20 ++++++--
5 files changed, 62 insertions(+), 20 deletions(-)

Detailed changes

crates/ui2/src/components/buffer_search.rs 🔗

@@ -1,20 +1,47 @@
+use gpui3::{view, Context, View};
+
 use crate::prelude::*;
-use crate::EditorPane;
+use crate::{h_stack, Icon, IconButton, IconColor, Input};
 
-#[derive(Element)]
-#[element(view_state = "EditorPane")]
-pub struct BufferSearch {}
+pub struct BufferSearch {
+    is_replace_open: bool,
+}
 
 impl BufferSearch {
     pub fn new() -> Self {
-        Self {}
+        Self {
+            is_replace_open: false,
+        }
+    }
+
+    fn toggle_replace(&mut self, cx: &mut ViewContext<Self>) {
+        self.is_replace_open = !self.is_replace_open;
+
+        cx.notify();
     }
 
-    fn render(
-        &mut self,
-        _view: &mut EditorPane,
-        cx: &mut ViewContext<EditorPane>,
-    ) -> impl Element<ViewState = EditorPane> {
-        div().child("This is where Buffer Search goes.")
+    pub fn view(cx: &mut WindowContext) -> View<Self> {
+        let theme = theme(cx);
+
+        view(cx.entity(|cx| Self::new()), Self::render)
+    }
+
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element<ViewState = Self> {
+        let theme = theme(cx);
+
+        h_stack()
+            .fill(theme.highest.base.default.background)
+            .p_2()
+            .child(
+                h_stack()
+                    .child(Input::new("Search (↑/↓ for previous/next query)"))
+                    .child(
+                        IconButton::<Self>::new(Icon::Replace)
+                            .when(self.is_replace_open, |this| this.color(IconColor::Accent))
+                            .on_click(|buffer_search, cx| {
+                                buffer_search.toggle_replace(cx);
+                            }),
+                    ),
+            )
     }
 }

crates/ui2/src/components/editor_pane.rs 🔗

@@ -14,11 +14,13 @@ pub struct EditorPane {
     path: PathBuf,
     symbols: Vec<Symbol>,
     buffer: Buffer<Self>,
+    buffer_search: View<BufferSearch>,
     is_buffer_search_open: bool,
 }
 
 impl EditorPane {
     pub fn new(
+        cx: &mut WindowContext,
         tabs: Vec<Tab<Self>>,
         path: PathBuf,
         symbols: Vec<Symbol>,
@@ -29,6 +31,7 @@ impl EditorPane {
             path,
             symbols,
             buffer,
+            buffer_search: BufferSearch::view(cx),
             is_buffer_search_open: false,
         }
     }
@@ -43,7 +46,7 @@ impl EditorPane {
         let theme = theme(cx);
 
         view(
-            cx.entity(|cx| hello_world_rust_editor_with_status_example(&theme)),
+            cx.entity(|cx| hello_world_rust_editor_with_status_example(cx)),
             Self::render,
         )
     }
@@ -69,7 +72,7 @@ impl EditorPane {
                         IconButton::new(Icon::MagicWand),
                     ]),
             )
-            .children(Some(BufferSearch::new()).filter(|_| self.is_buffer_search_open))
+            .children(Some(self.buffer_search.clone()).filter(|_| self.is_buffer_search_open))
             .child(self.buffer.clone())
     }
 }

crates/ui2/src/elements/button.rs 🔗

@@ -4,7 +4,7 @@ use std::sync::Arc;
 use gpui3::{DefiniteLength, Hsla, Interactive, MouseButton, WindowContext};
 
 use crate::prelude::*;
-use crate::{h_stack, theme, Icon, IconColor, IconElement, Label, LabelColor, LabelSize};
+use crate::{h_stack, Icon, IconColor, IconElement, Label, LabelColor, LabelSize};
 
 #[derive(Default, PartialEq, Clone, Copy)]
 pub enum IconPosition {

crates/ui2/src/elements/icon.rs 🔗

@@ -82,6 +82,8 @@ pub enum Icon {
     MicMute,
     Plus,
     Quote,
+    Replace,
+    ReplaceAll,
     Screen,
     SelectAll,
     Split,
@@ -130,6 +132,8 @@ impl Icon {
             Icon::MicMute => "icons/mic-mute.svg",
             Icon::Plus => "icons/plus.svg",
             Icon::Quote => "icons/quote.svg",
+            Icon::Replace => "icons/replace.svg",
+            Icon::ReplaceAll => "icons/replace_all.svg",
             Icon::Screen => "icons/desktop.svg",
             Icon::SelectAll => "icons/select-all.svg",
             Icon::Split => "icons/split.svg",

crates/ui2/src/static_data.rs 🔗

@@ -1,10 +1,11 @@
 use std::path::PathBuf;
 use std::str::FromStr;
 
+use gpui3::WindowContext;
 use rand::Rng;
 
 use crate::{
-    Buffer, BufferRow, BufferRows, EditorPane, FileSystemStatus, GitStatus, HighlightColor,
+    theme, Buffer, BufferRow, BufferRows, EditorPane, FileSystemStatus, GitStatus, HighlightColor,
     HighlightedLine, HighlightedText, Icon, Keybinding, Label, LabelColor, ListEntry,
     ListEntrySize, ListItem, Livestream, MicStatus, ModifierKeys, PaletteItem, Player,
     PlayerCallStatus, PlayerWithCallStatus, ScreenShareStatus, Symbol, Tab, Theme, ToggleState,
@@ -597,8 +598,9 @@ pub fn example_editor_actions<S: 'static + Send + Sync + Clone>() -> Vec<Palette
     ]
 }
 
-pub fn empty_editor_example() -> EditorPane {
+pub fn empty_editor_example(cx: &mut WindowContext) -> EditorPane {
     EditorPane::new(
+        cx,
         static_tabs_example(),
         PathBuf::from_str("crates/ui/src/static_data.rs").unwrap(),
         vec![],
@@ -610,8 +612,11 @@ pub fn empty_buffer_example<S: 'static + Send + Sync + Clone>() -> Buffer<S> {
     Buffer::new().set_rows(Some(BufferRows::default()))
 }
 
-pub fn hello_world_rust_editor_example(theme: &Theme) -> EditorPane {
+pub fn hello_world_rust_editor_example(cx: &mut WindowContext) -> EditorPane {
+    let theme = theme(cx);
+
     EditorPane::new(
+        cx,
         static_tabs_example(),
         PathBuf::from_str("crates/ui/src/static_data.rs").unwrap(),
         vec![Symbol(vec![
@@ -624,7 +629,7 @@ pub fn hello_world_rust_editor_example(theme: &Theme) -> EditorPane {
                 color: HighlightColor::Function.hsla(&theme),
             },
         ])],
-        hello_world_rust_buffer_example(theme),
+        hello_world_rust_buffer_example(&theme),
     )
 }
 
@@ -748,8 +753,11 @@ pub fn hello_world_rust_buffer_rows(theme: &Theme) -> Vec<BufferRow> {
     ]
 }
 
-pub fn hello_world_rust_editor_with_status_example(theme: &Theme) -> EditorPane {
+pub fn hello_world_rust_editor_with_status_example(cx: &mut WindowContext) -> EditorPane {
+    let theme = theme(cx);
+
     EditorPane::new(
+        cx,
         static_tabs_example(),
         PathBuf::from_str("crates/ui/src/static_data.rs").unwrap(),
         vec![Symbol(vec![
@@ -762,7 +770,7 @@ pub fn hello_world_rust_editor_with_status_example(theme: &Theme) -> EditorPane
                 color: HighlightColor::Function.hsla(&theme),
             },
         ])],
-        hello_world_rust_buffer_with_status_example(theme),
+        hello_world_rust_buffer_with_status_example(&theme),
     )
 }