repl: Fix image scaling (#48435)
Continues #47114 Release Notes: - Fixed REPL output width clamping to apply to the content area so images don’t get clipped by controls --------- Co-authored-by: MrSubidubi <finn@zed.dev>
This commit is contained in:
1 parent
e51cd4931c
commit
c0fa025bc9
6 files changed
+55
-98
No files matched your search
@@ -1,13 +1,11 @@
|
||||
#![allow(unused, dead_code)]
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use editor::{Editor, EditorMode, MultiBuffer, SizingBehavior};
|
||||
use futures::future::Shared;
|
||||
use gpui::{
|
||||
App, Entity, EventEmitter, Focusable, Hsla, InteractiveElement, KeyContext,
|
||||
RetainAllImageCache, StatefulInteractiveElement, Task, TextStyleRefinement, image_cache,
|
||||
prelude::*,
|
||||
App, Entity, EventEmitter, Focusable, Hsla, InteractiveElement, RetainAllImageCache,
|
||||
StatefulInteractiveElement, Task, TextStyleRefinement, prelude::*,
|
||||
};
|
||||
use language::{Buffer, Language, LanguageRegistry};
|
||||
use markdown::{Markdown, MarkdownElement, MarkdownStyle};
|
||||
@@ -236,7 +234,7 @@ pub trait RenderableCell: Render {
|
||||
fn source(&self) -> &String;
|
||||
fn selected(&self) -> bool;
|
||||
fn set_selected(&mut self, selected: bool) -> &mut Self;
|
||||
fn selected_bg_color(&self, window: &mut Window, cx: &mut Context<Self>) -> Hsla {
|
||||
fn selected_bg_color(&self, _window: &mut Window, cx: &mut Context<Self>) -> Hsla {
|
||||
if self.selected() {
|
||||
let mut color = cx.theme().colors().element_hover;
|
||||
color.fade_out(0.5);
|
||||
@@ -253,7 +251,7 @@ pub trait RenderableCell: Render {
|
||||
fn cell_position_spacer(
|
||||
&self,
|
||||
is_first: bool,
|
||||
window: &mut Window,
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<impl IntoElement> {
|
||||
let cell_position = self.cell_position();
|
||||
@@ -328,7 +326,6 @@ pub struct MarkdownCell {
|
||||
editing: bool,
|
||||
selected: bool,
|
||||
cell_position: Option<CellPosition>,
|
||||
languages: Arc<LanguageRegistry>,
|
||||
_editor_subscription: gpui::Subscription,
|
||||
}
|
||||
|
||||
@@ -386,7 +383,6 @@ impl MarkdownCell {
|
||||
|
||||
let markdown = cx.new(|cx| Markdown::new(source.clone().into(), None, None, cx));
|
||||
|
||||
let cell_id = id.clone();
|
||||
let editor_subscription =
|
||||
cx.subscribe(&editor, move |this, _editor, event, cx| match event {
|
||||
editor::EditorEvent::Blurred => {
|
||||
@@ -410,7 +406,6 @@ impl MarkdownCell {
|
||||
editing: start_editing,
|
||||
selected: false,
|
||||
cell_position: None,
|
||||
languages,
|
||||
_editor_subscription: editor_subscription,
|
||||
}
|
||||
}
|
||||
@@ -461,8 +456,6 @@ impl MarkdownCell {
|
||||
.unwrap_or_default();
|
||||
|
||||
self.source = source.clone();
|
||||
let languages = self.languages.clone();
|
||||
|
||||
self.markdown.update(cx, |markdown, cx| {
|
||||
markdown.reset(source.into(), cx);
|
||||
});
|
||||
@@ -606,7 +599,7 @@ pub struct CodeCell {
|
||||
outputs: Vec<Output>,
|
||||
selected: bool,
|
||||
cell_position: Option<CellPosition>,
|
||||
language_task: Task<()>,
|
||||
_language_task: Task<()>,
|
||||
execution_start_time: Option<Instant>,
|
||||
execution_duration: Option<Duration>,
|
||||
is_executing: bool,
|
||||
@@ -670,10 +663,10 @@ impl CodeCell {
|
||||
outputs: Vec::new(),
|
||||
selected: false,
|
||||
cell_position: None,
|
||||
language_task,
|
||||
execution_start_time: None,
|
||||
execution_duration: None,
|
||||
is_executing: false,
|
||||
_language_task: language_task,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,10 +741,10 @@ impl CodeCell {
|
||||
outputs,
|
||||
selected: false,
|
||||
cell_position: None,
|
||||
language_task,
|
||||
execution_start_time: None,
|
||||
execution_duration: None,
|
||||
is_executing: false,
|
||||
_language_task: language_task,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -879,15 +872,7 @@ impl CodeCell {
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn output_control(&self) -> Option<CellControlType> {
|
||||
if self.has_outputs() {
|
||||
Some(CellControlType::ClearCell)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gutter_output(&self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
pub fn gutter_output(&self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let is_selected = self.selected();
|
||||
|
||||
div()
|
||||
@@ -948,7 +933,7 @@ impl RenderableCell for CodeCell {
|
||||
&self.source
|
||||
}
|
||||
|
||||
fn control(&self, window: &mut Window, cx: &mut Context<Self>) -> Option<CellControl> {
|
||||
fn control(&self, _window: &mut Window, cx: &mut Context<Self>) -> Option<CellControl> {
|
||||
let control_type = if self.has_outputs() {
|
||||
CellControlType::RerunCell
|
||||
} else {
|
||||
@@ -1038,8 +1023,7 @@ impl RenderableCell for CodeCell {
|
||||
}
|
||||
|
||||
impl RunnableCell for CodeCell {
|
||||
fn run(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
println!("Running code cell: {}", self.id);
|
||||
fn run(&mut self, _window: &mut Window, cx: &mut Context<Self>) {
|
||||
cx.emit(CellEvent::Run(self.id.clone()));
|
||||
}
|
||||
|
||||
@@ -1062,11 +1046,8 @@ impl Render for CodeCell {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let output_max_width = plain::max_width_for_columns(
|
||||
ReplSettings::get_global(cx).output_max_width_columns,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
let output_max_width =
|
||||
plain::max_width_for_columns(ReplSettings::get_global(cx).max_columns, window, cx);
|
||||
// get the language from the editor's buffer
|
||||
let language_name = self
|
||||
.editor
|
||||
@@ -1198,41 +1179,23 @@ impl Render for CodeCell {
|
||||
},
|
||||
)
|
||||
// output at bottom
|
||||
.child(div().w_full().children(self.outputs.iter().map(
|
||||
|output| {
|
||||
let content = match output {
|
||||
Output::Plain { content, .. } => {
|
||||
Some(content.clone().into_any_element())
|
||||
}
|
||||
Output::Markdown { content, .. } => {
|
||||
Some(content.clone().into_any_element())
|
||||
}
|
||||
Output::Stream { content, .. } => {
|
||||
Some(content.clone().into_any_element())
|
||||
}
|
||||
Output::Image { content, .. } => {
|
||||
Some(content.clone().into_any_element())
|
||||
}
|
||||
Output::Message(message) => Some(
|
||||
div()
|
||||
.child(message.clone())
|
||||
.into_any_element(),
|
||||
),
|
||||
Output::Table { content, .. } => {
|
||||
Some(content.clone().into_any_element())
|
||||
}
|
||||
Output::Json { content, .. } => {
|
||||
Some(content.clone().into_any_element())
|
||||
}
|
||||
Output::ErrorOutput(error_view) => {
|
||||
error_view.render(window, cx)
|
||||
}
|
||||
Output::ClearOutputWaitMarker => None,
|
||||
};
|
||||
|
||||
div().children(content)
|
||||
},
|
||||
))),
|
||||
.child(
|
||||
div()
|
||||
.id((
|
||||
ElementId::from(self.id.to_string()),
|
||||
"output-scroll",
|
||||
))
|
||||
.w_full()
|
||||
.when_some(output_max_width, |div, max_width| {
|
||||
div.max_w(max_width).overflow_x_scroll()
|
||||
})
|
||||
.when_some(output_max_height, |div, max_height| {
|
||||
div.max_h(max_height).overflow_y_scroll()
|
||||
})
|
||||
.children(self.outputs.iter().map(|output| {
|
||||
div().children(output.content(window, cx))
|
||||
})),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
+21
-16
@@ -253,18 +253,8 @@ impl Output {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn render(
|
||||
&self,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<ExecutionView>,
|
||||
) -> impl IntoElement + use<> {
|
||||
let max_width = plain::max_width_for_columns(
|
||||
ReplSettings::get_global(cx).output_max_width_columns,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
let content = match self {
|
||||
pub fn content(&self, window: &mut Window, cx: &mut App) -> Option<AnyElement> {
|
||||
match self {
|
||||
Self::Plain { content, .. } => Some(content.clone().into_any_element()),
|
||||
Self::Markdown { content, .. } => Some(content.clone().into_any_element()),
|
||||
Self::Stream { content, .. } => Some(content.clone().into_any_element()),
|
||||
@@ -274,21 +264,36 @@ impl Output {
|
||||
Self::Json { content, .. } => Some(content.clone().into_any_element()),
|
||||
Self::ErrorOutput(error_view) => error_view.render(window, cx),
|
||||
Self::ClearOutputWaitMarker => None,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let needs_horizontal_scroll = matches!(self, Self::Table { .. } | Self::Image { .. });
|
||||
pub fn render(
|
||||
&self,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<ExecutionView>,
|
||||
) -> impl IntoElement + use<> {
|
||||
let max_width =
|
||||
plain::max_width_for_columns(ReplSettings::get_global(cx).max_columns, window, cx);
|
||||
let content = self.content(window, cx);
|
||||
|
||||
let needs_horizontal_scroll = matches!(self, Self::Table { .. });
|
||||
|
||||
h_flex()
|
||||
.id("output-content")
|
||||
.w_full()
|
||||
.when_some(max_width, |this, max_w| this.max_w(max_w))
|
||||
.overflow_x_scroll()
|
||||
.when_else(
|
||||
needs_horizontal_scroll,
|
||||
|this| this.overflow_x_scroll(),
|
||||
|this| this.overflow_x_hidden(),
|
||||
)
|
||||
.items_start()
|
||||
.child(
|
||||
div()
|
||||
.when(!needs_horizontal_scroll, |el| {
|
||||
el.flex_1().w_full().overflow_x_hidden()
|
||||
})
|
||||
.when_some(max_width, |el, max_width| el.max_w(max_width))
|
||||
.children(content),
|
||||
)
|
||||
.children(match self {
|
||||
|
||||
@@ -3,10 +3,10 @@ use base64::{
|
||||
Engine as _, alphabet,
|
||||
engine::{DecodePaddingMode, GeneralPurpose, GeneralPurposeConfig},
|
||||
};
|
||||
use gpui::{App, ClipboardItem, Image, ImageFormat, RenderImage, Window, img};
|
||||
use gpui::{App, ClipboardItem, Image, ImageFormat, Pixels, RenderImage, Window, img};
|
||||
use settings::Settings as _;
|
||||
use std::sync::Arc;
|
||||
use ui::{IntoElement, Styled, div, prelude::*};
|
||||
use ui::{IntoElement, Styled, prelude::*};
|
||||
|
||||
use crate::outputs::{OutputContent, plain};
|
||||
use crate::repl_settings::ReplSettings;
|
||||
@@ -113,7 +113,7 @@ impl Render for ImageView {
|
||||
let settings = ReplSettings::get_global(cx);
|
||||
let line_height = window.line_height();
|
||||
|
||||
let max_width = plain::max_width_for_columns(settings.output_max_width_columns, window, cx);
|
||||
let max_width = plain::max_width_for_columns(settings.max_columns, window, cx);
|
||||
|
||||
let max_height = if settings.output_max_height_lines > 0 {
|
||||
Some(line_height * settings.output_max_height_lines as f32)
|
||||
@@ -125,7 +125,7 @@ impl Render for ImageView {
|
||||
|
||||
let image = self.image.clone();
|
||||
|
||||
div().h(height).w(width).child(img(image))
|
||||
img(image).w(width).h(height)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ use alacritty_terminal::{
|
||||
term::Config,
|
||||
vte::ansi::Processor,
|
||||
};
|
||||
use gpui::{Bounds, ClipboardItem, Entity, FontStyle, TextStyle, WhiteSpace, canvas, size};
|
||||
use gpui::{Bounds, ClipboardItem, Entity, FontStyle, Pixels, TextStyle, WhiteSpace, canvas, size};
|
||||
use language::Buffer;
|
||||
use settings::Settings as _;
|
||||
use terminal::terminal_settings::TerminalSettings;
|
||||
|
||||
@@ -27,11 +27,6 @@ pub struct ReplSettings {
|
||||
///
|
||||
/// Default: 0
|
||||
pub output_max_height_lines: usize,
|
||||
/// Maximum number of columns of output to display before scaling images.
|
||||
/// Set to 0 to disable output width limits.
|
||||
///
|
||||
/// Default: 0
|
||||
pub output_max_width_columns: usize,
|
||||
}
|
||||
|
||||
impl Settings for ReplSettings {
|
||||
@@ -44,7 +39,6 @@ impl Settings for ReplSettings {
|
||||
inline_output: repl.inline_output.unwrap_or(true),
|
||||
inline_output_max_length: repl.inline_output_max_length.unwrap_or(50),
|
||||
output_max_height_lines: repl.output_max_height_lines.unwrap_or(0),
|
||||
output_max_width_columns: repl.output_max_width_columns.unwrap_or(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1148,11 +1148,6 @@ pub struct ReplSettingsContent {
|
||||
///
|
||||
/// Default: 0
|
||||
pub output_max_height_lines: Option<usize>,
|
||||
/// Maximum number of columns of output to display before scaling images.
|
||||
/// Set to 0 to disable output width limits.
|
||||
///
|
||||
/// Default: 0
|
||||
pub output_max_width_columns: Option<usize>,
|
||||
}
|
||||
|
||||
/// Settings for configuring the which-key popup behaviour.
|
||||
|
||||
Reference in new issue
Block a user