mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-28 19:25:33 +03:00
Pass a &mut BlockContext
when rendering blocks
This wraps and derefs to `RenderContext<Editor>`, so that we can easily use `MouseEventHandler`s in blocks.
This commit is contained in:
parent
9fa03b2f28
commit
aefdde66a6
@ -702,7 +702,7 @@ mod tests {
|
||||
use super::*;
|
||||
use editor::{
|
||||
display_map::{BlockContext, TransformBlock},
|
||||
DisplayPoint, EditorSnapshot,
|
||||
DisplayPoint,
|
||||
};
|
||||
use gpui::TestAppContext;
|
||||
use language::{Diagnostic, DiagnosticEntry, DiagnosticSeverity, PointUtf16};
|
||||
@ -835,10 +835,8 @@ mod tests {
|
||||
|
||||
view.next_notification(&cx).await;
|
||||
view.update(cx, |view, cx| {
|
||||
let editor = view.editor.update(cx, |editor, cx| editor.snapshot(cx));
|
||||
|
||||
assert_eq!(
|
||||
editor_blocks(&editor, cx),
|
||||
editor_blocks(&view.editor, cx),
|
||||
[
|
||||
(0, "path header block".into()),
|
||||
(2, "diagnostic header".into()),
|
||||
@ -848,7 +846,7 @@ mod tests {
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
editor.text(),
|
||||
view.editor.update(cx, |editor, cx| editor.display_text(cx)),
|
||||
concat!(
|
||||
//
|
||||
// main.rs
|
||||
@ -923,10 +921,8 @@ mod tests {
|
||||
|
||||
view.next_notification(&cx).await;
|
||||
view.update(cx, |view, cx| {
|
||||
let editor = view.editor.update(cx, |editor, cx| editor.snapshot(cx));
|
||||
|
||||
assert_eq!(
|
||||
editor_blocks(&editor, cx),
|
||||
editor_blocks(&view.editor, cx),
|
||||
[
|
||||
(0, "path header block".into()),
|
||||
(2, "diagnostic header".into()),
|
||||
@ -938,7 +934,7 @@ mod tests {
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
editor.text(),
|
||||
view.editor.update(cx, |editor, cx| editor.display_text(cx)),
|
||||
concat!(
|
||||
//
|
||||
// consts.rs
|
||||
@ -1038,10 +1034,8 @@ mod tests {
|
||||
|
||||
view.next_notification(&cx).await;
|
||||
view.update(cx, |view, cx| {
|
||||
let editor = view.editor.update(cx, |editor, cx| editor.snapshot(cx));
|
||||
|
||||
assert_eq!(
|
||||
editor_blocks(&editor, cx),
|
||||
editor_blocks(&view.editor, cx),
|
||||
[
|
||||
(0, "path header block".into()),
|
||||
(2, "diagnostic header".into()),
|
||||
@ -1055,7 +1049,7 @@ mod tests {
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
editor.text(),
|
||||
view.editor.update(cx, |editor, cx| editor.display_text(cx)),
|
||||
concat!(
|
||||
//
|
||||
// consts.rs
|
||||
@ -1115,36 +1109,44 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
fn editor_blocks(editor: &EditorSnapshot, cx: &AppContext) -> Vec<(u32, String)> {
|
||||
editor
|
||||
.blocks_in_range(0..editor.max_point().row())
|
||||
.filter_map(|(row, block)| {
|
||||
let name = match block {
|
||||
TransformBlock::Custom(block) => block
|
||||
.render(&BlockContext {
|
||||
cx,
|
||||
anchor_x: 0.,
|
||||
scroll_x: 0.,
|
||||
gutter_padding: 0.,
|
||||
gutter_width: 0.,
|
||||
line_height: 0.,
|
||||
em_width: 0.,
|
||||
})
|
||||
.name()?
|
||||
.to_string(),
|
||||
TransformBlock::ExcerptHeader {
|
||||
starts_new_buffer, ..
|
||||
} => {
|
||||
if *starts_new_buffer {
|
||||
"path header block".to_string()
|
||||
} else {
|
||||
"collapsed context".to_string()
|
||||
fn editor_blocks(
|
||||
editor: &ViewHandle<Editor>,
|
||||
cx: &mut MutableAppContext,
|
||||
) -> Vec<(u32, String)> {
|
||||
let mut presenter = cx.build_presenter(editor.id(), 0.);
|
||||
let mut cx = presenter.build_layout_context(Default::default(), false, cx);
|
||||
cx.render(editor, |editor, cx| {
|
||||
let snapshot = editor.snapshot(cx);
|
||||
snapshot
|
||||
.blocks_in_range(0..snapshot.max_point().row())
|
||||
.filter_map(|(row, block)| {
|
||||
let name = match block {
|
||||
TransformBlock::Custom(block) => block
|
||||
.render(&mut BlockContext {
|
||||
cx,
|
||||
anchor_x: 0.,
|
||||
scroll_x: 0.,
|
||||
gutter_padding: 0.,
|
||||
gutter_width: 0.,
|
||||
line_height: 0.,
|
||||
em_width: 0.,
|
||||
})
|
||||
.name()?
|
||||
.to_string(),
|
||||
TransformBlock::ExcerptHeader {
|
||||
starts_new_buffer, ..
|
||||
} => {
|
||||
if *starts_new_buffer {
|
||||
"path header block".to_string()
|
||||
} else {
|
||||
"collapsed context".to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Some((row, name))
|
||||
})
|
||||
.collect()
|
||||
Some((row, name))
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -4,14 +4,14 @@ use super::{
|
||||
};
|
||||
use crate::{Anchor, ToPoint as _};
|
||||
use collections::{Bound, HashMap, HashSet};
|
||||
use gpui::{AppContext, ElementBox};
|
||||
use gpui::{ElementBox, RenderContext};
|
||||
use language::{BufferSnapshot, Chunk, Patch};
|
||||
use parking_lot::Mutex;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
cmp::{self, Ordering},
|
||||
fmt::Debug,
|
||||
ops::{Deref, Range},
|
||||
ops::{Deref, DerefMut, Range},
|
||||
sync::{
|
||||
atomic::{AtomicUsize, Ordering::SeqCst},
|
||||
Arc,
|
||||
@ -50,7 +50,7 @@ struct BlockRow(u32);
|
||||
#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
|
||||
struct WrapRow(u32);
|
||||
|
||||
pub type RenderBlock = Arc<dyn Fn(&BlockContext) -> ElementBox>;
|
||||
pub type RenderBlock = Arc<dyn Fn(&mut BlockContext) -> ElementBox>;
|
||||
|
||||
pub struct Block {
|
||||
id: BlockId,
|
||||
@ -67,12 +67,12 @@ where
|
||||
{
|
||||
pub position: P,
|
||||
pub height: u8,
|
||||
pub render: Arc<dyn Fn(&BlockContext) -> ElementBox>,
|
||||
pub render: Arc<dyn Fn(&mut BlockContext) -> ElementBox>,
|
||||
pub disposition: BlockDisposition,
|
||||
}
|
||||
|
||||
pub struct BlockContext<'a> {
|
||||
pub cx: &'a AppContext,
|
||||
pub struct BlockContext<'a, 'b> {
|
||||
pub cx: &'b mut RenderContext<'a, crate::Editor>,
|
||||
pub anchor_x: f32,
|
||||
pub scroll_x: f32,
|
||||
pub gutter_width: f32,
|
||||
@ -916,16 +916,22 @@ impl BlockDisposition {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Deref for BlockContext<'a> {
|
||||
type Target = AppContext;
|
||||
impl<'a, 'b> Deref for BlockContext<'a, 'b> {
|
||||
type Target = RenderContext<'a, crate::Editor>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.cx
|
||||
self.cx
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> DerefMut for BlockContext<'a, 'b> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.cx
|
||||
}
|
||||
}
|
||||
|
||||
impl Block {
|
||||
pub fn render(&self, cx: &BlockContext) -> ElementBox {
|
||||
pub fn render(&self, cx: &mut BlockContext) -> ElementBox {
|
||||
self.render.lock()(cx)
|
||||
}
|
||||
|
||||
@ -1008,7 +1014,7 @@ mod tests {
|
||||
let mut block_map = BlockMap::new(wraps_snapshot.clone(), 1, 1);
|
||||
|
||||
let mut writer = block_map.write(wraps_snapshot.clone(), Default::default());
|
||||
writer.insert(vec![
|
||||
let block_ids = writer.insert(vec![
|
||||
BlockProperties {
|
||||
position: buffer_snapshot.anchor_after(Point::new(1, 0)),
|
||||
height: 1,
|
||||
@ -1036,22 +1042,7 @@ mod tests {
|
||||
.blocks_in_range(0..8)
|
||||
.map(|(start_row, block)| {
|
||||
let block = block.as_custom().unwrap();
|
||||
(
|
||||
start_row..start_row + block.height as u32,
|
||||
block
|
||||
.render(&BlockContext {
|
||||
cx,
|
||||
anchor_x: 0.,
|
||||
gutter_padding: 0.,
|
||||
scroll_x: 0.,
|
||||
gutter_width: 0.,
|
||||
line_height: 0.,
|
||||
em_width: 0.,
|
||||
})
|
||||
.name()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
)
|
||||
(start_row..start_row + block.height as u32, block.id)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@ -1059,9 +1050,9 @@ mod tests {
|
||||
assert_eq!(
|
||||
blocks,
|
||||
&[
|
||||
(1..2, "block 1".to_string()),
|
||||
(2..4, "block 2".to_string()),
|
||||
(7..10, "block 3".to_string()),
|
||||
(1..2, block_ids[0]),
|
||||
(2..4, block_ids[1]),
|
||||
(7..10, block_ids[2]),
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -4745,7 +4745,7 @@ impl Editor {
|
||||
height: 1,
|
||||
render: Arc::new({
|
||||
let editor = rename_editor.clone();
|
||||
move |cx: &BlockContext| {
|
||||
move |cx: &mut BlockContext| {
|
||||
ChildView::new(editor.clone())
|
||||
.contained()
|
||||
.with_padding_left(cx.anchor_x)
|
||||
@ -5866,7 +5866,7 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> Rend
|
||||
highlighted_lines.push(highlight_diagnostic_message(line));
|
||||
}
|
||||
|
||||
Arc::new(move |cx: &BlockContext| {
|
||||
Arc::new(move |cx: &mut BlockContext| {
|
||||
let settings = cx.global::<Settings>();
|
||||
let theme = &settings.theme.editor;
|
||||
let style = diagnostic_style(diagnostic.severity, is_valid, theme);
|
||||
|
@ -755,6 +755,12 @@ impl EditorElement {
|
||||
line_layouts: &[text_layout::Line],
|
||||
cx: &mut LayoutContext,
|
||||
) -> Vec<(u32, ElementBox)> {
|
||||
let editor = if let Some(editor) = self.view.upgrade(cx) {
|
||||
editor
|
||||
} else {
|
||||
return Default::default();
|
||||
};
|
||||
|
||||
let scroll_x = snapshot.scroll_position.x();
|
||||
snapshot
|
||||
.blocks_in_range(rows.clone())
|
||||
@ -774,14 +780,16 @@ impl EditorElement {
|
||||
.x_for_index(align_to.column() as usize)
|
||||
};
|
||||
|
||||
block.render(&BlockContext {
|
||||
cx,
|
||||
anchor_x,
|
||||
gutter_padding,
|
||||
line_height,
|
||||
scroll_x,
|
||||
gutter_width,
|
||||
em_width,
|
||||
cx.render(&editor, |_, cx| {
|
||||
block.render(&mut BlockContext {
|
||||
cx,
|
||||
anchor_x,
|
||||
gutter_padding,
|
||||
line_height,
|
||||
scroll_x,
|
||||
gutter_width,
|
||||
em_width,
|
||||
})
|
||||
})
|
||||
}
|
||||
TransformBlock::ExcerptHeader {
|
||||
|
Loading…
Reference in New Issue
Block a user