Merge branch 'main' into dispatch-tree
This commit is contained in:
commit
f464d69ff8
20 changed files with 2801 additions and 2730 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -1275,11 +1275,10 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
version = "1.0.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||
checksum = "0f8e7c90afad890484a21653d08b6e209ae34770fb5ee298f9c699fcc1e5c856"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
]
|
||||
|
||||
|
@ -4395,15 +4394,6 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "journal"
|
||||
version = "0.1.0"
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"bindings": {
|
||||
"ctrl->": "zed::IncreaseBufferFontSize",
|
||||
"ctrl-<": "zed::DecreaseBufferFontSize",
|
||||
"ctrl-shift-j": "editor::JoinLines",
|
||||
"cmd-d": "editor::DuplicateLine",
|
||||
"cmd-backspace": "editor::DeleteLine",
|
||||
"cmd-pagedown": "editor::MovePageDown",
|
||||
|
@ -18,7 +19,7 @@
|
|||
"cmd-alt-enter": "editor::NewlineAbove",
|
||||
"shift-enter": "editor::NewlineBelow",
|
||||
"cmd--": "editor::Fold",
|
||||
"cmd-=": "editor::UnfoldLines",
|
||||
"cmd-+": "editor::UnfoldLines",
|
||||
"alt-shift-g": "editor::SplitSelectionIntoLines",
|
||||
"ctrl-g": [
|
||||
"editor::SelectNext",
|
||||
|
|
|
@ -6,9 +6,12 @@ use gpui::{
|
|||
WeakView, WindowContext,
|
||||
};
|
||||
use picker::{Picker, PickerDelegate};
|
||||
use std::cmp::{self, Reverse};
|
||||
use std::{
|
||||
cmp::{self, Reverse},
|
||||
sync::Arc,
|
||||
};
|
||||
use theme::ActiveTheme;
|
||||
use ui::{modal, Label};
|
||||
use ui::{v_stack, HighlightedLabel, StyledExt};
|
||||
use util::{
|
||||
channel::{parse_zed_link, ReleaseChannel, RELEASE_CHANNEL},
|
||||
ResultExt,
|
||||
|
@ -76,8 +79,8 @@ impl Modal for CommandPalette {
|
|||
impl Render for CommandPalette {
|
||||
type Element = Div<Self>;
|
||||
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
modal(cx).w_96().child(self.picker.clone())
|
||||
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
|
||||
v_stack().w_96().child(self.picker.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,6 +150,10 @@ impl CommandPaletteDelegate {
|
|||
impl PickerDelegate for CommandPaletteDelegate {
|
||||
type ListItem = Div<Picker<Self>>;
|
||||
|
||||
fn placeholder_text(&self) -> Arc<str> {
|
||||
"Execute a command...".into()
|
||||
}
|
||||
|
||||
fn match_count(&self) -> usize {
|
||||
self.matches.len()
|
||||
}
|
||||
|
@ -296,25 +303,25 @@ impl PickerDelegate for CommandPaletteDelegate {
|
|||
cx: &mut ViewContext<Picker<Self>>,
|
||||
) -> Self::ListItem {
|
||||
let colors = cx.theme().colors();
|
||||
let Some(command) = self
|
||||
.matches
|
||||
.get(ix)
|
||||
.and_then(|m| self.commands.get(m.candidate_id))
|
||||
else {
|
||||
let Some(r#match) = self.matches.get(ix) else {
|
||||
return div();
|
||||
};
|
||||
let Some(command) = self.commands.get(r#match.candidate_id) else {
|
||||
return div();
|
||||
};
|
||||
|
||||
div()
|
||||
.px_1()
|
||||
.text_color(colors.text)
|
||||
.when(selected, |s| {
|
||||
s.border_l_10().border_color(colors.terminal_ansi_yellow)
|
||||
})
|
||||
.hover(|style| {
|
||||
style
|
||||
.bg(colors.element_active)
|
||||
.text_color(colors.text_accent)
|
||||
})
|
||||
.child(Label::new(command.name.clone()))
|
||||
.text_ui()
|
||||
.bg(colors.ghost_element_background)
|
||||
.rounded_md()
|
||||
.when(selected, |this| this.bg(colors.ghost_element_selected))
|
||||
.hover(|this| this.bg(colors.ghost_element_hover))
|
||||
.child(HighlightedLabel::new(
|
||||
command.name.clone(),
|
||||
r#match.positions.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
// fn render_match(
|
||||
|
|
|
@ -97,7 +97,7 @@ use text::{OffsetUtf16, Rope};
|
|||
use theme::{
|
||||
ActiveTheme, DiagnosticStyle, PlayerColor, SyntaxTheme, Theme, ThemeColors, ThemeSettings,
|
||||
};
|
||||
use ui::IconButton;
|
||||
use ui::{IconButton, StyledExt};
|
||||
use util::{post_inc, RangeExt, ResultExt, TryFutureExt};
|
||||
use workspace::{
|
||||
item::ItemEvent, searchable::SearchEvent, ItemNavHistory, SplitDirection, ViewId, Workspace,
|
||||
|
@ -1555,6 +1555,7 @@ impl CodeActionsMenu {
|
|||
let colors = cx.theme().colors();
|
||||
div()
|
||||
.px_2()
|
||||
.text_ui()
|
||||
.text_color(colors.text)
|
||||
.when(selected, |style| {
|
||||
style
|
||||
|
@ -1582,7 +1583,7 @@ impl CodeActionsMenu {
|
|||
.collect()
|
||||
},
|
||||
)
|
||||
.bg(cx.theme().colors().element_background)
|
||||
.elevation_1(cx)
|
||||
.px_2()
|
||||
.py_1()
|
||||
.with_width_from_item(
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
use gpui::TestAppContext;
|
||||
use language::language_settings::{AllLanguageSettings, AllLanguageSettingsContent};
|
||||
use settings::SettingsStore;
|
||||
|
||||
// use super::*;
|
||||
// use crate::{
|
||||
// scroll::scroll_amount::ScrollAmount,
|
||||
|
@ -8152,16 +8156,16 @@
|
|||
// });
|
||||
// }
|
||||
|
||||
// pub(crate) fn update_test_language_settings(
|
||||
// cx: &mut TestAppContext,
|
||||
// f: impl Fn(&mut AllLanguageSettingsContent),
|
||||
// ) {
|
||||
// cx.update(|cx| {
|
||||
// cx.update_global::<SettingsStore, _, _>(|store, cx| {
|
||||
// store.update_user_settings::<AllLanguageSettings>(cx, f);
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
pub(crate) fn update_test_language_settings(
|
||||
cx: &mut TestAppContext,
|
||||
f: impl Fn(&mut AllLanguageSettingsContent),
|
||||
) {
|
||||
cx.update(|cx| {
|
||||
cx.update_global::<SettingsStore, _>(|store, cx| {
|
||||
store.update_user_settings::<AllLanguageSettings>(cx, f);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// pub(crate) fn update_test_project_settings(
|
||||
// cx: &mut TestAppContext,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,19 +11,18 @@ pub enum ScrollAmount {
|
|||
|
||||
impl ScrollAmount {
|
||||
pub fn lines(&self, editor: &mut Editor) -> f32 {
|
||||
todo!()
|
||||
// match self {
|
||||
// Self::Line(count) => *count,
|
||||
// Self::Page(count) => editor
|
||||
// .visible_line_count()
|
||||
// .map(|mut l| {
|
||||
// // for full pages subtract one to leave an anchor line
|
||||
// if count.abs() == 1.0 {
|
||||
// l -= 1.0
|
||||
// }
|
||||
// (l * count).trunc()
|
||||
// })
|
||||
// .unwrap_or(0.),
|
||||
// }
|
||||
match self {
|
||||
Self::Line(count) => *count,
|
||||
Self::Page(count) => editor
|
||||
.visible_line_count()
|
||||
.map(|mut l| {
|
||||
// for full pages subtract one to leave an anchor line
|
||||
if count.abs() == 1.0 {
|
||||
l -= 1.0
|
||||
}
|
||||
(l * count).trunc()
|
||||
})
|
||||
.unwrap_or(0.),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,14 +67,21 @@ impl<V: 'static> Flex<V> {
|
|||
where
|
||||
Tag: 'static,
|
||||
{
|
||||
// Don't assume that this initialization is what scroll_state really is in other panes:
|
||||
// `element_state` is shared and there could be init races.
|
||||
let scroll_state = cx.element_state::<Tag, Rc<ScrollState>>(
|
||||
element_id,
|
||||
Rc::new(ScrollState {
|
||||
scroll_to: Cell::new(scroll_to),
|
||||
scroll_position: Default::default(),
|
||||
type_tag: TypeTag::new::<Tag>(),
|
||||
scroll_to: Default::default(),
|
||||
scroll_position: Default::default(),
|
||||
}),
|
||||
);
|
||||
// Set scroll_to separately, because the default state is already picked as `None` by other panes
|
||||
// by the time we start setting it here, hence update all others' state too.
|
||||
scroll_state.update(cx, |this, _| {
|
||||
this.scroll_to.set(scroll_to);
|
||||
});
|
||||
self.scroll_state = Some((scroll_state, cx.handle().id()));
|
||||
self
|
||||
}
|
||||
|
|
|
@ -182,7 +182,8 @@ impl Platform for TestPlatform {
|
|||
}
|
||||
|
||||
fn should_auto_hide_scrollbars(&self) -> bool {
|
||||
unimplemented!()
|
||||
// todo()
|
||||
true
|
||||
}
|
||||
|
||||
fn write_to_clipboard(&self, _item: crate::ClipboardItem) {
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
use std::{rc::Rc, sync::Arc};
|
||||
use std::{
|
||||
rc::Rc,
|
||||
sync::{self, Arc},
|
||||
};
|
||||
|
||||
use collections::HashMap;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use crate::{
|
||||
px, Pixels, PlatformAtlas, PlatformDisplay, PlatformWindow, Point, Scene, Size,
|
||||
WindowAppearance, WindowBounds, WindowOptions,
|
||||
px, AtlasKey, AtlasTextureId, AtlasTile, Pixels, PlatformAtlas, PlatformDisplay,
|
||||
PlatformWindow, Point, Scene, Size, TileId, WindowAppearance, WindowBounds, WindowOptions,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -30,7 +34,7 @@ impl TestWindow {
|
|||
current_scene: Default::default(),
|
||||
display,
|
||||
|
||||
sprite_atlas: Arc::new(TestAtlas),
|
||||
sprite_atlas: Arc::new(TestAtlas::new()),
|
||||
handlers: Default::default(),
|
||||
}
|
||||
}
|
||||
|
@ -154,26 +158,71 @@ impl PlatformWindow for TestWindow {
|
|||
self.current_scene.lock().replace(scene);
|
||||
}
|
||||
|
||||
fn sprite_atlas(&self) -> std::sync::Arc<dyn crate::PlatformAtlas> {
|
||||
fn sprite_atlas(&self) -> sync::Arc<dyn crate::PlatformAtlas> {
|
||||
self.sprite_atlas.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TestAtlas;
|
||||
pub struct TestAtlasState {
|
||||
next_id: u32,
|
||||
tiles: HashMap<AtlasKey, AtlasTile>,
|
||||
}
|
||||
|
||||
pub struct TestAtlas(Mutex<TestAtlasState>);
|
||||
|
||||
impl TestAtlas {
|
||||
pub fn new() -> Self {
|
||||
TestAtlas(Mutex::new(TestAtlasState {
|
||||
next_id: 0,
|
||||
tiles: HashMap::default(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl PlatformAtlas for TestAtlas {
|
||||
fn get_or_insert_with<'a>(
|
||||
&self,
|
||||
_key: &crate::AtlasKey,
|
||||
_build: &mut dyn FnMut() -> anyhow::Result<(
|
||||
key: &crate::AtlasKey,
|
||||
build: &mut dyn FnMut() -> anyhow::Result<(
|
||||
Size<crate::DevicePixels>,
|
||||
std::borrow::Cow<'a, [u8]>,
|
||||
)>,
|
||||
) -> anyhow::Result<crate::AtlasTile> {
|
||||
todo!()
|
||||
let mut state = self.0.lock();
|
||||
if let Some(tile) = state.tiles.get(key) {
|
||||
return Ok(tile.clone());
|
||||
}
|
||||
|
||||
state.next_id += 1;
|
||||
let texture_id = state.next_id;
|
||||
state.next_id += 1;
|
||||
let tile_id = state.next_id;
|
||||
|
||||
drop(state);
|
||||
let (size, _) = build()?;
|
||||
let mut state = self.0.lock();
|
||||
|
||||
state.tiles.insert(
|
||||
key.clone(),
|
||||
crate::AtlasTile {
|
||||
texture_id: AtlasTextureId {
|
||||
index: texture_id,
|
||||
kind: crate::AtlasTextureKind::Path,
|
||||
},
|
||||
tile_id: TileId(tile_id),
|
||||
bounds: crate::Bounds {
|
||||
origin: Point::zero(),
|
||||
size,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
Ok(state.tiles[key].clone())
|
||||
}
|
||||
|
||||
fn clear(&self) {
|
||||
todo!()
|
||||
let mut state = self.0.lock();
|
||||
state.tiles = HashMap::default();
|
||||
state.next_id = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,8 @@ use gpui::{
|
|||
div, uniform_list, Component, Div, ParentElement, Render, StatelessInteractive, Styled, Task,
|
||||
UniformListScrollHandle, View, ViewContext, VisualContext, WindowContext,
|
||||
};
|
||||
use std::cmp;
|
||||
use theme::ActiveTheme;
|
||||
use ui::v_stack;
|
||||
use std::{cmp, sync::Arc};
|
||||
use ui::{prelude::*, v_stack, Divider, Label, LabelColor};
|
||||
|
||||
pub struct Picker<D: PickerDelegate> {
|
||||
pub delegate: D,
|
||||
|
@ -21,7 +20,7 @@ pub trait PickerDelegate: Sized + 'static {
|
|||
fn selected_index(&self) -> usize;
|
||||
fn set_selected_index(&mut self, ix: usize, cx: &mut ViewContext<Picker<Self>>);
|
||||
|
||||
// fn placeholder_text(&self) -> Arc<str>;
|
||||
fn placeholder_text(&self) -> Arc<str>;
|
||||
fn update_matches(&mut self, query: String, cx: &mut ViewContext<Picker<Self>>) -> Task<()>;
|
||||
|
||||
fn confirm(&mut self, secondary: bool, cx: &mut ViewContext<Picker<Self>>);
|
||||
|
@ -37,7 +36,11 @@ pub trait PickerDelegate: Sized + 'static {
|
|||
|
||||
impl<D: PickerDelegate> Picker<D> {
|
||||
pub fn new(delegate: D, cx: &mut ViewContext<Self>) -> Self {
|
||||
let editor = cx.build_view(|cx| Editor::single_line(cx));
|
||||
let editor = cx.build_view(|cx| {
|
||||
let mut editor = Editor::single_line(cx);
|
||||
editor.set_placeholder_text(delegate.placeholder_text(), cx);
|
||||
editor
|
||||
});
|
||||
cx.subscribe(&editor, Self::on_input_editor_event).detach();
|
||||
Self {
|
||||
delegate,
|
||||
|
@ -142,6 +145,7 @@ impl<D: PickerDelegate> Render for Picker<D> {
|
|||
div()
|
||||
.context("picker")
|
||||
.size_full()
|
||||
.elevation_2(cx)
|
||||
.on_action(Self::select_next)
|
||||
.on_action(Self::select_prev)
|
||||
.on_action(Self::select_first)
|
||||
|
@ -149,38 +153,42 @@ impl<D: PickerDelegate> Render for Picker<D> {
|
|||
.on_action(Self::cancel)
|
||||
.on_action(Self::confirm)
|
||||
.on_action(Self::secondary_confirm)
|
||||
.child(
|
||||
v_stack().gap_px().child(
|
||||
v_stack()
|
||||
.py_0p5()
|
||||
.px_1()
|
||||
.child(div().px_2().py_0p5().child(self.editor.clone())),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.h_px()
|
||||
.w_full()
|
||||
.bg(cx.theme().colors().element_background),
|
||||
)
|
||||
.child(
|
||||
v_stack()
|
||||
.py_0p5()
|
||||
.px_1()
|
||||
.grow()
|
||||
.child(
|
||||
uniform_list("candidates", self.delegate.match_count(), {
|
||||
move |this: &mut Self, visible_range, cx| {
|
||||
let selected_ix = this.delegate.selected_index();
|
||||
visible_range
|
||||
.map(|ix| this.delegate.render_match(ix, ix == selected_ix, cx))
|
||||
.collect()
|
||||
}
|
||||
})
|
||||
.track_scroll(self.scroll_handle.clone()),
|
||||
)
|
||||
.max_h_72()
|
||||
.overflow_hidden(),
|
||||
.child(div().px_1().py_0p5().child(self.editor.clone())),
|
||||
)
|
||||
.child(Divider::horizontal())
|
||||
.when(self.delegate.match_count() > 0, |el| {
|
||||
el.child(
|
||||
v_stack()
|
||||
.p_1()
|
||||
.grow()
|
||||
.child(
|
||||
uniform_list("candidates", self.delegate.match_count(), {
|
||||
move |this: &mut Self, visible_range, cx| {
|
||||
let selected_ix = this.delegate.selected_index();
|
||||
visible_range
|
||||
.map(|ix| {
|
||||
this.delegate.render_match(ix, ix == selected_ix, cx)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
})
|
||||
.track_scroll(self.scroll_handle.clone()),
|
||||
)
|
||||
.max_h_72()
|
||||
.overflow_hidden(),
|
||||
)
|
||||
})
|
||||
.when(self.delegate.match_count() == 0, |el| {
|
||||
el.child(
|
||||
v_stack()
|
||||
.p_1()
|
||||
.grow()
|
||||
.child(Label::new("No matches").color(LabelColor::Muted)),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,10 @@ impl PickerDelegate for Delegate {
|
|||
self.candidates.len()
|
||||
}
|
||||
|
||||
fn placeholder_text(&self) -> Arc<str> {
|
||||
"Test".into()
|
||||
}
|
||||
|
||||
fn render_match(
|
||||
&self,
|
||||
ix: usize,
|
||||
|
|
|
@ -3,6 +3,7 @@ mod button;
|
|||
mod checkbox;
|
||||
mod context_menu;
|
||||
mod details;
|
||||
mod divider;
|
||||
mod elevated_surface;
|
||||
mod facepile;
|
||||
mod icon;
|
||||
|
@ -31,6 +32,7 @@ pub use button::*;
|
|||
pub use checkbox::*;
|
||||
pub use context_menu::*;
|
||||
pub use details::*;
|
||||
pub use divider::*;
|
||||
pub use elevated_surface::*;
|
||||
pub use facepile::*;
|
||||
pub use icon::*;
|
||||
|
|
46
crates/ui2/src/components/divider.rs
Normal file
46
crates/ui2/src/components/divider.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
enum DividerDirection {
|
||||
Horizontal,
|
||||
Vertical,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Divider {
|
||||
direction: DividerDirection,
|
||||
inset: bool,
|
||||
}
|
||||
|
||||
impl Divider {
|
||||
pub fn horizontal() -> Self {
|
||||
Self {
|
||||
direction: DividerDirection::Horizontal,
|
||||
inset: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vertical() -> Self {
|
||||
Self {
|
||||
direction: DividerDirection::Vertical,
|
||||
inset: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inset(mut self) -> Self {
|
||||
self.inset = true;
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
div()
|
||||
.map(|this| match self.direction {
|
||||
DividerDirection::Horizontal => {
|
||||
this.h_px().w_full().when(self.inset, |this| this.mx_1p5())
|
||||
}
|
||||
DividerDirection::Vertical => {
|
||||
this.w_px().h_full().when(self.inset, |this| this.my_1p5())
|
||||
}
|
||||
})
|
||||
.bg(cx.theme().colors().border_variant)
|
||||
}
|
||||
}
|
|
@ -24,5 +24,5 @@ pub fn elevated_surface<V: 'static>(level: ElevationIndex, cx: &mut ViewContext<
|
|||
}
|
||||
|
||||
pub fn modal<V>(cx: &mut ViewContext<V>) -> Div<V> {
|
||||
elevated_surface(ElevationIndex::ModalSurfaces, cx)
|
||||
elevated_surface(ElevationIndex::ModalSurface, cx)
|
||||
}
|
||||
|
|
|
@ -401,7 +401,7 @@ impl List {
|
|||
v_stack()
|
||||
.w_full()
|
||||
.py_1()
|
||||
.children(self.header.map(|header| header))
|
||||
.children(self.header)
|
||||
.child(list_content)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@ Material Design 3 has a some great visualizations of elevation that may be helpf
|
|||
|
||||
The app background constitutes the lowest elevation layer, appearing behind all other surfaces and components. It is predominantly used for the background color of the app.
|
||||
|
||||
### UI Surface
|
||||
### Surface
|
||||
|
||||
The UI Surface, located above the app background, is the standard level for all elements
|
||||
The Surface elevation level, located above the app background, is the standard level for all elements
|
||||
|
||||
Example Elements: Title Bar, Panel, Tab Bar, Editor
|
||||
|
||||
|
|
|
@ -11,43 +11,53 @@ pub enum Elevation {
|
|||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ElevationIndex {
|
||||
AppBackground,
|
||||
UISurface,
|
||||
Background,
|
||||
Surface,
|
||||
ElevatedSurface,
|
||||
Wash,
|
||||
ModalSurfaces,
|
||||
ModalSurface,
|
||||
DraggedElement,
|
||||
}
|
||||
|
||||
impl ElevationIndex {
|
||||
pub fn z_index(self) -> u32 {
|
||||
match self {
|
||||
ElevationIndex::AppBackground => 0,
|
||||
ElevationIndex::UISurface => 100,
|
||||
ElevationIndex::Background => 0,
|
||||
ElevationIndex::Surface => 100,
|
||||
ElevationIndex::ElevatedSurface => 200,
|
||||
ElevationIndex::Wash => 300,
|
||||
ElevationIndex::ModalSurfaces => 400,
|
||||
ElevationIndex::ModalSurface => 400,
|
||||
ElevationIndex::DraggedElement => 900,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shadow(self) -> SmallVec<[BoxShadow; 2]> {
|
||||
match self {
|
||||
ElevationIndex::AppBackground => smallvec![],
|
||||
ElevationIndex::Surface => smallvec![],
|
||||
|
||||
ElevationIndex::UISurface => smallvec![BoxShadow {
|
||||
ElevationIndex::ElevatedSurface => smallvec![BoxShadow {
|
||||
color: hsla(0., 0., 0., 0.12),
|
||||
offset: point(px(0.), px(1.)),
|
||||
blur_radius: px(3.),
|
||||
spread_radius: px(0.),
|
||||
}],
|
||||
|
||||
_ => smallvec![BoxShadow {
|
||||
color: hsla(0., 0., 0., 0.32),
|
||||
offset: point(px(1.), px(3.)),
|
||||
blur_radius: px(12.),
|
||||
spread_radius: px(0.),
|
||||
}],
|
||||
ElevationIndex::ModalSurface => smallvec![
|
||||
BoxShadow {
|
||||
color: hsla(0., 0., 0., 0.12),
|
||||
offset: point(px(0.), px(1.)),
|
||||
blur_radius: px(3.),
|
||||
spread_radius: px(0.),
|
||||
},
|
||||
BoxShadow {
|
||||
color: hsla(0., 0., 0., 0.16),
|
||||
offset: point(px(3.), px(1.)),
|
||||
blur_radius: px(12.),
|
||||
spread_radius: px(0.),
|
||||
},
|
||||
],
|
||||
|
||||
_ => smallvec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +1,33 @@
|
|||
use gpui::{Div, ElementInteractivity, KeyDispatch, Styled};
|
||||
use gpui::{Div, ElementInteractivity, KeyDispatch, Styled, UniformList, ViewContext};
|
||||
use theme2::ActiveTheme;
|
||||
|
||||
use crate::UITextSize;
|
||||
use crate::{ElevationIndex, UITextSize};
|
||||
|
||||
fn elevated<E: Styled, V: 'static>(this: E, cx: &mut ViewContext<V>, index: ElevationIndex) -> E {
|
||||
this.bg(cx.theme().colors().elevated_surface_background)
|
||||
.rounded_lg()
|
||||
.border()
|
||||
.border_color(cx.theme().colors().border_variant)
|
||||
.shadow(index.shadow())
|
||||
}
|
||||
|
||||
/// Extends [`Styled`](gpui::Styled) with Zed specific styling methods.
|
||||
pub trait StyledExt: Styled {
|
||||
pub trait StyledExt: Styled + Sized {
|
||||
/// Horizontally stacks elements.
|
||||
///
|
||||
/// Sets `flex()`, `flex_row()`, `items_center()`
|
||||
fn h_flex(self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
fn h_flex(self) -> Self {
|
||||
self.flex().flex_row().items_center()
|
||||
}
|
||||
|
||||
/// Vertically stacks elements.
|
||||
///
|
||||
/// Sets `flex()`, `flex_col()`
|
||||
fn v_flex(self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
fn v_flex(self) -> Self {
|
||||
self.flex().flex_col()
|
||||
}
|
||||
|
||||
fn text_ui_size(self, size: UITextSize) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
fn text_ui_size(self, size: UITextSize) -> Self {
|
||||
let size = size.rems();
|
||||
|
||||
self.text_size(size)
|
||||
|
@ -40,10 +40,7 @@ pub trait StyledExt: Styled {
|
|||
/// Note: The absolute size of this text will change based on a user's `ui_scale` setting.
|
||||
///
|
||||
/// Use [`text_ui_sm`] for regular-sized text.
|
||||
fn text_ui(self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
fn text_ui(self) -> Self {
|
||||
let size = UITextSize::default().rems();
|
||||
|
||||
self.text_size(size)
|
||||
|
@ -56,14 +53,44 @@ pub trait StyledExt: Styled {
|
|||
/// Note: The absolute size of this text will change based on a user's `ui_scale` setting.
|
||||
///
|
||||
/// Use [`text_ui`] for regular-sized text.
|
||||
fn text_ui_sm(self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
fn text_ui_sm(self) -> Self {
|
||||
let size = UITextSize::Small.rems();
|
||||
|
||||
self.text_size(size)
|
||||
}
|
||||
|
||||
/// The [`Surface`](ui2::ElevationIndex::Surface) elevation level, located above the app background, is the standard level for all elements
|
||||
///
|
||||
/// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
|
||||
///
|
||||
/// Example Elements: Title Bar, Panel, Tab Bar, Editor
|
||||
fn elevation_1<V: 'static>(self, cx: &mut ViewContext<V>) -> Self {
|
||||
elevated(self, cx, ElevationIndex::Surface)
|
||||
}
|
||||
|
||||
/// Non-Modal Elevated Surfaces appear above the [`Surface`](ui2::ElevationIndex::Surface) layer and is used for things that should appear above most UI elements like an editor or panel, but not elements like popovers, context menus, modals, etc.
|
||||
///
|
||||
/// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
|
||||
///
|
||||
/// Examples: Notifications, Palettes, Detached/Floating Windows, Detached/Floating Panels
|
||||
fn elevation_2<V: 'static>(self, cx: &mut ViewContext<V>) -> Self {
|
||||
elevated(self, cx, ElevationIndex::ElevatedSurface)
|
||||
}
|
||||
|
||||
// There is no elevation 3, as the third elevation level is reserved for wash layers. See [`Elevation`](ui2::Elevation).
|
||||
|
||||
/// Modal Surfaces are used for elements that should appear above all other UI elements and are located above the wash layer. This is the maximum elevation at which UI elements can be rendered in their default state.
|
||||
///
|
||||
/// Elements rendered at this layer should have an enforced behavior: Any interaction outside of the modal will either dismiss the modal or prompt an action (Save your progress, etc) then dismiss the modal.
|
||||
///
|
||||
/// If the element does not have this behavior, it should be rendered at the [`Elevated Surface`](ui2::ElevationIndex::ElevatedSurface) layer.
|
||||
///
|
||||
/// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
|
||||
///
|
||||
/// Examples: Settings Modal, Channel Management, Wizards/Setup UI, Dialogs
|
||||
fn elevation_4<V: 'static>(self, cx: &mut ViewContext<V>) -> Self {
|
||||
elevated(self, cx, ElevationIndex::ModalSurface)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, I, F> StyledExt for Div<V, I, F>
|
||||
|
@ -72,3 +99,5 @@ where
|
|||
F: KeyDispatch<V>,
|
||||
{
|
||||
}
|
||||
|
||||
impl<V> StyledExt for UniformList<V> {}
|
||||
|
|
|
@ -3448,27 +3448,27 @@ impl Workspace {
|
|||
})
|
||||
}
|
||||
|
||||
// todo!()
|
||||
// #[cfg(any(test, feature = "test-support"))]
|
||||
// pub fn test_new(project: ModelHandle<Project>, cx: &mut ViewContext<Self>) -> Self {
|
||||
// use node_runtime::FakeNodeRuntime;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn test_new(project: Model<Project>, cx: &mut ViewContext<Self>) -> Self {
|
||||
use gpui::Context;
|
||||
use node_runtime::FakeNodeRuntime;
|
||||
|
||||
// let client = project.read(cx).client();
|
||||
// let user_store = project.read(cx).user_store();
|
||||
let client = project.read(cx).client();
|
||||
let user_store = project.read(cx).user_store();
|
||||
|
||||
// let workspace_store = cx.add_model(|cx| WorkspaceStore::new(client.clone(), cx));
|
||||
// let app_state = Arc::new(AppState {
|
||||
// languages: project.read(cx).languages().clone(),
|
||||
// workspace_store,
|
||||
// client,
|
||||
// user_store,
|
||||
// fs: project.read(cx).fs().clone(),
|
||||
// build_window_options: |_, _, _| Default::default(),
|
||||
// initialize_workspace: |_, _, _, _| Task::ready(Ok(())),
|
||||
// node_runtime: FakeNodeRuntime::new(),
|
||||
// });
|
||||
// Self::new(0, project, app_state, cx)
|
||||
// }
|
||||
let workspace_store = cx.build_model(|cx| WorkspaceStore::new(client.clone(), cx));
|
||||
let app_state = Arc::new(AppState {
|
||||
languages: project.read(cx).languages().clone(),
|
||||
workspace_store,
|
||||
client,
|
||||
user_store,
|
||||
fs: project.read(cx).fs().clone(),
|
||||
build_window_options: |_, _, _| Default::default(),
|
||||
initialize_workspace: |_, _, _, _| Task::ready(Ok(())),
|
||||
node_runtime: FakeNodeRuntime::new(),
|
||||
});
|
||||
Self::new(0, project, app_state, cx)
|
||||
}
|
||||
|
||||
// fn render_dock(&self, position: DockPosition, cx: &WindowContext) -> Option<AnyElement<Self>> {
|
||||
// let dock = match position {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue