diff --git a/Cargo.lock b/Cargo.lock index aabfa24..a3b3c11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2106,6 +2106,7 @@ dependencies = [ "anyhow", "funnylog", "ming", + "widestring", ] [[package]] @@ -3916,6 +3917,12 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 64fea0e..058ebf6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition.workspace = true funnylog.workspace = true ming.workspace = true anyhow.workspace = true +widestring = "1.1.0" [workspace] members = [ diff --git a/crates/ming/src/shared_string.rs b/crates/ming/src/shared_string.rs index 1aa1bca..3801276 100644 --- a/crates/ming/src/shared_string.rs +++ b/crates/ming/src/shared_string.rs @@ -8,6 +8,23 @@ use util::arc_cow::ArcCow; #[derive(Deref, DerefMut, Eq, PartialEq, PartialOrd, Ord, Hash, Clone)] pub struct SharedString(ArcCow<'static, str>); +impl SharedString { + /// Create a new shared string from anything that can be turned into an [`ArcCow`], including: + /// - `&'static `[`str`] + /// - [`String`] + /// - [`Arc`]`<`[`str`]`>` + /// - a reference to any of the above + pub fn new(ac: impl Into>) -> Self { + Self(ac.into()) + } + + /// Create a new shared string from a `&'static `[`str`]. + /// This is a const method so you could store this inside a `const`. + pub const fn from_static(str: &'static str) -> Self { + Self(ArcCow::Borrowed(str)) + } +} + impl Default for SharedString { fn default() -> Self { Self(ArcCow::Owned("".into())) diff --git a/src/buffer.rs b/src/buffer.rs index 85754f4..25a4b09 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -1,10 +1,12 @@ -use std::path::PathBuf; +use std::{ops::Range, path::PathBuf}; +use widestring::Utf16String; use super::*; pub struct Buffer { - text: String, - path: Option, + pub text: Utf16String, + pub path: Option, + pub marked: Option> } impl Buffer { @@ -21,7 +23,7 @@ impl Buffer { pub fn scratch() -> Self { Self { - text: String::new(), + text: Utf16String::new(), path: None, } } diff --git a/src/editor.rs b/src/editor.rs index 8cc3271..94bc8c1 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -5,13 +5,13 @@ mod input; pub struct Editor { focus_handle: FocusHandle, - buffer: Model + buf: Model } impl Editor { pub fn make(cx: &mut ViewContext) -> View { cx.new_view(|cx| Self { - buffer: crate::buffer::Buffer::make_scratch(cx), + buf: crate::buffer::Buffer::make_scratch(cx), focus_handle: cx.focus_handle() }) } diff --git a/src/editor/element.rs b/src/editor/element.rs index 4c3f7fb..be14899 100644 --- a/src/editor/element.rs +++ b/src/editor/element.rs @@ -1,13 +1,29 @@ use super::*; +pub struct EditorStyle { + pub font_family: SharedString, + pub font_size: AbsoluteLength, +} + +impl Default for EditorStyle { + fn default() -> Self { + Self { + font_family: SharedString::from_static("Monospace"), + font_size: AbsoluteLength::Pixels(px(14)), + } + } +} + pub struct EditorElement { editor: View, + style: EditorStyle, } impl EditorElement { pub fn new(viewref: &View) -> Self { Self { editor: viewref.clone(), + style: EditorStyle::default(), } } } @@ -26,6 +42,17 @@ impl Element for EditorElement { type RequestLayoutState = (); type PrepaintState = EditorLayout; + fn id(&self) -> Option { + None + } + + fn request_layout( + &mut self, + id: Option<&GlobalElementId>, + cx: &mut WindowContext, + ) -> (LayoutId, Self::RequestLayoutState) { + } + fn prepaint( &mut self, id: Option<&GlobalElementId>, @@ -52,5 +79,16 @@ impl Element for EditorElement { &focus_handle, ElementInputHandler::new(bounds, self.editor.clone()), ); + + cx.with_text_style( + Some(TextStyleRefinement { + font_size: Some(self.style.font_size), + font_family: Some(self.style.font_family), + ..Default::default() + }), + |cx| { + todo!("draw text??") + }, + ); } } diff --git a/src/editor/input.rs b/src/editor/input.rs index 085f3c2..ff03707 100644 --- a/src/editor/input.rs +++ b/src/editor/input.rs @@ -1,3 +1,5 @@ +use widestring::Utf16Str; + use super::*; impl Editor { @@ -10,4 +12,46 @@ impl Editor { } } -impl ViewInputHandler for Editor {} +impl ViewInputHandler for Editor { + fn text_for_range( + &mut self, + range: std::ops::Range, + cx: &mut ViewContext, + ) -> Option { + self.buf + .read(cx) + .text + .get(range) + .map(|slice| slice.to_string()) + } + + fn unmark_text(&mut self, cx: &mut ViewContext) { + self.buf.update(cx, |buf, cx| { + buf.marked = None; + }) + } + + fn marked_text_range(&self, cx: &mut ViewContext) -> Option> { + self.buf.read(cx).marked.clone() + } + + fn bounds_for_range( + &mut self, + range_utf16: std::ops::Range, + element_bounds: Bounds, + cx: &mut ViewContext, + ) -> Option> { + } + + fn replace_and_mark_text_in_range( + &mut self, + range: Option>, + new_text: &str, + new_selected_range: Option>, + cx: &mut ViewContext, + ) { + self.buf.update(cx, |buf, cx| { + buf.marked = new_selected_range; + }) + } +}