Detailed changes
@@ -37,8 +37,8 @@ use futures::FutureExt;
use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{
div, px, AnyElement, AppContext, BackgroundExecutor, Context, Div, Element, EventEmitter,
- FocusHandle, Hsla, Model, Pixels, Render, Styled, Subscription, Task, TextStyle, View,
- ViewContext, VisualContext, WeakView, WindowContext,
+ FocusHandle, FontStyle, FontWeight, Hsla, Model, Pixels, Render, Styled, Subscription, Task,
+ TextStyle, View, ViewContext, VisualContext, WeakView, WindowContext,
};
use highlight_matching_bracket::refresh_matching_bracket_highlights;
use hover_popover::{hide_hover, HoverState};
@@ -81,7 +81,7 @@ use std::{
pub use sum_tree::Bias;
use sum_tree::TreeMap;
use text::Rope;
-use theme::{ActiveTheme, PlayerColor, ThemeColors, ThemeVariant};
+use theme::{ActiveTheme, PlayerColor, ThemeColors, ThemeSettings, ThemeVariant};
use util::{post_inc, RangeExt, ResultExt, TryFutureExt};
use workspace::{ItemNavHistory, SplitDirection, ViewId, Workspace};
@@ -1882,7 +1882,7 @@ impl Editor {
) -> Self {
// let editor_view_id = cx.view_id();
let style = cx.text_style();
- let font_size = style.font_size * cx.rem_size();
+ let font_size = style.font_size.to_pixels(cx.rem_size());
let display_map = cx.build_model(|cx| {
// todo!()
// let settings = settings::get::<ThemeSettings>(cx);
@@ -9325,11 +9325,22 @@ impl Render for Editor {
type Element = EditorElement;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+ let settings = ThemeSettings::get_global(cx);
+ let text_style = TextStyle {
+ color: cx.theme().colors().text,
+ font_family: settings.buffer_font.family.clone(),
+ font_features: settings.buffer_font.features,
+ font_size: settings.buffer_font_size.into(),
+ font_weight: FontWeight::NORMAL,
+ font_style: FontStyle::Normal,
+ line_height: Default::default(),
+ underline: None,
+ };
EditorElement::new(EditorStyle {
background: cx.theme().colors().editor,
local_player: cx.theme().players().local(),
- text: cx.text_style(),
- line_height_scalar: 1.,
+ text: text_style,
+ line_height_scalar: settings.buffer_line_height.value(),
scrollbar_width: px(12.),
})
}
@@ -612,7 +612,7 @@ impl EditorElement {
fn paint_gutter(
&mut self,
bounds: Bounds<Pixels>,
- layout: &mut LayoutState,
+ layout: &LayoutState,
editor: &mut Editor,
cx: &mut ViewContext<Editor>,
) {
@@ -672,7 +672,7 @@ impl EditorElement {
fn paint_diff_hunks(
bounds: Bounds<Pixels>,
- layout: &mut LayoutState,
+ layout: &LayoutState,
cx: &mut ViewContext<Editor>,
) {
// todo!()
@@ -761,11 +761,10 @@ impl EditorElement {
fn paint_text(
&mut self,
bounds: Bounds<Pixels>,
- layout: &mut LayoutState,
+ layout: &LayoutState,
editor: &mut Editor,
cx: &mut ViewContext<Editor>,
) {
- let style = &self.style;
let scroll_position = layout.position_map.snapshot.scroll_position();
let start_row = layout.visible_display_row_range.start;
let scroll_top = scroll_position.y * layout.position_map.line_height;
@@ -896,33 +895,21 @@ impl EditorElement {
.chars_at(cursor_position)
.next()
.and_then(|(character, _)| {
- let font_id =
- cursor_row_layout.font_for_index(cursor_column)?;
let text = character.to_string();
-
- cx.text_system().layout_text(
- &text,
- cursor_row_layout.font_size,
- &[TextRun {
- len: text.len(),
- font: todo!(),
- color: todo!(),
- underline: todo!(),
- }],
- None,
- );
- Some(cx.text_layout_cache().layout_str(
- &text,
- cursor_row_layout.font_size,
- &[(
- text.chars().count(),
- RunStyle {
- font_id,
- color: style.background,
- underline: Default::default(),
- },
- )],
- ))
+ cx.text_system()
+ .layout_text(
+ &text,
+ cursor_row_layout.font_size,
+ &[TextRun {
+ len: text.len(),
+ font: self.style.text.font(),
+ color: self.style.background,
+ underline: None,
+ }],
+ None,
+ )
+ .unwrap()
+ .pop()
})
} else {
None
@@ -958,125 +945,123 @@ impl EditorElement {
scroll_top,
content_origin,
scroll_left,
- visible_text_bounds,
whitespace_setting,
&invisible_display_ranges,
- visible_bounds,
cx,
)
}
- cx.scene().push_layer(Some(bounds));
+ // cx.scene().push_layer(Some(bounds));
for cursor in cursors {
cursor.paint(content_origin, cx);
}
- cx.scene().pop_layer();
-
- if let Some((position, context_menu)) = layout.context_menu.as_mut() {
- cx.scene().push_stacking_context(None, None);
- let cursor_row_layout =
- &layout.position_map.line_layouts[(position.row() - start_row) as usize].line;
- let x = cursor_row_layout.x_for_index(position.column() as usize) - scroll_left;
- let y = (position.row() + 1) as f32 * layout.position_map.line_height - scroll_top;
- let mut list_origin = content_origin + point(x, y);
- let list_width = context_menu.size().x;
- let list_height = context_menu.size().y;
-
- // Snap the right edge of the list to the right edge of the window if
- // its horizontal bounds overflow.
- if list_origin.x + list_width > cx.window_size().x {
- list_origin.set_x((cx.window_size().x - list_width).max(0.));
- }
-
- if list_origin.y + list_height > bounds.max_y {
- list_origin
- .set_y(list_origin.y - layout.position_map.line_height - list_height);
- }
-
- context_menu.paint(
- list_origin,
- Bounds::<Pixels>::from_points(
- gpui::Point::<Pixels>::zero(),
- point(f32::MAX, f32::MAX),
- ), // Let content bleed outside of editor
- editor,
- cx,
- );
+ // cx.scene().pop_layer();
+
+ // if let Some((position, context_menu)) = layout.context_menu.as_mut() {
+ // cx.scene().push_stacking_context(None, None);
+ // let cursor_row_layout =
+ // &layout.position_map.line_layouts[(position.row() - start_row) as usize].line;
+ // let x = cursor_row_layout.x_for_index(position.column() as usize) - scroll_left;
+ // let y = (position.row() + 1) as f32 * layout.position_map.line_height - scroll_top;
+ // let mut list_origin = content_origin + point(x, y);
+ // let list_width = context_menu.size().x;
+ // let list_height = context_menu.size().y;
+
+ // // Snap the right edge of the list to the right edge of the window if
+ // // its horizontal bounds overflow.
+ // if list_origin.x + list_width > cx.window_size().x {
+ // list_origin.set_x((cx.window_size().x - list_width).max(0.));
+ // }
- cx.scene().pop_stacking_context();
- }
+ // if list_origin.y + list_height > bounds.max_y {
+ // list_origin
+ // .set_y(list_origin.y - layout.position_map.line_height - list_height);
+ // }
- if let Some((position, hover_popovers)) = layout.hover_popovers.as_mut() {
- cx.scene().push_stacking_context(None, None);
-
- // This is safe because we check on layout whether the required row is available
- let hovered_row_layout =
- &layout.position_map.line_layouts[(position.row() - start_row) as usize].line;
-
- // Minimum required size: Take the first popover, and add 1.5 times the minimum popover
- // height. This is the size we will use to decide whether to render popovers above or below
- // the hovered line.
- let first_size = hover_popovers[0].size();
- let height_to_reserve = first_size.y
- + 1.5 * MIN_POPOVER_LINE_HEIGHT as f32 * layout.position_map.line_height;
-
- // Compute Hovered Point
- let x = hovered_row_layout.x_for_index(position.column() as usize) - scroll_left;
- let y = position.row() as f32 * layout.position_map.line_height - scroll_top;
- let hovered_point = content_origin + point(x, y);
-
- if hovered_point.y - height_to_reserve > 0.0 {
- // There is enough space above. Render popovers above the hovered point
- let mut current_y = hovered_point.y;
- for hover_popover in hover_popovers {
- let size = hover_popover.size();
- let mut popover_origin = point(hovered_point.x, current_y - size.y);
-
- let x_out_of_bounds = bounds.max_x - (popover_origin.x + size.x);
- if x_out_of_bounds < 0.0 {
- popover_origin.set_x(popover_origin.x + x_out_of_bounds);
- }
+ // context_menu.paint(
+ // list_origin,
+ // Bounds::<Pixels>::from_points(
+ // gpui::Point::<Pixels>::zero(),
+ // point(f32::MAX, f32::MAX),
+ // ), // Let content bleed outside of editor
+ // editor,
+ // cx,
+ // );
- hover_popover.paint(
- popover_origin,
- Bounds::<Pixels>::from_points(
- gpui::Point::<Pixels>::zero(),
- point(f32::MAX, f32::MAX),
- ), // Let content bleed outside of editor
- editor,
- cx,
- );
-
- current_y = popover_origin.y - HOVER_POPOVER_GAP;
- }
- } else {
- // There is not enough space above. Render popovers below the hovered point
- let mut current_y = hovered_point.y + layout.position_map.line_height;
- for hover_popover in hover_popovers {
- let size = hover_popover.size();
- let mut popover_origin = point(hovered_point.x, current_y);
-
- let x_out_of_bounds = bounds.max_x - (popover_origin.x + size.x);
- if x_out_of_bounds < 0.0 {
- popover_origin.set_x(popover_origin.x + x_out_of_bounds);
- }
+ // cx.scene().pop_stacking_context();
+ // }
- hover_popover.paint(
- popover_origin,
- Bounds::<Pixels>::from_points(
- gpui::Point::<Pixels>::zero(),
- point(f32::MAX, f32::MAX),
- ), // Let content bleed outside of editor
- editor,
- cx,
- );
-
- current_y = popover_origin.y + size.y + HOVER_POPOVER_GAP;
- }
- }
+ // if let Some((position, hover_popovers)) = layout.hover_popovers.as_mut() {
+ // cx.scene().push_stacking_context(None, None);
+
+ // // This is safe because we check on layout whether the required row is available
+ // let hovered_row_layout =
+ // &layout.position_map.line_layouts[(position.row() - start_row) as usize].line;
+
+ // // Minimum required size: Take the first popover, and add 1.5 times the minimum popover
+ // // height. This is the size we will use to decide whether to render popovers above or below
+ // // the hovered line.
+ // let first_size = hover_popovers[0].size();
+ // let height_to_reserve = first_size.y
+ // + 1.5 * MIN_POPOVER_LINE_HEIGHT as f32 * layout.position_map.line_height;
+
+ // // Compute Hovered Point
+ // let x = hovered_row_layout.x_for_index(position.column() as usize) - scroll_left;
+ // let y = position.row() as f32 * layout.position_map.line_height - scroll_top;
+ // let hovered_point = content_origin + point(x, y);
+
+ // if hovered_point.y - height_to_reserve > 0.0 {
+ // // There is enough space above. Render popovers above the hovered point
+ // let mut current_y = hovered_point.y;
+ // for hover_popover in hover_popovers {
+ // let size = hover_popover.size();
+ // let mut popover_origin = point(hovered_point.x, current_y - size.y);
+
+ // let x_out_of_bounds = bounds.max_x - (popover_origin.x + size.x);
+ // if x_out_of_bounds < 0.0 {
+ // popover_origin.set_x(popover_origin.x + x_out_of_bounds);
+ // }
+
+ // hover_popover.paint(
+ // popover_origin,
+ // Bounds::<Pixels>::from_points(
+ // gpui::Point::<Pixels>::zero(),
+ // point(f32::MAX, f32::MAX),
+ // ), // Let content bleed outside of editor
+ // editor,
+ // cx,
+ // );
+
+ // current_y = popover_origin.y - HOVER_POPOVER_GAP;
+ // }
+ // } else {
+ // // There is not enough space above. Render popovers below the hovered point
+ // let mut current_y = hovered_point.y + layout.position_map.line_height;
+ // for hover_popover in hover_popovers {
+ // let size = hover_popover.size();
+ // let mut popover_origin = point(hovered_point.x, current_y);
+
+ // let x_out_of_bounds = bounds.max_x - (popover_origin.x + size.x);
+ // if x_out_of_bounds < 0.0 {
+ // popover_origin.set_x(popover_origin.x + x_out_of_bounds);
+ // }
+
+ // hover_popover.paint(
+ // popover_origin,
+ // Bounds::<Pixels>::from_points(
+ // gpui::Point::<Pixels>::zero(),
+ // point(f32::MAX, f32::MAX),
+ // ), // Let content bleed outside of editor
+ // editor,
+ // cx,
+ // );
+
+ // current_y = popover_origin.y + size.y + HOVER_POPOVER_GAP;
+ // }
+ // }
- cx.scene().pop_stacking_context();
- }
+ // cx.scene().pop_stacking_context();
+ // }
})
}
@@ -1369,7 +1354,7 @@ impl EditorElement {
fn column_pixels(&self, column: usize, cx: &ViewContext<Editor>) -> Pixels {
let style = &self.style;
- let font_size = style.text.font_size * cx.rem_size();
+ let font_size = style.text.font_size.to_pixels(cx.rem_size());
let layout = cx
.text_system()
.layout_text(
@@ -1478,7 +1463,7 @@ impl EditorElement {
Vec<Option<gpui::Line>>,
Vec<Option<(FoldStatus, BufferRow, bool)>>,
) {
- let font_size = self.style.text.font_size * cx.rem_size();
+ let font_size = self.style.text.font_size.to_pixels(cx.rem_size());
let include_line_numbers = snapshot.mode == EditorMode::Full;
let mut line_number_layouts = Vec::with_capacity(rows.len());
let mut fold_statuses = Vec::with_capacity(rows.len());
@@ -1555,8 +1540,8 @@ impl EditorElement {
}
// When the editor is empty and unfocused, then show the placeholder.
- if snapshot.is_empty {
- let font_size = self.style.text.font_size * cx.rem_size();
+ if snapshot.is_empty() {
+ let font_size = self.style.text.font_size.to_pixels(cx.rem_size());
let placeholder_color = cx.theme().styles.colors.text_placeholder;
let placeholder_text = snapshot.placeholder_text();
let placeholder_lines = placeholder_text
@@ -1615,7 +1600,7 @@ impl EditorElement {
let snapshot = editor.snapshot(cx);
let style = self.style.clone();
let font_id = cx.text_system().font_id(&style.text.font()).unwrap();
- let font_size = style.text.font_size * cx.rem_size();
+ let font_size = style.text.font_size.to_pixels(cx.rem_size());
let line_height = (font_size * style.line_height_scalar).round();
let em_width = cx
.text_system()
@@ -1716,7 +1701,7 @@ impl EditorElement {
.anchor_before(DisplayPoint::new(start_row, 0).to_offset(&snapshot, Bias::Left))
};
let end_anchor = if end_row > max_row {
- Anchor::max
+ Anchor::max()
} else {
snapshot
.buffer_snapshot
@@ -1847,7 +1832,7 @@ impl EditorElement {
(is_singleton && scrollbar_settings.git_diff && snapshot.buffer_snapshot.has_git_diffs())
||
// Selections
- (is_singleton && scrollbar_settings.selections && !highlighted_ranges.is_empty)
+ (is_singleton && scrollbar_settings.selections && !highlighted_ranges.is_empty())
// Scrollmanager
|| editor.scroll_manager.scrollbars_visible()
}
@@ -1902,14 +1887,14 @@ impl EditorElement {
let line_layouts =
self.layout_lines(start_row..end_row, &line_number_layouts, &snapshot, cx);
for line_with_invisibles in &line_layouts {
- if line_with_invisibles.line.width() > max_visible_line_width {
- max_visible_line_width = line_with_invisibles.line.width();
+ if line_with_invisibles.line.width > max_visible_line_width {
+ max_visible_line_width = line_with_invisibles.line.width;
}
}
let longest_line_width = layout_line(snapshot.longest_row(), &snapshot, &style, cx)
.unwrap()
- .width();
+ .width;
let scroll_width = longest_line_width.max(max_visible_line_width) + overscroll.width;
// todo!("blocks")
// let (scroll_width, blocks) = self.layout_blocks(
@@ -2373,7 +2358,7 @@ impl LineWithInvisibles {
let mut non_whitespace_added = false;
let mut row = 0;
let mut line_exceeded_max_len = false;
- let font_size = text_style.font_size * cx.rem_size();
+ let font_size = text_style.font_size.to_pixels(cx.rem_size());
for highlighted_chunk in chunks.chain([HighlightedChunk {
chunk: "\n",
@@ -2400,7 +2385,7 @@ impl LineWithInvisibles {
}
}
- if !line_chunk.is_empty && !line_exceeded_max_len {
+ if !line_chunk.is_empty() && !line_exceeded_max_len {
let text_style = if let Some(style) = highlighted_chunk.style {
text_style
.clone()
@@ -2473,7 +2458,6 @@ impl LineWithInvisibles {
scroll_top: Pixels,
content_origin: gpui::Point<Pixels>,
scroll_left: Pixels,
- visible_text_bounds: Bounds<Pixels>,
whitespace_setting: ShowWhitespaceSetting,
selection_ranges: &[Range<DisplayPoint>],
cx: &mut ViewContext<Editor>,
@@ -2525,9 +2509,8 @@ impl LineWithInvisibles {
};
let x_offset = self.line.x_for_index(token_offset);
- let invisible_offset = (layout.position_map.em_width - invisible_symbol.width())
- .max(Pixels::from(0.0))
- / 2.0;
+ let invisible_offset =
+ (layout.position_map.em_width - invisible_symbol.width).max(Pixels::ZERO) / 2.0;
let origin =
content_origin + gpui::point(-scroll_left + x_offset + invisible_offset, line_y);
@@ -2600,9 +2583,9 @@ impl Element<Editor> for EditorElement {
self.paint_background(gutter_bounds, text_bounds, &layout, cx);
if layout.gutter_size.width > Pixels::ZERO {
- self.paint_gutter(gutter_bounds, layout, editor, cx);
+ self.paint_gutter(gutter_bounds, &layout, editor, cx);
}
- self.paint_text(text_bounds, layout, editor, cx);
+ self.paint_text(text_bounds, &layout, editor, cx);
});
}
}
@@ -3342,7 +3325,7 @@ fn layout_line(
.text_system()
.layout_text(
&line,
- style.text.font_size * cx.rem_size(),
+ style.text.font_size.to_pixels(cx.rem_size()),
&[TextRun {
len: snapshot.line_len(row) as usize,
font: style.text.font(),
@@ -3475,7 +3458,7 @@ impl HighlightedRange {
bounds: Bounds<Pixels>,
cx: &mut WindowContext,
) {
- if lines.is_empty {
+ if lines.is_empty() {
return;
}
@@ -74,7 +74,7 @@ impl<V: 'static> Element<V> for Text<V> {
) -> LayoutId {
let text_system = cx.text_system().clone();
let text_style = cx.text_style();
- let font_size = text_style.font_size * cx.rem_size();
+ let font_size = text_style.font_size.to_pixels(cx.rem_size());
let line_height = text_style
.line_height
.to_pixels(font_size.into(), cx.rem_size());
@@ -1,7 +1,7 @@
use crate::{
black, phi, point, rems, AbsoluteLength, BorrowAppContext, BorrowWindow, Bounds, ContentMask,
Corners, CornersRefinement, DefiniteLength, Edges, EdgesRefinement, Font, FontFeatures,
- FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rems, Result, Rgba,
+ FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Result, Rgba,
SharedString, Size, SizeRefinement, Styled, TextRun, ViewContext, WindowContext,
};
use refineable::{Cascade, Refineable};
@@ -121,7 +121,7 @@ pub struct TextStyle {
pub color: Hsla,
pub font_family: SharedString,
pub font_features: FontFeatures,
- pub font_size: Rems,
+ pub font_size: AbsoluteLength,
pub line_height: DefiniteLength,
pub font_weight: FontWeight,
pub font_style: FontStyle,
@@ -134,7 +134,7 @@ impl Default for TextStyle {
color: black(),
font_family: "Helvetica".into(), // todo!("Get a font we know exists on the system")
font_features: FontFeatures::default(),
- font_size: rems(1.),
+ font_size: rems(1.).into(),
line_height: phi(),
font_weight: FontWeight::default(),
font_style: FontStyle::default(),
@@ -1,6 +1,7 @@
use crate::{
- self as gpui2, hsla, point, px, relative, rems, AlignItems, DefiniteLength, Display, Fill,
- FlexDirection, Hsla, JustifyContent, Length, Position, Rems, SharedString, StyleRefinement,
+ self as gpui2, hsla, point, px, relative, rems, AbsoluteLength, AlignItems, DefiniteLength,
+ Display, Fill, FlexDirection, Hsla, JustifyContent, Length, Position, SharedString,
+ StyleRefinement,
};
use crate::{BoxShadow, TextStyleRefinement};
use smallvec::smallvec;
@@ -384,7 +385,7 @@ pub trait Styled {
self
}
- fn text_size(mut self, size: impl Into<Rems>) -> Self
+ fn text_size(mut self, size: impl Into<AbsoluteLength>) -> Self
where
Self: Sized,
{
@@ -400,7 +401,7 @@ pub trait Styled {
{
self.text_style()
.get_or_insert_with(Default::default)
- .font_size = Some(rems(0.75));
+ .font_size = Some(rems(0.75).into());
self
}
@@ -410,7 +411,7 @@ pub trait Styled {
{
self.text_style()
.get_or_insert_with(Default::default)
- .font_size = Some(rems(0.875));
+ .font_size = Some(rems(0.875).into());
self
}
@@ -420,7 +421,7 @@ pub trait Styled {
{
self.text_style()
.get_or_insert_with(Default::default)
- .font_size = Some(rems(1.0));
+ .font_size = Some(rems(1.0).into());
self
}
@@ -430,7 +431,7 @@ pub trait Styled {
{
self.text_style()
.get_or_insert_with(Default::default)
- .font_size = Some(rems(1.125));
+ .font_size = Some(rems(1.125).into());
self
}
@@ -440,7 +441,7 @@ pub trait Styled {
{
self.text_style()
.get_or_insert_with(Default::default)
- .font_size = Some(rems(1.25));
+ .font_size = Some(rems(1.25).into());
self
}
@@ -450,7 +451,7 @@ pub trait Styled {
{
self.text_style()
.get_or_insert_with(Default::default)
- .font_size = Some(rems(1.5));
+ .font_size = Some(rems(1.5).into());
self
}
@@ -460,7 +461,7 @@ pub trait Styled {
{
self.text_style()
.get_or_insert_with(Default::default)
- .font_size = Some(rems(1.875));
+ .font_size = Some(rems(1.875).into());
self
}
@@ -82,18 +82,6 @@ impl LineLayout {
self.width
}
- pub fn font_for_index(&self, index: usize) -> Option<FontId> {
- for run in &self.runs {
- for glyph in &run.glyphs {
- if glyph.index >= index {
- return Some(run.font_id);
- }
- }
- }
-
- None
- }
-
fn compute_wrap_boundaries(
&self,
text: &str,
@@ -6,6 +6,8 @@ mod scale;
mod settings;
mod syntax;
+use std::sync::Arc;
+
use ::settings::Settings;
pub use colors::*;
pub use default_colors::*;
@@ -29,11 +31,11 @@ pub fn init(cx: &mut AppContext) {
}
pub trait ActiveTheme {
- fn theme(&self) -> &ThemeVariant;
+ fn theme(&self) -> &Arc<ThemeVariant>;
}
impl ActiveTheme for AppContext {
- fn theme(&self) -> &ThemeVariant {
+ fn theme(&self) -> &Arc<ThemeVariant> {
&ThemeSettings::get_global(self).active_theme
}
}
@@ -38,6 +38,7 @@ use std::{
thread,
time::{SystemTime, UNIX_EPOCH},
};
+use theme::ActiveTheme;
use util::{
async_maybe,
channel::{parse_zed_link, ReleaseChannel, RELEASE_CHANNEL},
@@ -164,7 +165,7 @@ fn main() {
// .detach();
// watch_file_types(fs.clone(), cx);
- // languages.set_theme(theme::current(cx).clone());
+ languages.set_theme(cx.theme().clone());
// cx.observe_global::<SettingsStore, _>({
// let languages = languages.clone();
// move |cx| languages.set_theme(theme::current(cx).clone())