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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user