Merge remote-tracking branch 'origin/main' into perf-2
This commit is contained in:
commit
02606d1fb9
34 changed files with 822 additions and 1270 deletions
19
Cargo.lock
generated
19
Cargo.lock
generated
|
@ -182,7 +182,7 @@ dependencies = [
|
||||||
"alacritty_config",
|
"alacritty_config",
|
||||||
"alacritty_config_derive",
|
"alacritty_config_derive",
|
||||||
"base64 0.13.1",
|
"base64 0.13.1",
|
||||||
"bitflags 2.4.0",
|
"bitflags 2.4.1",
|
||||||
"home",
|
"home",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
@ -1025,9 +1025,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.4.0"
|
version = "2.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
|
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
@ -3280,6 +3280,7 @@ name = "feedback2"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"bitflags 2.4.1",
|
||||||
"client2",
|
"client2",
|
||||||
"db2",
|
"db2",
|
||||||
"editor2",
|
"editor2",
|
||||||
|
@ -4026,7 +4027,7 @@ dependencies = [
|
||||||
"async-task",
|
"async-task",
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bindgen 0.65.1",
|
"bindgen 0.65.1",
|
||||||
"bitflags 2.4.0",
|
"bitflags 2.4.1",
|
||||||
"block",
|
"block",
|
||||||
"cbindgen",
|
"cbindgen",
|
||||||
"cocoa",
|
"cocoa",
|
||||||
|
@ -6195,7 +6196,7 @@ version = "0.10.57"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c"
|
checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.0",
|
"bitflags 2.4.1",
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"foreign-types",
|
"foreign-types",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -7915,7 +7916,7 @@ version = "0.29.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2"
|
checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.0",
|
"bitflags 2.4.1",
|
||||||
"fallible-iterator",
|
"fallible-iterator",
|
||||||
"fallible-streaming-iterator",
|
"fallible-streaming-iterator",
|
||||||
"hashlink",
|
"hashlink",
|
||||||
|
@ -8031,7 +8032,7 @@ version = "0.38.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f"
|
checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.0",
|
"bitflags 2.4.1",
|
||||||
"errno 0.3.3",
|
"errno 0.3.3",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.4.7",
|
"linux-raw-sys 0.4.7",
|
||||||
|
@ -9134,7 +9135,7 @@ dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
"base64 0.21.4",
|
"base64 0.21.4",
|
||||||
"bigdecimal",
|
"bigdecimal",
|
||||||
"bitflags 2.4.0",
|
"bitflags 2.4.1",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes 1.5.0",
|
"bytes 1.5.0",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -9181,7 +9182,7 @@ dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
"base64 0.21.4",
|
"base64 0.21.4",
|
||||||
"bigdecimal",
|
"bigdecimal",
|
||||||
"bitflags 2.4.0",
|
"bitflags 2.4.1",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"chrono",
|
"chrono",
|
||||||
"crc",
|
"crc",
|
||||||
|
|
|
@ -2552,12 +2552,11 @@ impl CollabPanel {
|
||||||
.group("")
|
.group("")
|
||||||
.flex()
|
.flex()
|
||||||
.w_full()
|
.w_full()
|
||||||
.on_drag({
|
.on_drag(channel.clone(), move |channel, cx| {
|
||||||
let channel = channel.clone();
|
cx.build_view(|cx| DraggedChannelView {
|
||||||
move |cx| {
|
channel: channel.clone(),
|
||||||
let channel = channel.clone();
|
width,
|
||||||
cx.build_view(|cx| DraggedChannelView { channel, width })
|
})
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.drag_over::<DraggedChannelView>(|style| {
|
.drag_over::<DraggedChannelView>(|style| {
|
||||||
style.bg(cx.theme().colors().ghost_element_hover)
|
style.bg(cx.theme().colors().ghost_element_hover)
|
||||||
|
|
|
@ -9297,7 +9297,7 @@ impl Render for Editor {
|
||||||
let settings = ThemeSettings::get_global(cx);
|
let settings = ThemeSettings::get_global(cx);
|
||||||
let text_style = match self.mode {
|
let text_style = match self.mode {
|
||||||
EditorMode::SingleLine | EditorMode::AutoHeight { .. } => TextStyle {
|
EditorMode::SingleLine | EditorMode::AutoHeight { .. } => TextStyle {
|
||||||
color: cx.theme().colors().text,
|
color: cx.theme().colors().editor_foreground,
|
||||||
font_family: settings.ui_font.family.clone(),
|
font_family: settings.ui_font.family.clone(),
|
||||||
font_features: settings.ui_font.features,
|
font_features: settings.ui_font.features,
|
||||||
font_size: rems(0.875).into(),
|
font_size: rems(0.875).into(),
|
||||||
|
@ -9310,7 +9310,7 @@ impl Render for Editor {
|
||||||
},
|
},
|
||||||
|
|
||||||
EditorMode::Full => TextStyle {
|
EditorMode::Full => TextStyle {
|
||||||
color: cx.theme().colors().text,
|
color: cx.theme().colors().editor_foreground,
|
||||||
font_family: settings.buffer_font.family.clone(),
|
font_family: settings.buffer_font.family.clone(),
|
||||||
font_features: settings.buffer_font.features,
|
font_features: settings.buffer_font.features,
|
||||||
font_size: settings.buffer_font_size(cx).into(),
|
font_size: settings.buffer_font_size(cx).into(),
|
||||||
|
|
|
@ -18,7 +18,6 @@ gpui = { package = "gpui2", path = "../gpui2" }
|
||||||
language = { package = "language2", path = "../language2" }
|
language = { package = "language2", path = "../language2" }
|
||||||
menu = { package = "menu2", path = "../menu2" }
|
menu = { package = "menu2", path = "../menu2" }
|
||||||
project = { package = "project2", path = "../project2" }
|
project = { package = "project2", path = "../project2" }
|
||||||
regex.workspace = true
|
|
||||||
search = { package = "search2", path = "../search2" }
|
search = { package = "search2", path = "../search2" }
|
||||||
settings = { package = "settings2", path = "../settings2" }
|
settings = { package = "settings2", path = "../settings2" }
|
||||||
theme = { package = "theme2", path = "../theme2" }
|
theme = { package = "theme2", path = "../theme2" }
|
||||||
|
@ -26,13 +25,16 @@ ui = { package = "ui2", path = "../ui2" }
|
||||||
util = { path = "../util" }
|
util = { path = "../util" }
|
||||||
workspace = { package = "workspace2", path = "../workspace2"}
|
workspace = { package = "workspace2", path = "../workspace2"}
|
||||||
|
|
||||||
|
bitflags = "2.4.1"
|
||||||
|
human_bytes = "0.4.1"
|
||||||
|
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
human_bytes = "0.4.1"
|
|
||||||
isahc.workspace = true
|
isahc.workspace = true
|
||||||
lazy_static.workspace = true
|
lazy_static.workspace = true
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
postage.workspace = true
|
postage.workspace = true
|
||||||
|
regex.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_derive.workspace = true
|
serde_derive.workspace = true
|
||||||
smallvec.workspace = true
|
smallvec.workspace = true
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::{ops::RangeInclusive, sync::Arc, time::Duration};
|
use std::{ops::RangeInclusive, sync::Arc, time::Duration};
|
||||||
|
|
||||||
use anyhow::{anyhow, bail};
|
use anyhow::{anyhow, bail};
|
||||||
|
use bitflags::bitflags;
|
||||||
use client::{Client, ZED_SECRET_CLIENT_TOKEN, ZED_SERVER_URL};
|
use client::{Client, ZED_SECRET_CLIENT_TOKEN, ZED_SERVER_URL};
|
||||||
use db::kvp::KEY_VALUE_STORE;
|
use db::kvp::KEY_VALUE_STORE;
|
||||||
use editor::{Editor, EditorEvent};
|
use editor::{Editor, EditorEvent};
|
||||||
|
@ -48,15 +49,17 @@ struct FeedbackRequestBody<'a> {
|
||||||
token: &'a str,
|
token: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
bitflags! {
|
||||||
enum InvalidStateIssue {
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
EmailAddress,
|
struct InvalidStateFlags: u8 {
|
||||||
CharacterCount,
|
const EmailAddress = 0b00000001;
|
||||||
|
const CharacterCount = 0b00000010;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
enum CannotSubmitReason {
|
enum CannotSubmitReason {
|
||||||
InvalidState { issues: Vec<InvalidStateIssue> },
|
InvalidState { flags: InvalidStateFlags },
|
||||||
AwaitingSubmission,
|
AwaitingSubmission,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +325,7 @@ impl FeedbackModal {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut invalid_state_issues = Vec::new();
|
let mut invalid_state_flags = InvalidStateFlags::empty();
|
||||||
|
|
||||||
let valid_email_address = match self.email_address_editor.read(cx).text_option(cx) {
|
let valid_email_address = match self.email_address_editor.read(cx).text_option(cx) {
|
||||||
Some(email_address) => Regex::new(EMAIL_REGEX).unwrap().is_match(&email_address),
|
Some(email_address) => Regex::new(EMAIL_REGEX).unwrap().is_match(&email_address),
|
||||||
|
@ -330,37 +333,37 @@ impl FeedbackModal {
|
||||||
};
|
};
|
||||||
|
|
||||||
if !valid_email_address {
|
if !valid_email_address {
|
||||||
invalid_state_issues.push(InvalidStateIssue::EmailAddress);
|
invalid_state_flags |= InvalidStateFlags::EmailAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !FEEDBACK_CHAR_LIMIT.contains(&self.character_count) {
|
if !FEEDBACK_CHAR_LIMIT.contains(&self.character_count) {
|
||||||
invalid_state_issues.push(InvalidStateIssue::CharacterCount);
|
invalid_state_flags |= InvalidStateFlags::CharacterCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if invalid_state_issues.is_empty() {
|
if invalid_state_flags.is_empty() {
|
||||||
self.submission_state = Some(SubmissionState::CanSubmit);
|
self.submission_state = Some(SubmissionState::CanSubmit);
|
||||||
} else {
|
} else {
|
||||||
self.submission_state = Some(SubmissionState::CannotSubmit {
|
self.submission_state = Some(SubmissionState::CannotSubmit {
|
||||||
reason: CannotSubmitReason::InvalidState {
|
reason: CannotSubmitReason::InvalidState {
|
||||||
issues: invalid_state_issues,
|
flags: invalid_state_flags,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn valid_email_address(&self) -> bool {
|
fn valid_email_address(&self) -> bool {
|
||||||
!self.in_invalid_state(InvalidStateIssue::EmailAddress)
|
!self.in_invalid_state(InvalidStateFlags::EmailAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn valid_character_count(&self) -> bool {
|
fn valid_character_count(&self) -> bool {
|
||||||
!self.in_invalid_state(InvalidStateIssue::CharacterCount)
|
!self.in_invalid_state(InvalidStateFlags::CharacterCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn in_invalid_state(&self, a: InvalidStateIssue) -> bool {
|
fn in_invalid_state(&self, flag: InvalidStateFlags) -> bool {
|
||||||
match self.submission_state {
|
match self.submission_state {
|
||||||
Some(SubmissionState::CannotSubmit {
|
Some(SubmissionState::CannotSubmit {
|
||||||
reason: CannotSubmitReason::InvalidState { ref issues },
|
reason: CannotSubmitReason::InvalidState { ref flags },
|
||||||
}) => issues.contains(&a),
|
}) => flags.contains(flag),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1139,8 +1139,10 @@ impl AppContext {
|
||||||
self.active_drag.is_some()
|
self.active_drag.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_drag(&self) -> Option<AnyView> {
|
pub fn active_drag<T: 'static>(&self) -> Option<&T> {
|
||||||
self.active_drag.as_ref().map(|drag| drag.view.clone())
|
self.active_drag
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|drag| drag.value.downcast_ref())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1296,6 +1298,7 @@ impl<G: 'static> DerefMut for GlobalLease<G> {
|
||||||
/// within the window or by dragging into the app from the underlying platform.
|
/// within the window or by dragging into the app from the underlying platform.
|
||||||
pub struct AnyDrag {
|
pub struct AnyDrag {
|
||||||
pub view: AnyView,
|
pub view: AnyView,
|
||||||
|
pub value: Box<dyn Any>,
|
||||||
pub cursor_offset: Point<Pixels>,
|
pub cursor_offset: Point<Pixels>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ use std::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
|
marker::PhantomData,
|
||||||
mem,
|
mem,
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
|
@ -30,9 +31,18 @@ pub struct GroupStyle {
|
||||||
pub style: Box<StyleRefinement>,
|
pub style: Box<StyleRefinement>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DragMoveEvent<W: Render> {
|
pub struct DragMoveEvent<T> {
|
||||||
pub event: MouseMoveEvent,
|
pub event: MouseMoveEvent,
|
||||||
pub drag: View<W>,
|
drag: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: 'static> DragMoveEvent<T> {
|
||||||
|
pub fn drag<'b>(&self, cx: &'b AppContext) -> &'b T {
|
||||||
|
cx.active_drag
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|drag| drag.value.downcast_ref::<T>())
|
||||||
|
.expect("DragMoveEvent is only valid when the stored active drag is of the same type.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interactivity {
|
impl Interactivity {
|
||||||
|
@ -133,23 +143,26 @@ impl Interactivity {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_drag_move<W>(
|
pub fn on_drag_move<T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
listener: impl Fn(&DragMoveEvent<W>, &mut WindowContext) + 'static,
|
listener: impl Fn(&DragMoveEvent<T>, &mut WindowContext) + 'static,
|
||||||
) where
|
) where
|
||||||
W: Render,
|
T: 'static,
|
||||||
{
|
{
|
||||||
self.mouse_move_listeners
|
self.mouse_move_listeners
|
||||||
.push(Box::new(move |event, bounds, phase, cx| {
|
.push(Box::new(move |event, bounds, phase, cx| {
|
||||||
if phase == DispatchPhase::Capture
|
if phase == DispatchPhase::Capture
|
||||||
&& bounds.drag_target_contains(&event.position, cx)
|
&& bounds.drag_target_contains(&event.position, cx)
|
||||||
{
|
{
|
||||||
if let Some(view) = cx.active_drag().and_then(|view| view.downcast::<W>().ok())
|
if cx
|
||||||
|
.active_drag
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|drag| drag.value.type_id() == TypeId::of::<T>())
|
||||||
{
|
{
|
||||||
(listener)(
|
(listener)(
|
||||||
&DragMoveEvent {
|
&DragMoveEvent {
|
||||||
event: event.clone(),
|
event: event.clone(),
|
||||||
drag: view,
|
drag: PhantomData,
|
||||||
},
|
},
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
@ -252,14 +265,11 @@ impl Interactivity {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_drop<W: 'static>(
|
pub fn on_drop<T: 'static>(&mut self, listener: impl Fn(&T, &mut WindowContext) + 'static) {
|
||||||
&mut self,
|
|
||||||
listener: impl Fn(&View<W>, &mut WindowContext) + 'static,
|
|
||||||
) {
|
|
||||||
self.drop_listeners.push((
|
self.drop_listeners.push((
|
||||||
TypeId::of::<W>(),
|
TypeId::of::<T>(),
|
||||||
Box::new(move |dragged_view, cx| {
|
Box::new(move |dragged_value, cx| {
|
||||||
listener(&dragged_view.downcast().unwrap(), cx);
|
listener(dragged_value.downcast_ref().unwrap(), cx);
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -272,19 +282,23 @@ impl Interactivity {
|
||||||
.push(Box::new(move |event, cx| listener(event, cx)));
|
.push(Box::new(move |event, cx| listener(event, cx)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_drag<W>(&mut self, constructor: impl Fn(&mut WindowContext) -> View<W> + 'static)
|
pub fn on_drag<T, W>(
|
||||||
where
|
&mut self,
|
||||||
|
value: T,
|
||||||
|
constructor: impl Fn(&T, &mut WindowContext) -> View<W> + 'static,
|
||||||
|
) where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
|
T: 'static,
|
||||||
W: 'static + Render,
|
W: 'static + Render,
|
||||||
{
|
{
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
self.drag_listener.is_none(),
|
self.drag_listener.is_none(),
|
||||||
"calling on_drag more than once on the same element is not supported"
|
"calling on_drag more than once on the same element is not supported"
|
||||||
);
|
);
|
||||||
self.drag_listener = Some(Box::new(move |cursor_offset, cx| AnyDrag {
|
self.drag_listener = Some((
|
||||||
view: constructor(cx).into(),
|
Box::new(value),
|
||||||
cursor_offset,
|
Box::new(move |value, cx| constructor(value.downcast_ref().unwrap(), cx).into()),
|
||||||
}));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_hover(&mut self, listener: impl Fn(&bool, &mut WindowContext) + 'static)
|
pub fn on_hover(&mut self, listener: impl Fn(&bool, &mut WindowContext) + 'static)
|
||||||
|
@ -413,12 +427,12 @@ pub trait InteractiveElement: Sized {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_drag_move<W>(
|
fn on_drag_move<T>(
|
||||||
mut self,
|
mut self,
|
||||||
listener: impl Fn(&DragMoveEvent<W>, &mut WindowContext) + 'static,
|
listener: impl Fn(&DragMoveEvent<T>, &mut WindowContext) + 'static,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
W: Render,
|
T: Render,
|
||||||
{
|
{
|
||||||
self.interactivity().on_drag_move(listener);
|
self.interactivity().on_drag_move(listener);
|
||||||
self
|
self
|
||||||
|
@ -485,14 +499,6 @@ pub trait InteractiveElement: Sized {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_drop<W: 'static>(
|
|
||||||
mut self,
|
|
||||||
listener: impl Fn(&View<W>, &mut WindowContext) + 'static,
|
|
||||||
) -> Self {
|
|
||||||
self.interactivity().on_drop(listener);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn drag_over<S: 'static>(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self {
|
fn drag_over<S: 'static>(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self {
|
||||||
self.interactivity()
|
self.interactivity()
|
||||||
.drag_over_styles
|
.drag_over_styles
|
||||||
|
@ -514,6 +520,11 @@ pub trait InteractiveElement: Sized {
|
||||||
));
|
));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_drop<T: 'static>(mut self, listener: impl Fn(&T, &mut WindowContext) + 'static) -> Self {
|
||||||
|
self.interactivity().on_drop(listener);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait StatefulInteractiveElement: InteractiveElement {
|
pub trait StatefulInteractiveElement: InteractiveElement {
|
||||||
|
@ -574,12 +585,17 @@ pub trait StatefulInteractiveElement: InteractiveElement {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_drag<W>(mut self, constructor: impl Fn(&mut WindowContext) -> View<W> + 'static) -> Self
|
fn on_drag<T, W>(
|
||||||
|
mut self,
|
||||||
|
value: T,
|
||||||
|
constructor: impl Fn(&T, &mut WindowContext) -> View<W> + 'static,
|
||||||
|
) -> Self
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
|
T: 'static,
|
||||||
W: 'static + Render,
|
W: 'static + Render,
|
||||||
{
|
{
|
||||||
self.interactivity().on_drag(constructor);
|
self.interactivity().on_drag(value, constructor);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -635,9 +651,9 @@ pub type ScrollWheelListener =
|
||||||
|
|
||||||
pub type ClickListener = Box<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>;
|
pub type ClickListener = Box<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>;
|
||||||
|
|
||||||
pub type DragListener = Box<dyn Fn(Point<Pixels>, &mut WindowContext) -> AnyDrag + 'static>;
|
pub type DragListener = Box<dyn Fn(&dyn Any, &mut WindowContext) -> AnyView + 'static>;
|
||||||
|
|
||||||
type DropListener = dyn Fn(AnyView, &mut WindowContext) + 'static;
|
type DropListener = Box<dyn Fn(&dyn Any, &mut WindowContext) + 'static>;
|
||||||
|
|
||||||
pub type TooltipBuilder = Rc<dyn Fn(&mut WindowContext) -> AnyView + 'static>;
|
pub type TooltipBuilder = Rc<dyn Fn(&mut WindowContext) -> AnyView + 'static>;
|
||||||
|
|
||||||
|
@ -834,9 +850,9 @@ pub struct Interactivity {
|
||||||
pub key_down_listeners: Vec<KeyDownListener>,
|
pub key_down_listeners: Vec<KeyDownListener>,
|
||||||
pub key_up_listeners: Vec<KeyUpListener>,
|
pub key_up_listeners: Vec<KeyUpListener>,
|
||||||
pub action_listeners: Vec<(TypeId, ActionListener)>,
|
pub action_listeners: Vec<(TypeId, ActionListener)>,
|
||||||
pub drop_listeners: Vec<(TypeId, Box<DropListener>)>,
|
pub drop_listeners: Vec<(TypeId, DropListener)>,
|
||||||
pub click_listeners: Vec<ClickListener>,
|
pub click_listeners: Vec<ClickListener>,
|
||||||
pub drag_listener: Option<DragListener>,
|
pub drag_listener: Option<(Box<dyn Any>, DragListener)>,
|
||||||
pub hover_listener: Option<Box<dyn Fn(&bool, &mut WindowContext)>>,
|
pub hover_listener: Option<Box<dyn Fn(&bool, &mut WindowContext)>>,
|
||||||
pub tooltip_builder: Option<TooltipBuilder>,
|
pub tooltip_builder: Option<TooltipBuilder>,
|
||||||
|
|
||||||
|
@ -1124,8 +1140,10 @@ impl Interactivity {
|
||||||
if phase == DispatchPhase::Bubble
|
if phase == DispatchPhase::Bubble
|
||||||
&& interactive_bounds.drag_target_contains(&event.position, cx)
|
&& interactive_bounds.drag_target_contains(&event.position, cx)
|
||||||
{
|
{
|
||||||
if let Some(drag_state_type) =
|
if let Some(drag_state_type) = cx
|
||||||
cx.active_drag.as_ref().map(|drag| drag.view.entity_type())
|
.active_drag
|
||||||
|
.as_ref()
|
||||||
|
.map(|drag| drag.value.as_ref().type_id())
|
||||||
{
|
{
|
||||||
for (drop_state_type, listener) in &drop_listeners {
|
for (drop_state_type, listener) in &drop_listeners {
|
||||||
if *drop_state_type == drag_state_type {
|
if *drop_state_type == drag_state_type {
|
||||||
|
@ -1134,7 +1152,7 @@ impl Interactivity {
|
||||||
.take()
|
.take()
|
||||||
.expect("checked for type drag state type above");
|
.expect("checked for type drag state type above");
|
||||||
|
|
||||||
listener(drag.view.clone(), cx);
|
listener(drag.value.as_ref(), cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
cx.stop_propagation();
|
cx.stop_propagation();
|
||||||
}
|
}
|
||||||
|
@ -1148,7 +1166,7 @@ impl Interactivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
let click_listeners = mem::take(&mut self.click_listeners);
|
let click_listeners = mem::take(&mut self.click_listeners);
|
||||||
let drag_listener = mem::take(&mut self.drag_listener);
|
let mut drag_listener = mem::take(&mut self.drag_listener);
|
||||||
|
|
||||||
if !click_listeners.is_empty() || drag_listener.is_some() {
|
if !click_listeners.is_empty() || drag_listener.is_some() {
|
||||||
let pending_mouse_down = element_state
|
let pending_mouse_down = element_state
|
||||||
|
@ -1157,7 +1175,7 @@ impl Interactivity {
|
||||||
.clone();
|
.clone();
|
||||||
let mouse_down = pending_mouse_down.borrow().clone();
|
let mouse_down = pending_mouse_down.borrow().clone();
|
||||||
if let Some(mouse_down) = mouse_down {
|
if let Some(mouse_down) = mouse_down {
|
||||||
if let Some(drag_listener) = drag_listener {
|
if drag_listener.is_some() {
|
||||||
let active_state = element_state
|
let active_state = element_state
|
||||||
.clicked_state
|
.clicked_state
|
||||||
.get_or_insert_with(Default::default)
|
.get_or_insert_with(Default::default)
|
||||||
|
@ -1173,10 +1191,18 @@ impl Interactivity {
|
||||||
&& interactive_bounds.visibly_contains(&event.position, cx)
|
&& interactive_bounds.visibly_contains(&event.position, cx)
|
||||||
&& (event.position - mouse_down.position).magnitude() > DRAG_THRESHOLD
|
&& (event.position - mouse_down.position).magnitude() > DRAG_THRESHOLD
|
||||||
{
|
{
|
||||||
|
let (drag_value, drag_listener) = drag_listener
|
||||||
|
.take()
|
||||||
|
.expect("The notify below should invalidate this callback");
|
||||||
|
|
||||||
*active_state.borrow_mut() = ElementClickedState::default();
|
*active_state.borrow_mut() = ElementClickedState::default();
|
||||||
let cursor_offset = event.position - bounds.origin;
|
let cursor_offset = event.position - bounds.origin;
|
||||||
let drag = drag_listener(cursor_offset, cx);
|
let drag = (drag_listener)(drag_value.as_ref(), cx);
|
||||||
cx.active_drag = Some(drag);
|
cx.active_drag = Some(AnyDrag {
|
||||||
|
view: drag,
|
||||||
|
value: drag_value,
|
||||||
|
cursor_offset,
|
||||||
|
});
|
||||||
cx.notify();
|
cx.notify();
|
||||||
cx.stop_propagation();
|
cx.stop_propagation();
|
||||||
}
|
}
|
||||||
|
@ -1470,7 +1496,7 @@ impl Interactivity {
|
||||||
if let Some(drag) = cx.active_drag.take() {
|
if let Some(drag) = cx.active_drag.take() {
|
||||||
for (state_type, group_drag_style) in &self.group_drag_over_styles {
|
for (state_type, group_drag_style) in &self.group_drag_over_styles {
|
||||||
if let Some(group_bounds) = GroupBounds::get(&group_drag_style.group, cx) {
|
if let Some(group_bounds) = GroupBounds::get(&group_drag_style.group, cx) {
|
||||||
if *state_type == drag.view.entity_type()
|
if *state_type == drag.value.as_ref().type_id()
|
||||||
&& group_bounds.contains(&mouse_position)
|
&& group_bounds.contains(&mouse_position)
|
||||||
{
|
{
|
||||||
style.refine(&group_drag_style.style);
|
style.refine(&group_drag_style.style);
|
||||||
|
@ -1479,7 +1505,7 @@ impl Interactivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (state_type, drag_over_style) in &self.drag_over_styles {
|
for (state_type, drag_over_style) in &self.drag_over_styles {
|
||||||
if *state_type == drag.view.entity_type()
|
if *state_type == drag.value.as_ref().type_id()
|
||||||
&& bounds
|
&& bounds
|
||||||
.intersect(&cx.content_mask().bounds)
|
.intersect(&cx.content_mask().bounds)
|
||||||
.contains(&mouse_position)
|
.contains(&mouse_position)
|
||||||
|
|
|
@ -7,6 +7,7 @@ use crate::{
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use std::{
|
use std::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
|
fmt,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -308,6 +309,20 @@ impl<V: 'static + Render> From<WeakView<V>> for AnyWeakView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for AnyWeakView {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.model == other.model
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for AnyWeakView {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.debug_struct("AnyWeakView")
|
||||||
|
.field("entity_id", &self.model.entity_id)
|
||||||
|
.finish_non_exhaustive()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, E> Render for T
|
impl<T, E> Render for T
|
||||||
where
|
where
|
||||||
T: 'static + FnMut(&mut WindowContext) -> E,
|
T: 'static + FnMut(&mut WindowContext) -> E,
|
||||||
|
|
|
@ -822,7 +822,7 @@ impl<'a> WindowContext<'a> {
|
||||||
/// a specific need to register a global listener.
|
/// a specific need to register a global listener.
|
||||||
pub fn on_mouse_event<Event: 'static>(
|
pub fn on_mouse_event<Event: 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static,
|
mut handler: impl FnMut(&Event, DispatchPhase, &mut WindowContext) + 'static,
|
||||||
) {
|
) {
|
||||||
let order = self.window.next_frame.z_index_stack.clone();
|
let order = self.window.next_frame.z_index_stack.clone();
|
||||||
self.window
|
self.window
|
||||||
|
@ -1400,6 +1400,7 @@ impl<'a> WindowContext<'a> {
|
||||||
self.window.mouse_position = position;
|
self.window.mouse_position = position;
|
||||||
if self.active_drag.is_none() {
|
if self.active_drag.is_none() {
|
||||||
self.active_drag = Some(AnyDrag {
|
self.active_drag = Some(AnyDrag {
|
||||||
|
value: Box::new(files.clone()),
|
||||||
view: self.build_view(|_| files).into(),
|
view: self.build_view(|_| files).into(),
|
||||||
cursor_offset: position,
|
cursor_offset: position,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1377,33 +1377,28 @@ impl ProjectPanel {
|
||||||
})
|
})
|
||||||
.unwrap_or(theme.status().info);
|
.unwrap_or(theme.status().info);
|
||||||
|
|
||||||
|
let file_name = details.filename.clone();
|
||||||
|
let icon = details.icon.clone();
|
||||||
|
let depth = details.depth;
|
||||||
div()
|
div()
|
||||||
.id(entry_id.to_proto() as usize)
|
.id(entry_id.to_proto() as usize)
|
||||||
.on_drag({
|
.on_drag(entry_id, move |entry_id, cx| {
|
||||||
let details = details.clone();
|
cx.build_view(|_| DraggedProjectEntryView {
|
||||||
move |cx| {
|
details: details.clone(),
|
||||||
let details = details.clone();
|
width,
|
||||||
cx.build_view(|_| DraggedProjectEntryView {
|
entry_id: *entry_id,
|
||||||
details,
|
})
|
||||||
width,
|
|
||||||
entry_id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.drag_over::<DraggedProjectEntryView>(|style| {
|
.drag_over::<ProjectEntryId>(|style| style.bg(cx.theme().colors().ghost_element_hover))
|
||||||
style.bg(cx.theme().colors().ghost_element_hover)
|
.on_drop(cx.listener(move |this, dragged_id: &ProjectEntryId, cx| {
|
||||||
})
|
this.move_entry(*dragged_id, entry_id, kind.is_file(), cx);
|
||||||
.on_drop(cx.listener(
|
}))
|
||||||
move |this, dragged_view: &View<DraggedProjectEntryView>, cx| {
|
|
||||||
this.move_entry(dragged_view.read(cx).entry_id, entry_id, kind.is_file(), cx);
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.child(
|
.child(
|
||||||
ListItem::new(entry_id.to_proto() as usize)
|
ListItem::new(entry_id.to_proto() as usize)
|
||||||
.indent_level(details.depth)
|
.indent_level(depth)
|
||||||
.indent_step_size(px(settings.indent_size))
|
.indent_step_size(px(settings.indent_size))
|
||||||
.selected(is_selected)
|
.selected(is_selected)
|
||||||
.child(if let Some(icon) = &details.icon {
|
.child(if let Some(icon) = &icon {
|
||||||
div().child(IconElement::from_path(icon.to_string()))
|
div().child(IconElement::from_path(icon.to_string()))
|
||||||
} else {
|
} else {
|
||||||
div()
|
div()
|
||||||
|
@ -1414,7 +1409,7 @@ impl ProjectPanel {
|
||||||
} else {
|
} else {
|
||||||
div()
|
div()
|
||||||
.text_color(filename_text_color)
|
.text_color(filename_text_color)
|
||||||
.child(Label::new(details.filename.clone()))
|
.child(Label::new(file_name))
|
||||||
}
|
}
|
||||||
.ml_1(),
|
.ml_1(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1590,12 +1590,16 @@ impl Render for ProjectSearchBar {
|
||||||
);
|
);
|
||||||
let replace_column = if search.replace_enabled {
|
let replace_column = if search.replace_enabled {
|
||||||
h_stack()
|
h_stack()
|
||||||
.p_1()
|
|
||||||
.flex_1()
|
.flex_1()
|
||||||
.border_2()
|
.h_full()
|
||||||
|
.gap_2()
|
||||||
|
.px_2()
|
||||||
|
.py_1()
|
||||||
|
.border_1()
|
||||||
|
.border_color(cx.theme().colors().border)
|
||||||
.rounded_lg()
|
.rounded_lg()
|
||||||
.child(IconElement::new(Icon::Replace).size(ui::IconSize::Small))
|
.child(IconElement::new(Icon::Replace).size(ui::IconSize::Small))
|
||||||
.child(search.replacement_editor.clone())
|
.child(self.render_text_input(&search.replacement_editor, cx))
|
||||||
} else {
|
} else {
|
||||||
// Fill out the space if we don't have a replacement editor.
|
// Fill out the space if we don't have a replacement editor.
|
||||||
h_stack().flex_1()
|
h_stack().flex_1()
|
||||||
|
@ -1658,10 +1662,10 @@ impl Render for ProjectSearchBar {
|
||||||
]);
|
]);
|
||||||
v_stack()
|
v_stack()
|
||||||
.key_context(key_context)
|
.key_context(key_context)
|
||||||
|
.flex_grow()
|
||||||
.p_1()
|
.p_1()
|
||||||
.m_2()
|
.m_2()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.justify_between()
|
|
||||||
.on_action(cx.listener(|this, _: &ToggleFilters, cx| {
|
.on_action(cx.listener(|this, _: &ToggleFilters, cx| {
|
||||||
this.toggle_filters(cx);
|
this.toggle_filters(cx);
|
||||||
}))
|
}))
|
||||||
|
@ -1713,10 +1717,59 @@ impl Render for ProjectSearchBar {
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.child(query_column)
|
.child(
|
||||||
.child(mode_column)
|
h_stack()
|
||||||
.child(replace_column)
|
.justify_between()
|
||||||
.child(actions_column)
|
.child(query_column)
|
||||||
|
.child(mode_column)
|
||||||
|
.child(replace_column)
|
||||||
|
.child(actions_column),
|
||||||
|
)
|
||||||
|
.when(search.filters_enabled, |this| {
|
||||||
|
this.child(
|
||||||
|
h_stack()
|
||||||
|
.flex_1()
|
||||||
|
.gap_2()
|
||||||
|
.justify_between()
|
||||||
|
.child(
|
||||||
|
h_stack()
|
||||||
|
.flex_1()
|
||||||
|
.h_full()
|
||||||
|
.px_2()
|
||||||
|
.py_1()
|
||||||
|
.border_1()
|
||||||
|
.border_color(cx.theme().colors().border)
|
||||||
|
.rounded_lg()
|
||||||
|
.child(self.render_text_input(&search.included_files_editor, cx))
|
||||||
|
.when(search.current_mode != SearchMode::Semantic, |this| {
|
||||||
|
this.child(
|
||||||
|
SearchOptions::INCLUDE_IGNORED.as_button(
|
||||||
|
search
|
||||||
|
.search_options
|
||||||
|
.contains(SearchOptions::INCLUDE_IGNORED),
|
||||||
|
cx.listener(|this, _, cx| {
|
||||||
|
this.toggle_search_option(
|
||||||
|
SearchOptions::INCLUDE_IGNORED,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
h_stack()
|
||||||
|
.flex_1()
|
||||||
|
.h_full()
|
||||||
|
.px_2()
|
||||||
|
.py_1()
|
||||||
|
.border_1()
|
||||||
|
.border_color(cx.theme().colors().border)
|
||||||
|
.rounded_lg()
|
||||||
|
.child(self.render_text_input(&search.excluded_files_editor, cx)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// impl Entity for ProjectSearchBar {
|
// impl Entity for ProjectSearchBar {
|
||||||
|
|
|
@ -695,7 +695,6 @@ impl TerminalElement {
|
||||||
move |external_paths, cx| {
|
move |external_paths, cx| {
|
||||||
cx.focus(&focus);
|
cx.focus(&focus);
|
||||||
let mut new_text = external_paths
|
let mut new_text = external_paths
|
||||||
.read(cx)
|
|
||||||
.paths()
|
.paths()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|path| format!(" {path:?}"))
|
.map(|path| format!(" {path:?}"))
|
||||||
|
|
|
@ -47,6 +47,7 @@ pub fn andromeda() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x3a3f4c77).into()),
|
scrollbar_thumb_border: Some(rgba(0x3a3f4c77).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x23262eff).into()),
|
scrollbar_track_background: Some(rgba(0x23262eff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x1b1d23ff).into()),
|
scrollbar_track_border: Some(rgba(0x1b1d23ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xd5ced9ff).into()),
|
||||||
editor_background: Some(rgba(0x23262eff).into()),
|
editor_background: Some(rgba(0x23262eff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x23262eff).into()),
|
editor_gutter_background: Some(rgba(0x23262eff).into()),
|
||||||
editor_line_number: Some(rgba(0x746f77ff).into()),
|
editor_line_number: Some(rgba(0x746f77ff).into()),
|
||||||
|
@ -261,6 +262,7 @@ pub fn andromeda() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x3a3f4c77).into()),
|
scrollbar_thumb_border: Some(rgba(0x3a3f4c77).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x262a33ff).into()),
|
scrollbar_track_background: Some(rgba(0x262a33ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x1b1d23ff).into()),
|
scrollbar_track_border: Some(rgba(0x1b1d23ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xd5ced9ff).into()),
|
||||||
editor_background: Some(rgba(0x262a33ff).into()),
|
editor_background: Some(rgba(0x262a33ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x262a33ff).into()),
|
editor_gutter_background: Some(rgba(0x262a33ff).into()),
|
||||||
editor_line_number: Some(rgba(0x746f77ff).into()),
|
editor_line_number: Some(rgba(0x746f77ff).into()),
|
||||||
|
|
|
@ -46,6 +46,7 @@ pub fn ayu() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x8a919966).into()),
|
scrollbar_thumb_border: Some(rgba(0x8a919966).into()),
|
||||||
scrollbar_track_background: Some(rgba(0xf8f9faff).into()),
|
scrollbar_track_background: Some(rgba(0xf8f9faff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x6b7d8f1f).into()),
|
scrollbar_track_border: Some(rgba(0x6b7d8f1f).into()),
|
||||||
|
editor_foreground: Some(rgba(0x5c6166ff).into()),
|
||||||
editor_background: Some(rgba(0xf8f9faff).into()),
|
editor_background: Some(rgba(0xf8f9faff).into()),
|
||||||
editor_gutter_background: Some(rgba(0xf8f9faff).into()),
|
editor_gutter_background: Some(rgba(0xf8f9faff).into()),
|
||||||
editor_line_number: Some(rgba(0x8a919966).into()),
|
editor_line_number: Some(rgba(0x8a919966).into()),
|
||||||
|
@ -352,6 +353,7 @@ pub fn ayu() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x707a8c66).into()),
|
scrollbar_thumb_border: Some(rgba(0x707a8c66).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x1f2430ff).into()),
|
scrollbar_track_background: Some(rgba(0x1f2430ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x171b24ff).into()),
|
scrollbar_track_border: Some(rgba(0x171b24ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xcccac2ff).into()),
|
||||||
editor_background: Some(rgba(0x1f2430ff).into()),
|
editor_background: Some(rgba(0x1f2430ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x1f2430ff).into()),
|
editor_gutter_background: Some(rgba(0x1f2430ff).into()),
|
||||||
editor_line_number: Some(rgba(0x8a919966).into()),
|
editor_line_number: Some(rgba(0x8a919966).into()),
|
||||||
|
@ -658,6 +660,7 @@ pub fn ayu() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x565b6666).into()),
|
scrollbar_thumb_border: Some(rgba(0x565b6666).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x0b0e14ff).into()),
|
scrollbar_track_background: Some(rgba(0x0b0e14ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x1e232bff).into()),
|
scrollbar_track_border: Some(rgba(0x1e232bff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xbfbdb6ff).into()),
|
||||||
editor_background: Some(rgba(0x0b0e14ff).into()),
|
editor_background: Some(rgba(0x0b0e14ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x0b0e14ff).into()),
|
editor_gutter_background: Some(rgba(0x0b0e14ff).into()),
|
||||||
editor_line_number: Some(rgba(0x6c738099).into()),
|
editor_line_number: Some(rgba(0x6c738099).into()),
|
||||||
|
|
|
@ -43,6 +43,7 @@ pub fn dracula() -> UserThemeFamily {
|
||||||
tab_active_background: Some(rgba(0x282a36ff).into()),
|
tab_active_background: Some(rgba(0x282a36ff).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x282a36ff).into()),
|
scrollbar_track_background: Some(rgba(0x282a36ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x191a21ff).into()),
|
scrollbar_track_border: Some(rgba(0x191a21ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xf8f8f2ff).into()),
|
||||||
editor_background: Some(rgba(0x282a36ff).into()),
|
editor_background: Some(rgba(0x282a36ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x282a36ff).into()),
|
editor_gutter_background: Some(rgba(0x282a36ff).into()),
|
||||||
editor_line_number: Some(rgba(0x6272a4ff).into()),
|
editor_line_number: Some(rgba(0x6272a4ff).into()),
|
||||||
|
|
|
@ -46,6 +46,7 @@ pub fn gruvbox() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x50494599).into()),
|
scrollbar_thumb_border: Some(rgba(0x50494599).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x1d2021ff).into()),
|
scrollbar_track_background: Some(rgba(0x1d2021ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x1d202100).into()),
|
scrollbar_track_border: Some(rgba(0x1d202100).into()),
|
||||||
|
editor_foreground: Some(rgba(0xebdbb2ff).into()),
|
||||||
editor_background: Some(rgba(0x1d2021ff).into()),
|
editor_background: Some(rgba(0x1d2021ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x1d2021ff).into()),
|
editor_gutter_background: Some(rgba(0x1d2021ff).into()),
|
||||||
editor_line_number: Some(rgba(0x665c54ff).into()),
|
editor_line_number: Some(rgba(0x665c54ff).into()),
|
||||||
|
@ -338,6 +339,7 @@ pub fn gruvbox() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x50494599).into()),
|
scrollbar_thumb_border: Some(rgba(0x50494599).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x282828ff).into()),
|
scrollbar_track_background: Some(rgba(0x282828ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x28282800).into()),
|
scrollbar_track_border: Some(rgba(0x28282800).into()),
|
||||||
|
editor_foreground: Some(rgba(0xebdbb2ff).into()),
|
||||||
editor_background: Some(rgba(0x282828ff).into()),
|
editor_background: Some(rgba(0x282828ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x282828ff).into()),
|
editor_gutter_background: Some(rgba(0x282828ff).into()),
|
||||||
editor_line_number: Some(rgba(0x665c54ff).into()),
|
editor_line_number: Some(rgba(0x665c54ff).into()),
|
||||||
|
@ -630,6 +632,7 @@ pub fn gruvbox() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x50494599).into()),
|
scrollbar_thumb_border: Some(rgba(0x50494599).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x32302fff).into()),
|
scrollbar_track_background: Some(rgba(0x32302fff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x32302f00).into()),
|
scrollbar_track_border: Some(rgba(0x32302f00).into()),
|
||||||
|
editor_foreground: Some(rgba(0xebdbb2ff).into()),
|
||||||
editor_background: Some(rgba(0x32302fff).into()),
|
editor_background: Some(rgba(0x32302fff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x32302fff).into()),
|
editor_gutter_background: Some(rgba(0x32302fff).into()),
|
||||||
editor_line_number: Some(rgba(0x665c54ff).into()),
|
editor_line_number: Some(rgba(0x665c54ff).into()),
|
||||||
|
@ -922,6 +925,7 @@ pub fn gruvbox() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0xd5c4a199).into()),
|
scrollbar_thumb_border: Some(rgba(0xd5c4a199).into()),
|
||||||
scrollbar_track_background: Some(rgba(0xf9f5d7ff).into()),
|
scrollbar_track_background: Some(rgba(0xf9f5d7ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0xf9f5d700).into()),
|
scrollbar_track_border: Some(rgba(0xf9f5d700).into()),
|
||||||
|
editor_foreground: Some(rgba(0x3c3836ff).into()),
|
||||||
editor_background: Some(rgba(0xf9f5d7ff).into()),
|
editor_background: Some(rgba(0xf9f5d7ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0xf9f5d7ff).into()),
|
editor_gutter_background: Some(rgba(0xf9f5d7ff).into()),
|
||||||
editor_line_number: Some(rgba(0xbdae93ff).into()),
|
editor_line_number: Some(rgba(0xbdae93ff).into()),
|
||||||
|
@ -1214,6 +1218,7 @@ pub fn gruvbox() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0xd5c4a199).into()),
|
scrollbar_thumb_border: Some(rgba(0xd5c4a199).into()),
|
||||||
scrollbar_track_background: Some(rgba(0xfbf1c7ff).into()),
|
scrollbar_track_background: Some(rgba(0xfbf1c7ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0xfbf1c700).into()),
|
scrollbar_track_border: Some(rgba(0xfbf1c700).into()),
|
||||||
|
editor_foreground: Some(rgba(0x3c3836ff).into()),
|
||||||
editor_background: Some(rgba(0xfbf1c7ff).into()),
|
editor_background: Some(rgba(0xfbf1c7ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0xfbf1c7ff).into()),
|
editor_gutter_background: Some(rgba(0xfbf1c7ff).into()),
|
||||||
editor_line_number: Some(rgba(0xbdae93ff).into()),
|
editor_line_number: Some(rgba(0xbdae93ff).into()),
|
||||||
|
@ -1506,6 +1511,7 @@ pub fn gruvbox() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0xd5c4a199).into()),
|
scrollbar_thumb_border: Some(rgba(0xd5c4a199).into()),
|
||||||
scrollbar_track_background: Some(rgba(0xf2e5bcff).into()),
|
scrollbar_track_background: Some(rgba(0xf2e5bcff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0xf2e5bc00).into()),
|
scrollbar_track_border: Some(rgba(0xf2e5bc00).into()),
|
||||||
|
editor_foreground: Some(rgba(0x3c3836ff).into()),
|
||||||
editor_background: Some(rgba(0xf2e5bcff).into()),
|
editor_background: Some(rgba(0xf2e5bcff).into()),
|
||||||
editor_gutter_background: Some(rgba(0xf2e5bcff).into()),
|
editor_gutter_background: Some(rgba(0xf2e5bcff).into()),
|
||||||
editor_line_number: Some(rgba(0xbdae93ff).into()),
|
editor_line_number: Some(rgba(0xbdae93ff).into()),
|
||||||
|
|
|
@ -46,6 +46,7 @@ pub fn night_owl() -> UserThemeFamily {
|
||||||
scrollbar_thumb_hover_background: Some(rgba(0x084d8180).into()),
|
scrollbar_thumb_hover_background: Some(rgba(0x084d8180).into()),
|
||||||
scrollbar_thumb_border: Some(rgba(0x084d8180).into()),
|
scrollbar_thumb_border: Some(rgba(0x084d8180).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x011627ff).into()),
|
scrollbar_track_background: Some(rgba(0x011627ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xd6deebff).into()),
|
||||||
editor_background: Some(rgba(0x011627ff).into()),
|
editor_background: Some(rgba(0x011627ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x011627ff).into()),
|
editor_gutter_background: Some(rgba(0x011627ff).into()),
|
||||||
editor_line_number: Some(rgba(0x4b6479ff).into()),
|
editor_line_number: Some(rgba(0x4b6479ff).into()),
|
||||||
|
@ -305,6 +306,7 @@ pub fn night_owl() -> UserThemeFamily {
|
||||||
tab_inactive_background: Some(rgba(0xf0f0f0ff).into()),
|
tab_inactive_background: Some(rgba(0xf0f0f0ff).into()),
|
||||||
tab_active_background: Some(rgba(0xf6f6f6ff).into()),
|
tab_active_background: Some(rgba(0xf6f6f6ff).into()),
|
||||||
scrollbar_track_background: Some(rgba(0xfbfbfbff).into()),
|
scrollbar_track_background: Some(rgba(0xfbfbfbff).into()),
|
||||||
|
editor_foreground: Some(rgba(0x403f53ff).into()),
|
||||||
editor_background: Some(rgba(0xfbfbfbff).into()),
|
editor_background: Some(rgba(0xfbfbfbff).into()),
|
||||||
editor_gutter_background: Some(rgba(0xfbfbfbff).into()),
|
editor_gutter_background: Some(rgba(0xfbfbfbff).into()),
|
||||||
editor_line_number: Some(rgba(0x90a7b2ff).into()),
|
editor_line_number: Some(rgba(0x90a7b2ff).into()),
|
||||||
|
|
|
@ -47,6 +47,7 @@ pub fn noctis() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x008ee633).into()),
|
scrollbar_thumb_border: Some(rgba(0x008ee633).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x07273bff).into()),
|
scrollbar_track_background: Some(rgba(0x07273bff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x07273bff).into()),
|
scrollbar_track_border: Some(rgba(0x07273bff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xbecfdaff).into()),
|
||||||
editor_background: Some(rgba(0x07273bff).into()),
|
editor_background: Some(rgba(0x07273bff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x07273bff).into()),
|
editor_gutter_background: Some(rgba(0x07273bff).into()),
|
||||||
editor_line_number: Some(rgba(0x4d6c80ff).into()),
|
editor_line_number: Some(rgba(0x4d6c80ff).into()),
|
||||||
|
@ -324,6 +325,7 @@ pub fn noctis() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0xeb609133).into()),
|
scrollbar_thumb_border: Some(rgba(0xeb609133).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x322a2dff).into()),
|
scrollbar_track_background: Some(rgba(0x322a2dff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x322a2dff).into()),
|
scrollbar_track_border: Some(rgba(0x322a2dff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xcbbec2ff).into()),
|
||||||
editor_background: Some(rgba(0x322a2dff).into()),
|
editor_background: Some(rgba(0x322a2dff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x322a2dff).into()),
|
editor_gutter_background: Some(rgba(0x322a2dff).into()),
|
||||||
editor_line_number: Some(rgba(0x715b63ff).into()),
|
editor_line_number: Some(rgba(0x715b63ff).into()),
|
||||||
|
@ -601,6 +603,7 @@ pub fn noctis() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x6a90955b).into()),
|
scrollbar_thumb_border: Some(rgba(0x6a90955b).into()),
|
||||||
scrollbar_track_background: Some(rgba(0xf4f6f6ff).into()),
|
scrollbar_track_background: Some(rgba(0xf4f6f6ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0xf4f6f6ff).into()),
|
scrollbar_track_border: Some(rgba(0xf4f6f6ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0x005661ff).into()),
|
||||||
editor_background: Some(rgba(0xf4f6f6ff).into()),
|
editor_background: Some(rgba(0xf4f6f6ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0xf4f6f6ff).into()),
|
editor_gutter_background: Some(rgba(0xf4f6f6ff).into()),
|
||||||
editor_line_number: Some(rgba(0xa0abacff).into()),
|
editor_line_number: Some(rgba(0xa0abacff).into()),
|
||||||
|
@ -878,6 +881,7 @@ pub fn noctis() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x6a90955b).into()),
|
scrollbar_thumb_border: Some(rgba(0x6a90955b).into()),
|
||||||
scrollbar_track_background: Some(rgba(0xf2f1f8ff).into()),
|
scrollbar_track_background: Some(rgba(0xf2f1f8ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0xf2f1f8ff).into()),
|
scrollbar_track_border: Some(rgba(0xf2f1f8ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0x0c006bff).into()),
|
||||||
editor_background: Some(rgba(0xf2f1f8ff).into()),
|
editor_background: Some(rgba(0xf2f1f8ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0xf2f1f8ff).into()),
|
editor_gutter_background: Some(rgba(0xf2f1f8ff).into()),
|
||||||
editor_line_number: Some(rgba(0x9d9ab1ff).into()),
|
editor_line_number: Some(rgba(0x9d9ab1ff).into()),
|
||||||
|
@ -1155,6 +1159,7 @@ pub fn noctis() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x6a90955b).into()),
|
scrollbar_thumb_border: Some(rgba(0x6a90955b).into()),
|
||||||
scrollbar_track_background: Some(rgba(0xfef8ecff).into()),
|
scrollbar_track_background: Some(rgba(0xfef8ecff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0xfef8ecff).into()),
|
scrollbar_track_border: Some(rgba(0xfef8ecff).into()),
|
||||||
|
editor_foreground: Some(rgba(0x005661ff).into()),
|
||||||
editor_background: Some(rgba(0xfef8ecff).into()),
|
editor_background: Some(rgba(0xfef8ecff).into()),
|
||||||
editor_gutter_background: Some(rgba(0xfef8ecff).into()),
|
editor_gutter_background: Some(rgba(0xfef8ecff).into()),
|
||||||
editor_line_number: Some(rgba(0xa0abacff).into()),
|
editor_line_number: Some(rgba(0xa0abacff).into()),
|
||||||
|
@ -1432,6 +1437,7 @@ pub fn noctis() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x3f7fa633).into()),
|
scrollbar_thumb_border: Some(rgba(0x3f7fa633).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x1b2932ff).into()),
|
scrollbar_track_background: Some(rgba(0x1b2932ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x1b2932ff).into()),
|
scrollbar_track_border: Some(rgba(0x1b2932ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xc5cdd3ff).into()),
|
||||||
editor_background: Some(rgba(0x1b2932ff).into()),
|
editor_background: Some(rgba(0x1b2932ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x1b2932ff).into()),
|
editor_gutter_background: Some(rgba(0x1b2932ff).into()),
|
||||||
editor_line_number: Some(rgba(0x5d6e79ff).into()),
|
editor_line_number: Some(rgba(0x5d6e79ff).into()),
|
||||||
|
@ -1709,6 +1715,7 @@ pub fn noctis() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x6a90955b).into()),
|
scrollbar_thumb_border: Some(rgba(0x6a90955b).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x052529ff).into()),
|
scrollbar_track_background: Some(rgba(0x052529ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x052529ff).into()),
|
scrollbar_track_border: Some(rgba(0x052529ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xb2cacdff).into()),
|
||||||
editor_background: Some(rgba(0x052529ff).into()),
|
editor_background: Some(rgba(0x052529ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x052529ff).into()),
|
editor_gutter_background: Some(rgba(0x052529ff).into()),
|
||||||
editor_line_number: Some(rgba(0x4e6b6eff).into()),
|
editor_line_number: Some(rgba(0x4e6b6eff).into()),
|
||||||
|
@ -1986,6 +1993,7 @@ pub fn noctis() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x6a90955b).into()),
|
scrollbar_thumb_border: Some(rgba(0x6a90955b).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x031417ff).into()),
|
scrollbar_track_background: Some(rgba(0x031417ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x031417ff).into()),
|
scrollbar_track_border: Some(rgba(0x031417ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xb2cacdff).into()),
|
||||||
editor_background: Some(rgba(0x031417ff).into()),
|
editor_background: Some(rgba(0x031417ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x031417ff).into()),
|
editor_gutter_background: Some(rgba(0x031417ff).into()),
|
||||||
editor_line_number: Some(rgba(0x4e6b6eff).into()),
|
editor_line_number: Some(rgba(0x4e6b6eff).into()),
|
||||||
|
@ -2263,6 +2271,7 @@ pub fn noctis() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x6a90955b).into()),
|
scrollbar_thumb_border: Some(rgba(0x6a90955b).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x031417ff).into()),
|
scrollbar_track_background: Some(rgba(0x031417ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x031417ff).into()),
|
scrollbar_track_border: Some(rgba(0x031417ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xb2cacdff).into()),
|
||||||
editor_background: Some(rgba(0x031417ff).into()),
|
editor_background: Some(rgba(0x031417ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x031417ff).into()),
|
editor_gutter_background: Some(rgba(0x031417ff).into()),
|
||||||
editor_line_number: Some(rgba(0x4e6b6eff).into()),
|
editor_line_number: Some(rgba(0x4e6b6eff).into()),
|
||||||
|
@ -2540,6 +2549,7 @@ pub fn noctis() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x7060eb33).into()),
|
scrollbar_thumb_border: Some(rgba(0x7060eb33).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x292640ff).into()),
|
scrollbar_track_background: Some(rgba(0x292640ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x292640ff).into()),
|
scrollbar_track_border: Some(rgba(0x292640ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xc5c2d6ff).into()),
|
||||||
editor_background: Some(rgba(0x292640ff).into()),
|
editor_background: Some(rgba(0x292640ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x292640ff).into()),
|
editor_gutter_background: Some(rgba(0x292640ff).into()),
|
||||||
editor_line_number: Some(rgba(0x5c5973ff).into()),
|
editor_line_number: Some(rgba(0x5c5973ff).into()),
|
||||||
|
@ -2817,6 +2827,7 @@ pub fn noctis() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0xa660eb33).into()),
|
scrollbar_thumb_border: Some(rgba(0xa660eb33).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x30243dff).into()),
|
scrollbar_track_background: Some(rgba(0x30243dff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x30243dff).into()),
|
scrollbar_track_border: Some(rgba(0x30243dff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xccbfd9ff).into()),
|
||||||
editor_background: Some(rgba(0x30243dff).into()),
|
editor_background: Some(rgba(0x30243dff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x30243dff).into()),
|
editor_gutter_background: Some(rgba(0x30243dff).into()),
|
||||||
editor_line_number: Some(rgba(0x665973ff).into()),
|
editor_line_number: Some(rgba(0x665973ff).into()),
|
||||||
|
|
|
@ -46,6 +46,7 @@ pub fn nord() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x434c5e99).into()),
|
scrollbar_thumb_border: Some(rgba(0x434c5e99).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x2e3440ff).into()),
|
scrollbar_track_background: Some(rgba(0x2e3440ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x3b4252ff).into()),
|
scrollbar_track_border: Some(rgba(0x3b4252ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xd8dee9ff).into()),
|
||||||
editor_background: Some(rgba(0x2e3440ff).into()),
|
editor_background: Some(rgba(0x2e3440ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x2e3440ff).into()),
|
editor_gutter_background: Some(rgba(0x2e3440ff).into()),
|
||||||
editor_line_number: Some(rgba(0x4c566aff).into()),
|
editor_line_number: Some(rgba(0x4c566aff).into()),
|
||||||
|
|
|
@ -46,6 +46,7 @@ pub fn palenight() -> UserThemeFamily {
|
||||||
scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()),
|
scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()),
|
||||||
scrollbar_thumb_border: Some(rgba(0x694ca466).into()),
|
scrollbar_thumb_border: Some(rgba(0x694ca466).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x292d3eff).into()),
|
scrollbar_track_background: Some(rgba(0x292d3eff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xbfc7d5ff).into()),
|
||||||
editor_background: Some(rgba(0x292d3eff).into()),
|
editor_background: Some(rgba(0x292d3eff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x292d3eff).into()),
|
editor_gutter_background: Some(rgba(0x292d3eff).into()),
|
||||||
editor_line_number: Some(rgba(0x4c5374ff).into()),
|
editor_line_number: Some(rgba(0x4c5374ff).into()),
|
||||||
|
@ -331,6 +332,7 @@ pub fn palenight() -> UserThemeFamily {
|
||||||
scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()),
|
scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()),
|
||||||
scrollbar_thumb_border: Some(rgba(0x694ca466).into()),
|
scrollbar_thumb_border: Some(rgba(0x694ca466).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x292d3eff).into()),
|
scrollbar_track_background: Some(rgba(0x292d3eff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xbfc7d5ff).into()),
|
||||||
editor_background: Some(rgba(0x292d3eff).into()),
|
editor_background: Some(rgba(0x292d3eff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x292d3eff).into()),
|
editor_gutter_background: Some(rgba(0x292d3eff).into()),
|
||||||
editor_line_number: Some(rgba(0x4c5374ff).into()),
|
editor_line_number: Some(rgba(0x4c5374ff).into()),
|
||||||
|
@ -616,6 +618,7 @@ pub fn palenight() -> UserThemeFamily {
|
||||||
scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()),
|
scrollbar_thumb_hover_background: Some(rgba(0x694ca4cc).into()),
|
||||||
scrollbar_thumb_border: Some(rgba(0x694ca466).into()),
|
scrollbar_thumb_border: Some(rgba(0x694ca466).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x292d3eff).into()),
|
scrollbar_track_background: Some(rgba(0x292d3eff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xbfc7d5ff).into()),
|
||||||
editor_background: Some(rgba(0x292d3eff).into()),
|
editor_background: Some(rgba(0x292d3eff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x292d3eff).into()),
|
editor_gutter_background: Some(rgba(0x292d3eff).into()),
|
||||||
editor_line_number: Some(rgba(0x4c5374ff).into()),
|
editor_line_number: Some(rgba(0x4c5374ff).into()),
|
||||||
|
|
|
@ -47,6 +47,7 @@ pub fn rose_pine() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x6e6a8633).into()),
|
scrollbar_thumb_border: Some(rgba(0x6e6a8633).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x191724ff).into()),
|
scrollbar_track_background: Some(rgba(0x191724ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x6e6a8666).into()),
|
scrollbar_track_border: Some(rgba(0x6e6a8666).into()),
|
||||||
|
editor_foreground: Some(rgba(0xe0def4ff).into()),
|
||||||
editor_background: Some(rgba(0x191724ff).into()),
|
editor_background: Some(rgba(0x191724ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x191724ff).into()),
|
editor_gutter_background: Some(rgba(0x191724ff).into()),
|
||||||
editor_line_number: Some(rgba(0x908caaff).into()),
|
editor_line_number: Some(rgba(0x908caaff).into()),
|
||||||
|
@ -306,6 +307,7 @@ pub fn rose_pine() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x817c9c26).into()),
|
scrollbar_thumb_border: Some(rgba(0x817c9c26).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x232136ff).into()),
|
scrollbar_track_background: Some(rgba(0x232136ff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x817c9c4d).into()),
|
scrollbar_track_border: Some(rgba(0x817c9c4d).into()),
|
||||||
|
editor_foreground: Some(rgba(0xe0def4ff).into()),
|
||||||
editor_background: Some(rgba(0x232136ff).into()),
|
editor_background: Some(rgba(0x232136ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x232136ff).into()),
|
editor_gutter_background: Some(rgba(0x232136ff).into()),
|
||||||
editor_line_number: Some(rgba(0x908caaff).into()),
|
editor_line_number: Some(rgba(0x908caaff).into()),
|
||||||
|
@ -565,6 +567,7 @@ pub fn rose_pine() -> UserThemeFamily {
|
||||||
scrollbar_thumb_border: Some(rgba(0x6e6a8614).into()),
|
scrollbar_thumb_border: Some(rgba(0x6e6a8614).into()),
|
||||||
scrollbar_track_background: Some(rgba(0xfaf4edff).into()),
|
scrollbar_track_background: Some(rgba(0xfaf4edff).into()),
|
||||||
scrollbar_track_border: Some(rgba(0x6e6a8626).into()),
|
scrollbar_track_border: Some(rgba(0x6e6a8626).into()),
|
||||||
|
editor_foreground: Some(rgba(0x575279ff).into()),
|
||||||
editor_background: Some(rgba(0xfaf4edff).into()),
|
editor_background: Some(rgba(0xfaf4edff).into()),
|
||||||
editor_gutter_background: Some(rgba(0xfaf4edff).into()),
|
editor_gutter_background: Some(rgba(0xfaf4edff).into()),
|
||||||
editor_line_number: Some(rgba(0x797593ff).into()),
|
editor_line_number: Some(rgba(0x797593ff).into()),
|
||||||
|
|
|
@ -42,6 +42,7 @@ pub fn solarized() -> UserThemeFamily {
|
||||||
tab_inactive_background: Some(rgba(0x004052ff).into()),
|
tab_inactive_background: Some(rgba(0x004052ff).into()),
|
||||||
tab_active_background: Some(rgba(0x002b37ff).into()),
|
tab_active_background: Some(rgba(0x002b37ff).into()),
|
||||||
scrollbar_track_background: Some(rgba(0x002b36ff).into()),
|
scrollbar_track_background: Some(rgba(0x002b36ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0xbbbbbbff).into()),
|
||||||
editor_background: Some(rgba(0x002b36ff).into()),
|
editor_background: Some(rgba(0x002b36ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0x002b36ff).into()),
|
editor_gutter_background: Some(rgba(0x002b36ff).into()),
|
||||||
editor_line_number: Some(rgba(0x566c74ff).into()),
|
editor_line_number: Some(rgba(0x566c74ff).into()),
|
||||||
|
@ -307,6 +308,7 @@ pub fn solarized() -> UserThemeFamily {
|
||||||
tab_inactive_background: Some(rgba(0xd3cbb7ff).into()),
|
tab_inactive_background: Some(rgba(0xd3cbb7ff).into()),
|
||||||
tab_active_background: Some(rgba(0xfdf6e3ff).into()),
|
tab_active_background: Some(rgba(0xfdf6e3ff).into()),
|
||||||
scrollbar_track_background: Some(rgba(0xfdf6e3ff).into()),
|
scrollbar_track_background: Some(rgba(0xfdf6e3ff).into()),
|
||||||
|
editor_foreground: Some(rgba(0x333333ff).into()),
|
||||||
editor_background: Some(rgba(0xfdf6e3ff).into()),
|
editor_background: Some(rgba(0xfdf6e3ff).into()),
|
||||||
editor_gutter_background: Some(rgba(0xfdf6e3ff).into()),
|
editor_gutter_background: Some(rgba(0xfdf6e3ff).into()),
|
||||||
editor_line_number: Some(rgba(0x9ca8a6ff).into()),
|
editor_line_number: Some(rgba(0x9ca8a6ff).into()),
|
||||||
|
|
|
@ -201,6 +201,7 @@ impl<'a> Debug for ThemeColorsRefinementPrinter<'a> {
|
||||||
self.0.scrollbar_track_background,
|
self.0.scrollbar_track_background,
|
||||||
),
|
),
|
||||||
("scrollbar_track_border", self.0.scrollbar_track_border),
|
("scrollbar_track_border", self.0.scrollbar_track_border),
|
||||||
|
("editor_foreground", self.0.editor_foreground),
|
||||||
("editor_background", self.0.editor_background),
|
("editor_background", self.0.editor_background),
|
||||||
("editor_gutter_background", self.0.editor_gutter_background),
|
("editor_gutter_background", self.0.editor_gutter_background),
|
||||||
(
|
(
|
||||||
|
|
|
@ -132,6 +132,11 @@ impl VsCodeThemeConverter {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.traverse(|color| try_parse_color(&color))?;
|
.traverse(|color| try_parse_color(&color))?;
|
||||||
|
|
||||||
|
let vscode_editor_foreground = vscode_colors
|
||||||
|
.editor_foreground
|
||||||
|
.as_ref()
|
||||||
|
.traverse(|color| try_parse_color(&color))?;
|
||||||
|
|
||||||
let vscode_editor_background = vscode_colors
|
let vscode_editor_background = vscode_colors
|
||||||
.editor_background
|
.editor_background
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -142,6 +147,16 @@ impl VsCodeThemeConverter {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.traverse(|color| try_parse_color(&color))?;
|
.traverse(|color| try_parse_color(&color))?;
|
||||||
|
|
||||||
|
let vscode_token_colors_foreground = self
|
||||||
|
.theme
|
||||||
|
.token_colors
|
||||||
|
.iter()
|
||||||
|
.find(|token_color| token_color.scope.is_none())
|
||||||
|
.and_then(|token_color| token_color.settings.foreground.as_ref())
|
||||||
|
.traverse(|color| try_parse_color(&color))
|
||||||
|
.ok()
|
||||||
|
.flatten();
|
||||||
|
|
||||||
Ok(ThemeColorsRefinement {
|
Ok(ThemeColorsRefinement {
|
||||||
border: vscode_panel_border,
|
border: vscode_panel_border,
|
||||||
border_variant: vscode_panel_border,
|
border_variant: vscode_panel_border,
|
||||||
|
@ -197,16 +212,7 @@ impl VsCodeThemeConverter {
|
||||||
.foreground
|
.foreground
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.traverse(|color| try_parse_color(&color))?
|
.traverse(|color| try_parse_color(&color))?
|
||||||
.or_else(|| {
|
.or(vscode_token_colors_foreground),
|
||||||
self.theme
|
|
||||||
.token_colors
|
|
||||||
.iter()
|
|
||||||
.find(|token_color| token_color.scope.is_none())
|
|
||||||
.and_then(|token_color| token_color.settings.foreground.as_ref())
|
|
||||||
.traverse(|color| try_parse_color(&color))
|
|
||||||
.ok()
|
|
||||||
.flatten()
|
|
||||||
}),
|
|
||||||
text_muted: vscode_colors
|
text_muted: vscode_colors
|
||||||
.tab_inactive_foreground
|
.tab_inactive_foreground
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -226,6 +232,7 @@ impl VsCodeThemeConverter {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.traverse(|color| try_parse_color(&color))?
|
.traverse(|color| try_parse_color(&color))?
|
||||||
.or(vscode_editor_background),
|
.or(vscode_editor_background),
|
||||||
|
editor_foreground: vscode_editor_foreground.or(vscode_token_colors_foreground),
|
||||||
editor_background: vscode_editor_background,
|
editor_background: vscode_editor_background,
|
||||||
editor_gutter_background: vscode_editor_background,
|
editor_gutter_background: vscode_editor_background,
|
||||||
editor_line_number: vscode_colors
|
editor_line_number: vscode_colors
|
||||||
|
|
|
@ -41,7 +41,7 @@ pub trait Panel: FocusableView + EventEmitter<PanelEvent> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PanelHandle: Send + Sync {
|
pub trait PanelHandle: Send + Sync {
|
||||||
fn entity_id(&self) -> EntityId;
|
fn panel_id(&self) -> EntityId;
|
||||||
fn persistent_name(&self) -> &'static str;
|
fn persistent_name(&self) -> &'static str;
|
||||||
fn position(&self, cx: &WindowContext) -> DockPosition;
|
fn position(&self, cx: &WindowContext) -> DockPosition;
|
||||||
fn position_is_valid(&self, position: DockPosition, cx: &WindowContext) -> bool;
|
fn position_is_valid(&self, position: DockPosition, cx: &WindowContext) -> bool;
|
||||||
|
@ -62,7 +62,7 @@ impl<T> PanelHandle for View<T>
|
||||||
where
|
where
|
||||||
T: Panel,
|
T: Panel,
|
||||||
{
|
{
|
||||||
fn entity_id(&self) -> EntityId {
|
fn panel_id(&self) -> EntityId {
|
||||||
Entity::entity_id(self)
|
Entity::entity_id(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ pub struct Dock {
|
||||||
is_open: bool,
|
is_open: bool,
|
||||||
active_panel_index: usize,
|
active_panel_index: usize,
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
focus_subscription: Subscription,
|
_focus_subscription: Subscription,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FocusableView for Dock {
|
impl FocusableView for Dock {
|
||||||
|
@ -187,7 +187,6 @@ struct PanelEntry {
|
||||||
|
|
||||||
pub struct PanelButtons {
|
pub struct PanelButtons {
|
||||||
dock: View<Dock>,
|
dock: View<Dock>,
|
||||||
workspace: WeakView<Workspace>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Dock {
|
impl Dock {
|
||||||
|
@ -204,7 +203,7 @@ impl Dock {
|
||||||
active_panel_index: 0,
|
active_panel_index: 0,
|
||||||
is_open: false,
|
is_open: false,
|
||||||
focus_handle,
|
focus_handle,
|
||||||
focus_subscription,
|
_focus_subscription: focus_subscription,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +260,7 @@ impl Dock {
|
||||||
|
|
||||||
pub fn set_panel_zoomed(&mut self, panel: &AnyView, zoomed: bool, cx: &mut ViewContext<Self>) {
|
pub fn set_panel_zoomed(&mut self, panel: &AnyView, zoomed: bool, cx: &mut ViewContext<Self>) {
|
||||||
for entry in &mut self.panel_entries {
|
for entry in &mut self.panel_entries {
|
||||||
if entry.panel.entity_id() == panel.entity_id() {
|
if entry.panel.panel_id() == panel.entity_id() {
|
||||||
if zoomed != entry.panel.is_zoomed(cx) {
|
if zoomed != entry.panel.is_zoomed(cx) {
|
||||||
entry.panel.set_zoomed(zoomed, cx);
|
entry.panel.set_zoomed(zoomed, cx);
|
||||||
}
|
}
|
||||||
|
@ -309,7 +308,7 @@ impl Dock {
|
||||||
|
|
||||||
let was_visible = this.is_open()
|
let was_visible = this.is_open()
|
||||||
&& this.visible_panel().map_or(false, |active_panel| {
|
&& this.visible_panel().map_or(false, |active_panel| {
|
||||||
active_panel.entity_id() == Entity::entity_id(&panel)
|
active_panel.panel_id() == Entity::entity_id(&panel)
|
||||||
});
|
});
|
||||||
|
|
||||||
this.remove_panel(&panel, cx);
|
this.remove_panel(&panel, cx);
|
||||||
|
@ -351,7 +350,7 @@ impl Dock {
|
||||||
if let Some(ix) = this
|
if let Some(ix) = this
|
||||||
.panel_entries
|
.panel_entries
|
||||||
.iter()
|
.iter()
|
||||||
.position(|entry| entry.panel.entity_id() == Entity::entity_id(&panel))
|
.position(|entry| entry.panel.panel_id() == Entity::entity_id(&panel))
|
||||||
{
|
{
|
||||||
this.set_open(true, cx);
|
this.set_open(true, cx);
|
||||||
this.activate_panel(ix, cx);
|
this.activate_panel(ix, cx);
|
||||||
|
@ -361,7 +360,7 @@ impl Dock {
|
||||||
PanelEvent::Close => {
|
PanelEvent::Close => {
|
||||||
if this
|
if this
|
||||||
.visible_panel()
|
.visible_panel()
|
||||||
.map_or(false, |p| p.entity_id() == Entity::entity_id(&panel))
|
.map_or(false, |p| p.panel_id() == Entity::entity_id(&panel))
|
||||||
{
|
{
|
||||||
this.set_open(false, cx);
|
this.set_open(false, cx);
|
||||||
}
|
}
|
||||||
|
@ -389,7 +388,7 @@ impl Dock {
|
||||||
if let Some(panel_ix) = self
|
if let Some(panel_ix) = self
|
||||||
.panel_entries
|
.panel_entries
|
||||||
.iter()
|
.iter()
|
||||||
.position(|entry| entry.panel.entity_id() == Entity::entity_id(panel))
|
.position(|entry| entry.panel.panel_id() == Entity::entity_id(panel))
|
||||||
{
|
{
|
||||||
if panel_ix == self.active_panel_index {
|
if panel_ix == self.active_panel_index {
|
||||||
self.active_panel_index = 0;
|
self.active_panel_index = 0;
|
||||||
|
@ -450,7 +449,7 @@ impl Dock {
|
||||||
pub fn panel_size(&self, panel: &dyn PanelHandle, cx: &WindowContext) -> Option<f32> {
|
pub fn panel_size(&self, panel: &dyn PanelHandle, cx: &WindowContext) -> Option<f32> {
|
||||||
self.panel_entries
|
self.panel_entries
|
||||||
.iter()
|
.iter()
|
||||||
.find(|entry| entry.panel.entity_id() == panel.entity_id())
|
.find(|entry| entry.panel.panel_id() == panel.panel_id())
|
||||||
.map(|entry| entry.panel.size(cx))
|
.map(|entry| entry.panel.size(cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,7 +492,9 @@ impl Render for Dock {
|
||||||
let handler = div()
|
let handler = div()
|
||||||
.id("resize-handle")
|
.id("resize-handle")
|
||||||
.bg(cx.theme().colors().border)
|
.bg(cx.theme().colors().border)
|
||||||
.on_drag(move |cx| cx.build_view(|_| DraggedDock(position)))
|
.on_drag(DraggedDock(position), |dock, cx| {
|
||||||
|
cx.build_view(|_| dock.clone())
|
||||||
|
})
|
||||||
.on_click(cx.listener(|v, e: &ClickEvent, cx| {
|
.on_click(cx.listener(|v, e: &ClickEvent, cx| {
|
||||||
if e.down.button == MouseButton::Left && e.down.click_count == 2 {
|
if e.down.button == MouseButton::Left && e.down.click_count == 2 {
|
||||||
v.resize_active_panel(None, cx)
|
v.resize_active_panel(None, cx)
|
||||||
|
@ -547,166 +548,12 @@ impl Render for Dock {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PanelButtons {
|
impl PanelButtons {
|
||||||
pub fn new(
|
pub fn new(dock: View<Dock>, cx: &mut ViewContext<Self>) -> Self {
|
||||||
dock: View<Dock>,
|
|
||||||
workspace: WeakView<Workspace>,
|
|
||||||
cx: &mut ViewContext<Self>,
|
|
||||||
) -> Self {
|
|
||||||
cx.observe(&dock, |_, _, cx| cx.notify()).detach();
|
cx.observe(&dock, |_, _, cx| cx.notify()).detach();
|
||||||
Self { dock, workspace }
|
Self { dock }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl Render for PanelButtons {
|
|
||||||
// type Element = ();
|
|
||||||
|
|
||||||
// fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
|
||||||
// todo!("")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn ui_name() -> &'static str {
|
|
||||||
// "PanelButtons"
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
|
||||||
// let theme = &settings::get::<ThemeSettings>(cx).theme;
|
|
||||||
// let tooltip_style = theme.tooltip.clone();
|
|
||||||
// let theme = &theme.workspace.status_bar.panel_buttons;
|
|
||||||
// let button_style = theme.button.clone();
|
|
||||||
// let dock = self.dock.read(cx);
|
|
||||||
// let active_ix = dock.active_panel_index;
|
|
||||||
// let is_open = dock.is_open;
|
|
||||||
// let dock_position = dock.position;
|
|
||||||
// let group_style = match dock_position {
|
|
||||||
// DockPosition::Left => theme.group_left,
|
|
||||||
// DockPosition::Bottom => theme.group_bottom,
|
|
||||||
// DockPosition::Right => theme.group_right,
|
|
||||||
// };
|
|
||||||
// let menu_corner = match dock_position {
|
|
||||||
// DockPosition::Left => AnchorCorner::BottomLeft,
|
|
||||||
// DockPosition::Bottom | DockPosition::Right => AnchorCorner::BottomRight,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let panels = dock
|
|
||||||
// .panel_entries
|
|
||||||
// .iter()
|
|
||||||
// .map(|item| (item.panel.clone(), item.context_menu.clone()))
|
|
||||||
// .collect::<Vec<_>>();
|
|
||||||
// Flex::row()
|
|
||||||
// .with_children(panels.into_iter().enumerate().filter_map(
|
|
||||||
// |(panel_ix, (view, context_menu))| {
|
|
||||||
// let icon_path = view.icon_path(cx)?;
|
|
||||||
// let is_active = is_open && panel_ix == active_ix;
|
|
||||||
// let (tooltip, tooltip_action) = if is_active {
|
|
||||||
// (
|
|
||||||
// format!("Close {} dock", dock_position.to_label()),
|
|
||||||
// Some(match dock_position {
|
|
||||||
// DockPosition::Left => crate::ToggleLeftDock.boxed_clone(),
|
|
||||||
// DockPosition::Bottom => crate::ToggleBottomDock.boxed_clone(),
|
|
||||||
// DockPosition::Right => crate::ToggleRightDock.boxed_clone(),
|
|
||||||
// }),
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// view.icon_tooltip(cx)
|
|
||||||
// };
|
|
||||||
// Some(
|
|
||||||
// Stack::new()
|
|
||||||
// .with_child(
|
|
||||||
// MouseEventHandler::new::<Self, _>(panel_ix, cx, |state, cx| {
|
|
||||||
// let style = button_style.in_state(is_active);
|
|
||||||
|
|
||||||
// let style = style.style_for(state);
|
|
||||||
// Flex::row()
|
|
||||||
// .with_child(
|
|
||||||
// Svg::new(icon_path)
|
|
||||||
// .with_color(style.icon_color)
|
|
||||||
// .constrained()
|
|
||||||
// .with_width(style.icon_size)
|
|
||||||
// .aligned(),
|
|
||||||
// )
|
|
||||||
// .with_children(if let Some(label) = view.icon_label(cx) {
|
|
||||||
// Some(
|
|
||||||
// Label::new(label, style.label.text.clone())
|
|
||||||
// .contained()
|
|
||||||
// .with_style(style.label.container)
|
|
||||||
// .aligned(),
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// None
|
|
||||||
// })
|
|
||||||
// .constrained()
|
|
||||||
// .with_height(style.icon_size)
|
|
||||||
// .contained()
|
|
||||||
// .with_style(style.container)
|
|
||||||
// })
|
|
||||||
// .with_cursor_style(CursorStyle::PointingHand)
|
|
||||||
// .on_click(MouseButton::Left, {
|
|
||||||
// let tooltip_action =
|
|
||||||
// tooltip_action.as_ref().map(|action| action.boxed_clone());
|
|
||||||
// move |_, this, cx| {
|
|
||||||
// if let Some(tooltip_action) = &tooltip_action {
|
|
||||||
// let window = cx.window();
|
|
||||||
// let view_id = this.workspace.id();
|
|
||||||
// let tooltip_action = tooltip_action.boxed_clone();
|
|
||||||
// cx.spawn(|_, mut cx| async move {
|
|
||||||
// window.dispatch_action(
|
|
||||||
// view_id,
|
|
||||||
// &*tooltip_action,
|
|
||||||
// &mut cx,
|
|
||||||
// );
|
|
||||||
// })
|
|
||||||
// .detach();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// .on_click(MouseButton::Right, {
|
|
||||||
// let view = view.clone();
|
|
||||||
// let menu = context_menu.clone();
|
|
||||||
// move |_, _, cx| {
|
|
||||||
// const POSITIONS: [DockPosition; 3] = [
|
|
||||||
// DockPosition::Left,
|
|
||||||
// DockPosition::Right,
|
|
||||||
// DockPosition::Bottom,
|
|
||||||
// ];
|
|
||||||
|
|
||||||
// menu.update(cx, |menu, cx| {
|
|
||||||
// let items = POSITIONS
|
|
||||||
// .into_iter()
|
|
||||||
// .filter(|position| {
|
|
||||||
// *position != dock_position
|
|
||||||
// && view.position_is_valid(*position, cx)
|
|
||||||
// })
|
|
||||||
// .map(|position| {
|
|
||||||
// let view = view.clone();
|
|
||||||
// ContextMenuItem::handler(
|
|
||||||
// format!("Dock {}", position.to_label()),
|
|
||||||
// move |cx| view.set_position(position, cx),
|
|
||||||
// )
|
|
||||||
// })
|
|
||||||
// .collect();
|
|
||||||
// menu.show(Default::default(), menu_corner, items, cx);
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// .with_tooltip::<Self>(
|
|
||||||
// panel_ix,
|
|
||||||
// tooltip,
|
|
||||||
// tooltip_action,
|
|
||||||
// tooltip_style.clone(),
|
|
||||||
// cx,
|
|
||||||
// ),
|
|
||||||
// )
|
|
||||||
// .with_child(ChildView::new(&context_menu, cx)),
|
|
||||||
// )
|
|
||||||
// },
|
|
||||||
// ))
|
|
||||||
// .contained()
|
|
||||||
// .with_style(group_style)
|
|
||||||
// .into_any()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// here be kittens
|
|
||||||
impl Render for PanelButtons {
|
impl Render for PanelButtons {
|
||||||
type Element = Div;
|
type Element = Div;
|
||||||
|
|
||||||
|
|
|
@ -919,7 +919,7 @@ pub mod test {
|
||||||
impl EventEmitter<ItemEvent> for TestItem {}
|
impl EventEmitter<ItemEvent> for TestItem {}
|
||||||
|
|
||||||
impl FocusableView for TestItem {
|
impl FocusableView for TestItem {
|
||||||
fn focus_handle(&self, cx: &AppContext) -> gpui::FocusHandle {
|
fn focus_handle(&self, _: &AppContext) -> gpui::FocusHandle {
|
||||||
self.focus_handle.clone()
|
self.focus_handle.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -941,8 +941,8 @@ pub mod test {
|
||||||
fn tab_content(
|
fn tab_content(
|
||||||
&self,
|
&self,
|
||||||
detail: Option<usize>,
|
detail: Option<usize>,
|
||||||
selected: bool,
|
_selected: bool,
|
||||||
cx: &ui::prelude::WindowContext,
|
_cx: &ui::prelude::WindowContext,
|
||||||
) -> AnyElement {
|
) -> AnyElement {
|
||||||
self.tab_detail.set(detail);
|
self.tab_detail.set(detail);
|
||||||
gpui::div().into_any_element()
|
gpui::div().into_any_element()
|
||||||
|
|
|
@ -5,7 +5,7 @@ use gpui::{
|
||||||
use ui::{h_stack, v_stack};
|
use ui::{h_stack, v_stack};
|
||||||
|
|
||||||
pub trait ModalView: ManagedView {
|
pub trait ModalView: ManagedView {
|
||||||
fn on_before_dismiss(&mut self, cx: &mut ViewContext<Self>) -> bool {
|
fn on_before_dismiss(&mut self, _: &mut ViewContext<Self>) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ impl<V: ModalView> ModalViewHandle for View<V> {
|
||||||
|
|
||||||
pub struct ActiveModal {
|
pub struct ActiveModal {
|
||||||
modal: Box<dyn ModalViewHandle>,
|
modal: Box<dyn ModalViewHandle>,
|
||||||
subscription: Subscription,
|
_subscription: Subscription,
|
||||||
previous_focus_handle: Option<FocusHandle>,
|
previous_focus_handle: Option<FocusHandle>,
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ impl ModalLayer {
|
||||||
{
|
{
|
||||||
self.active_modal = Some(ActiveModal {
|
self.active_modal = Some(ActiveModal {
|
||||||
modal: Box::new(new_modal.clone()),
|
modal: Box::new(new_modal.clone()),
|
||||||
subscription: cx.subscribe(&new_modal, |this, modal, _: &DismissEvent, cx| {
|
_subscription: cx.subscribe(&new_modal, |this, _, _: &DismissEvent, cx| {
|
||||||
this.hide_modal(cx);
|
this.hide_modal(cx);
|
||||||
}),
|
}),
|
||||||
previous_focus_handle: cx.focused(),
|
previous_focus_handle: cx.focused(),
|
||||||
|
|
|
@ -104,12 +104,9 @@ impl Workspace {
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
let notification = build_notification(cx);
|
let notification = build_notification(cx);
|
||||||
cx.subscribe(
|
cx.subscribe(¬ification, move |this, _, _: &DismissEvent, cx| {
|
||||||
¬ification,
|
this.dismiss_notification_internal(type_id, id, cx);
|
||||||
move |this, handle, event: &DismissEvent, cx| {
|
})
|
||||||
this.dismiss_notification_internal(type_id, id, cx);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.detach();
|
.detach();
|
||||||
self.notifications
|
self.notifications
|
||||||
.push((type_id, id, Box::new(notification)));
|
.push((type_id, id, Box::new(notification)));
|
||||||
|
@ -173,21 +170,15 @@ impl Workspace {
|
||||||
|
|
||||||
pub mod simple_message_notification {
|
pub mod simple_message_notification {
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, AnyElement, AppContext, DismissEvent, Div, EventEmitter, InteractiveElement,
|
div, DismissEvent, Div, EventEmitter, InteractiveElement, ParentElement, Render,
|
||||||
ParentElement, Render, SharedString, StatefulInteractiveElement, Styled, TextStyle,
|
SharedString, StatefulInteractiveElement, Styled, ViewContext,
|
||||||
ViewContext,
|
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use ui::prelude::*;
|
use ui::prelude::*;
|
||||||
use ui::{h_stack, v_stack, Button, Icon, IconElement, Label, StyledExt};
|
use ui::{h_stack, v_stack, Button, Icon, IconElement, Label, StyledExt};
|
||||||
|
|
||||||
enum NotificationMessage {
|
|
||||||
Text(SharedString),
|
|
||||||
Element(fn(TextStyle, &AppContext) -> AnyElement),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MessageNotification {
|
pub struct MessageNotification {
|
||||||
message: NotificationMessage,
|
message: SharedString,
|
||||||
on_click: Option<Arc<dyn Fn(&mut ViewContext<Self>)>>,
|
on_click: Option<Arc<dyn Fn(&mut ViewContext<Self>)>>,
|
||||||
click_message: Option<SharedString>,
|
click_message: Option<SharedString>,
|
||||||
}
|
}
|
||||||
|
@ -200,23 +191,12 @@ pub mod simple_message_notification {
|
||||||
S: Into<SharedString>,
|
S: Into<SharedString>,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
message: NotificationMessage::Text(message.into()),
|
message: message.into(),
|
||||||
on_click: None,
|
on_click: None,
|
||||||
click_message: None,
|
click_message: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// not needed I think (only for the "new panel" toast, which is outdated now)
|
|
||||||
// pub fn new_element(
|
|
||||||
// message: fn(TextStyle, &AppContext) -> AnyElement,
|
|
||||||
// ) -> MessageNotification {
|
|
||||||
// Self {
|
|
||||||
// message: NotificationMessage::Element(message),
|
|
||||||
// on_click: None,
|
|
||||||
// click_message: None,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn with_click_message<S>(mut self, message: S) -> Self
|
pub fn with_click_message<S>(mut self, message: S) -> Self
|
||||||
where
|
where
|
||||||
S: Into<SharedString>,
|
S: Into<SharedString>,
|
||||||
|
@ -248,18 +228,13 @@ pub mod simple_message_notification {
|
||||||
.child(
|
.child(
|
||||||
h_stack()
|
h_stack()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
.child(div().max_w_80().child(match &self.message {
|
.child(div().max_w_80().child(Label::new(self.message.clone())))
|
||||||
NotificationMessage::Text(text) => Label::new(text.clone()),
|
|
||||||
NotificationMessage::Element(element) => {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.id("cancel")
|
.id("cancel")
|
||||||
.child(IconElement::new(Icon::Close))
|
.child(IconElement::new(Icon::Close))
|
||||||
.cursor_pointer()
|
.cursor_pointer()
|
||||||
.on_click(cx.listener(|this, event, cx| this.dismiss(cx))),
|
.on_click(cx.listener(|this, _, cx| this.dismiss(cx))),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.children(self.click_message.iter().map(|message| {
|
.children(self.click_message.iter().map(|message| {
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use collections::{HashMap, HashSet, VecDeque};
|
use collections::{HashMap, HashSet, VecDeque};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AnyWeakView, AppContext,
|
actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AppContext,
|
||||||
AsyncWindowContext, DismissEvent, Div, EntityId, EventEmitter, FocusHandle, Focusable,
|
AsyncWindowContext, DismissEvent, Div, EntityId, EventEmitter, FocusHandle, Focusable,
|
||||||
FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, PromptLevel, Render,
|
FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, PromptLevel, Render,
|
||||||
ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext,
|
ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext,
|
||||||
|
@ -164,11 +164,6 @@ impl fmt::Debug for Event {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FocusedView {
|
|
||||||
view: AnyWeakView,
|
|
||||||
focus_handle: FocusHandle,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Pane {
|
pub struct Pane {
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
items: Vec<Box<dyn ItemHandle>>,
|
items: Vec<Box<dyn ItemHandle>>,
|
||||||
|
@ -187,7 +182,7 @@ pub struct Pane {
|
||||||
// can_drop: Rc<dyn Fn(&DragAndDrop<Workspace>, &WindowContext) -> bool>,
|
// can_drop: Rc<dyn Fn(&DragAndDrop<Workspace>, &WindowContext) -> bool>,
|
||||||
can_split: bool,
|
can_split: bool,
|
||||||
// render_tab_bar_buttons: Rc<dyn Fn(&mut Pane, &mut ViewContext<Pane>) -> AnyElement<Pane>>,
|
// render_tab_bar_buttons: Rc<dyn Fn(&mut Pane, &mut ViewContext<Pane>) -> AnyElement<Pane>>,
|
||||||
subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
tab_bar_scroll_handle: ScrollHandle,
|
tab_bar_scroll_handle: ScrollHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,6 +226,7 @@ pub struct NavigationEntry {
|
||||||
pub timestamp: usize,
|
pub timestamp: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
struct DraggedTab {
|
struct DraggedTab {
|
||||||
pub pane: View<Pane>,
|
pub pane: View<Pane>,
|
||||||
pub ix: usize,
|
pub ix: usize,
|
||||||
|
@ -431,14 +427,10 @@ impl Pane {
|
||||||
// })
|
// })
|
||||||
// .into_any()
|
// .into_any()
|
||||||
// }),
|
// }),
|
||||||
subscriptions,
|
_subscriptions: subscriptions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn workspace(&self) -> &WeakView<Workspace> {
|
|
||||||
&self.workspace
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_focus(&self, cx: &WindowContext) -> bool {
|
pub fn has_focus(&self, cx: &WindowContext) -> bool {
|
||||||
// todo!(); // inline this manually
|
// todo!(); // inline this manually
|
||||||
self.focus_handle.contains_focused(cx)
|
self.focus_handle.contains_focused(cx)
|
||||||
|
@ -1467,21 +1459,6 @@ impl Pane {
|
||||||
let label = item.tab_content(Some(detail), is_active, cx);
|
let label = item.tab_content(Some(detail), is_active, cx);
|
||||||
let close_side = &ItemSettings::get_global(cx).close_position;
|
let close_side = &ItemSettings::get_global(cx).close_position;
|
||||||
|
|
||||||
let (text_color, tab_bg, tab_hover_bg, tab_active_bg) = match ix == self.active_item_index {
|
|
||||||
false => (
|
|
||||||
cx.theme().colors().text_muted,
|
|
||||||
cx.theme().colors().tab_inactive_background,
|
|
||||||
cx.theme().colors().ghost_element_hover,
|
|
||||||
cx.theme().colors().ghost_element_active,
|
|
||||||
),
|
|
||||||
true => (
|
|
||||||
cx.theme().colors().text,
|
|
||||||
cx.theme().colors().tab_active_background,
|
|
||||||
cx.theme().colors().element_hover,
|
|
||||||
cx.theme().colors().element_active,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
let indicator = maybe!({
|
let indicator = maybe!({
|
||||||
let indicator_color = match (item.has_conflict(cx), item.is_dirty(cx)) {
|
let indicator_color = match (item.has_conflict(cx), item.is_dirty(cx)) {
|
||||||
(true, _) => Color::Warning,
|
(true, _) => Color::Warning,
|
||||||
|
@ -1497,56 +1474,55 @@ impl Pane {
|
||||||
let is_last_item = ix == self.items.len() - 1;
|
let is_last_item = ix == self.items.len() - 1;
|
||||||
let position_relative_to_active_item = ix.cmp(&self.active_item_index);
|
let position_relative_to_active_item = ix.cmp(&self.active_item_index);
|
||||||
|
|
||||||
let tab =
|
let tab = Tab::new(ix)
|
||||||
Tab::new(ix)
|
.position(if is_first_item {
|
||||||
.position(if is_first_item {
|
TabPosition::First
|
||||||
TabPosition::First
|
} else if is_last_item {
|
||||||
} else if is_last_item {
|
TabPosition::Last
|
||||||
TabPosition::Last
|
} else {
|
||||||
} else {
|
TabPosition::Middle(position_relative_to_active_item)
|
||||||
TabPosition::Middle(position_relative_to_active_item)
|
})
|
||||||
})
|
.close_side(match close_side {
|
||||||
.close_side(match close_side {
|
ClosePosition::Left => ui::TabCloseSide::Start,
|
||||||
ClosePosition::Left => ui::TabCloseSide::Start,
|
ClosePosition::Right => ui::TabCloseSide::End,
|
||||||
ClosePosition::Right => ui::TabCloseSide::End,
|
})
|
||||||
})
|
.selected(is_active)
|
||||||
.selected(is_active)
|
.on_click(
|
||||||
.on_click(cx.listener(move |pane: &mut Self, event, cx| {
|
cx.listener(move |pane: &mut Self, _, cx| pane.activate_item(ix, true, true, cx)),
|
||||||
pane.activate_item(ix, true, true, cx)
|
)
|
||||||
}))
|
.on_drag(
|
||||||
.on_drag({
|
DraggedTab {
|
||||||
let pane = cx.view().clone();
|
pane: cx.view().clone(),
|
||||||
move |cx| {
|
detail,
|
||||||
cx.build_view(|cx| DraggedTab {
|
item_id,
|
||||||
pane: pane.clone(),
|
is_active,
|
||||||
detail,
|
ix,
|
||||||
item_id,
|
},
|
||||||
is_active,
|
|tab, cx| cx.build_view(|_| tab.clone()),
|
||||||
ix,
|
)
|
||||||
})
|
.drag_over::<DraggedTab>(|tab| tab.bg(cx.theme().colors().tab_active_background))
|
||||||
}
|
.drag_over::<ProjectEntryId>(|tab| tab.bg(gpui::red()))
|
||||||
})
|
.on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| {
|
||||||
.drag_over::<DraggedTab>(|tab| tab.bg(cx.theme().colors().tab_active_background))
|
this.handle_tab_drop(dragged_tab, ix, cx)
|
||||||
.on_drop(
|
}))
|
||||||
cx.listener(move |this, dragged_tab: &View<DraggedTab>, cx| {
|
.on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| {
|
||||||
this.handle_tab_drop(dragged_tab, ix, cx)
|
this.handle_project_entry_drop(entry_id, cx)
|
||||||
}),
|
}))
|
||||||
)
|
.when_some(item.tab_tooltip_text(cx), |tab, text| {
|
||||||
.when_some(item.tab_tooltip_text(cx), |tab, text| {
|
tab.tooltip(move |cx| Tooltip::text(text.clone(), cx))
|
||||||
tab.tooltip(move |cx| Tooltip::text(text.clone(), cx))
|
})
|
||||||
})
|
.start_slot::<Indicator>(indicator)
|
||||||
.start_slot::<Indicator>(indicator)
|
.end_slot(
|
||||||
.end_slot(
|
IconButton::new("close tab", Icon::Close)
|
||||||
IconButton::new("close tab", Icon::Close)
|
.icon_color(Color::Muted)
|
||||||
.icon_color(Color::Muted)
|
.size(ButtonSize::None)
|
||||||
.size(ButtonSize::None)
|
.icon_size(IconSize::XSmall)
|
||||||
.icon_size(IconSize::XSmall)
|
.on_click(cx.listener(move |pane, _, cx| {
|
||||||
.on_click(cx.listener(move |pane, _, cx| {
|
pane.close_item_by_id(item_id, SaveIntent::Close, cx)
|
||||||
pane.close_item_by_id(item_id, SaveIntent::Close, cx)
|
.detach_and_log_err(cx);
|
||||||
.detach_and_log_err(cx);
|
})),
|
||||||
})),
|
)
|
||||||
)
|
.child(label);
|
||||||
.child(label);
|
|
||||||
|
|
||||||
let single_entry_to_resolve = {
|
let single_entry_to_resolve = {
|
||||||
let item_entries = self.items[ix].project_entry_ids(cx);
|
let item_entries = self.items[ix].project_entry_ids(cx);
|
||||||
|
@ -1616,12 +1592,12 @@ impl Pane {
|
||||||
IconButton::new("plus", Icon::Plus)
|
IconButton::new("plus", Icon::Plus)
|
||||||
.icon_size(IconSize::Small)
|
.icon_size(IconSize::Small)
|
||||||
.on_click(cx.listener(|this, _, cx| {
|
.on_click(cx.listener(|this, _, cx| {
|
||||||
let menu = ContextMenu::build(cx, |menu, cx| {
|
let menu = ContextMenu::build(cx, |menu, _| {
|
||||||
menu.action("New File", NewFile.boxed_clone())
|
menu.action("New File", NewFile.boxed_clone())
|
||||||
.action("New Terminal", NewCenterTerminal.boxed_clone())
|
.action("New Terminal", NewCenterTerminal.boxed_clone())
|
||||||
.action("New Search", NewSearch.boxed_clone())
|
.action("New Search", NewSearch.boxed_clone())
|
||||||
});
|
});
|
||||||
cx.subscribe(&menu, |this, _, event: &DismissEvent, cx| {
|
cx.subscribe(&menu, |this, _, _: &DismissEvent, cx| {
|
||||||
this.focus(cx);
|
this.focus(cx);
|
||||||
this.new_item_menu = None;
|
this.new_item_menu = None;
|
||||||
})
|
})
|
||||||
|
@ -1640,13 +1616,13 @@ impl Pane {
|
||||||
IconButton::new("split", Icon::Split)
|
IconButton::new("split", Icon::Split)
|
||||||
.icon_size(IconSize::Small)
|
.icon_size(IconSize::Small)
|
||||||
.on_click(cx.listener(|this, _, cx| {
|
.on_click(cx.listener(|this, _, cx| {
|
||||||
let menu = ContextMenu::build(cx, |menu, cx| {
|
let menu = ContextMenu::build(cx, |menu, _| {
|
||||||
menu.action("Split Right", SplitRight.boxed_clone())
|
menu.action("Split Right", SplitRight.boxed_clone())
|
||||||
.action("Split Left", SplitLeft.boxed_clone())
|
.action("Split Left", SplitLeft.boxed_clone())
|
||||||
.action("Split Up", SplitUp.boxed_clone())
|
.action("Split Up", SplitUp.boxed_clone())
|
||||||
.action("Split Down", SplitDown.boxed_clone())
|
.action("Split Down", SplitDown.boxed_clone())
|
||||||
});
|
});
|
||||||
cx.subscribe(&menu, |this, _, event: &DismissEvent, cx| {
|
cx.subscribe(&menu, |this, _, _: &DismissEvent, cx| {
|
||||||
this.focus(cx);
|
this.focus(cx);
|
||||||
this.split_item_menu = None;
|
this.split_item_menu = None;
|
||||||
})
|
})
|
||||||
|
@ -1677,11 +1653,13 @@ impl Pane {
|
||||||
.drag_over::<DraggedTab>(|bar| {
|
.drag_over::<DraggedTab>(|bar| {
|
||||||
bar.bg(cx.theme().colors().tab_active_background)
|
bar.bg(cx.theme().colors().tab_active_background)
|
||||||
})
|
})
|
||||||
.on_drop(
|
.drag_over::<ProjectEntryId>(|bar| bar.bg(gpui::red()))
|
||||||
cx.listener(move |this, dragged_tab: &View<DraggedTab>, cx| {
|
.on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| {
|
||||||
this.handle_tab_drop(dragged_tab, this.items.len(), cx)
|
this.handle_tab_drop(dragged_tab, this.items.len(), cx)
|
||||||
}),
|
}))
|
||||||
),
|
.on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| {
|
||||||
|
this.handle_project_entry_drop(entry_id, cx)
|
||||||
|
})),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1743,16 +1721,15 @@ impl Pane {
|
||||||
|
|
||||||
fn handle_tab_drop(
|
fn handle_tab_drop(
|
||||||
&mut self,
|
&mut self,
|
||||||
dragged_tab: &View<DraggedTab>,
|
dragged_tab: &DraggedTab,
|
||||||
ix: usize,
|
ix: usize,
|
||||||
cx: &mut ViewContext<'_, Pane>,
|
cx: &mut ViewContext<'_, Pane>,
|
||||||
) {
|
) {
|
||||||
let dragged_tab = dragged_tab.read(cx);
|
|
||||||
let item_id = dragged_tab.item_id;
|
let item_id = dragged_tab.item_id;
|
||||||
let from_pane = dragged_tab.pane.clone();
|
let from_pane = dragged_tab.pane.clone();
|
||||||
let to_pane = cx.view().clone();
|
let to_pane = cx.view().clone();
|
||||||
self.workspace
|
self.workspace
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |_, cx| {
|
||||||
cx.defer(move |workspace, cx| {
|
cx.defer(move |workspace, cx| {
|
||||||
workspace.move_item(from_pane, to_pane, item_id, ix, cx);
|
workspace.move_item(from_pane, to_pane, item_id, ix, cx);
|
||||||
});
|
});
|
||||||
|
@ -1760,28 +1737,69 @@ impl Pane {
|
||||||
.log_err();
|
.log_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_project_entry_drop(
|
||||||
|
&mut self,
|
||||||
|
project_entry_id: &ProjectEntryId,
|
||||||
|
cx: &mut ViewContext<'_, Pane>,
|
||||||
|
) {
|
||||||
|
let to_pane = cx.view().downgrade();
|
||||||
|
let project_entry_id = *project_entry_id;
|
||||||
|
self.workspace
|
||||||
|
.update(cx, |_, cx| {
|
||||||
|
cx.defer(move |workspace, cx| {
|
||||||
|
if let Some(path) = workspace
|
||||||
|
.project()
|
||||||
|
.read(cx)
|
||||||
|
.path_for_entry(project_entry_id, cx)
|
||||||
|
{
|
||||||
|
workspace
|
||||||
|
.open_path(path, Some(to_pane), true, cx)
|
||||||
|
.detach_and_log_err(cx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.log_err();
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_split_tab_drop(
|
fn handle_split_tab_drop(
|
||||||
&mut self,
|
&mut self,
|
||||||
dragged_tab: &View<DraggedTab>,
|
dragged_tab: &DraggedTab,
|
||||||
split_direction: SplitDirection,
|
split_direction: SplitDirection,
|
||||||
cx: &mut ViewContext<'_, Pane>,
|
cx: &mut ViewContext<'_, Pane>,
|
||||||
) {
|
) {
|
||||||
let dragged_tab = dragged_tab.read(cx);
|
|
||||||
let item_id = dragged_tab.item_id;
|
let item_id = dragged_tab.item_id;
|
||||||
let from_pane = dragged_tab.pane.clone();
|
let from_pane = dragged_tab.pane.clone();
|
||||||
let to_pane = cx.view().clone();
|
let to_pane = cx.view().clone();
|
||||||
self.workspace
|
self.workspace
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |_, cx| {
|
||||||
cx.defer(move |workspace, cx| {
|
cx.defer(move |workspace, cx| {
|
||||||
let item = from_pane
|
let pane = workspace.split_pane(to_pane, split_direction, cx);
|
||||||
|
workspace.move_item(from_pane, pane, item_id, 0, cx);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.log_err();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_split_project_entry_drop(
|
||||||
|
&mut self,
|
||||||
|
project_entry_id: &ProjectEntryId,
|
||||||
|
split_direction: SplitDirection,
|
||||||
|
cx: &mut ViewContext<'_, Pane>,
|
||||||
|
) {
|
||||||
|
let project_entry_id = *project_entry_id;
|
||||||
|
let current_pane = cx.view().clone();
|
||||||
|
self.workspace
|
||||||
|
.update(cx, |_, cx| {
|
||||||
|
cx.defer(move |workspace, cx| {
|
||||||
|
if let Some(path) = workspace
|
||||||
|
.project()
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.items()
|
.path_for_entry(project_entry_id, cx)
|
||||||
.find(|item| item.item_id() == item_id)
|
{
|
||||||
.map(|item| item.boxed_clone());
|
let pane = workspace.split_pane(current_pane, split_direction, cx);
|
||||||
if let Some(item) = item {
|
workspace
|
||||||
if let Some(item) = item.clone_on_split(workspace.database_id(), cx) {
|
.open_path(path, Some(pane.downgrade()), true, cx)
|
||||||
workspace.split_item(split_direction, item, cx);
|
.detach_and_log_err(cx);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
@ -1799,8 +1817,6 @@ impl Render for Pane {
|
||||||
type Element = Focusable<Div>;
|
type Element = Focusable<Div>;
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||||
let this = cx.view().downgrade();
|
|
||||||
|
|
||||||
v_stack()
|
v_stack()
|
||||||
.key_context("Pane")
|
.key_context("Pane")
|
||||||
.track_focus(&self.focus_handle)
|
.track_focus(&self.focus_handle)
|
||||||
|
@ -1894,11 +1910,13 @@ impl Render for Pane {
|
||||||
.full()
|
.full()
|
||||||
.z_index(1)
|
.z_index(1)
|
||||||
.drag_over::<DraggedTab>(|style| style.bg(drag_target_color))
|
.drag_over::<DraggedTab>(|style| style.bg(drag_target_color))
|
||||||
.on_drop(cx.listener(
|
.drag_over::<ProjectEntryId>(|style| style.bg(gpui::red()))
|
||||||
move |this, dragged_tab: &View<DraggedTab>, cx| {
|
.on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| {
|
||||||
this.handle_tab_drop(dragged_tab, this.active_item_index(), cx)
|
this.handle_tab_drop(dragged_tab, this.active_item_index(), cx)
|
||||||
},
|
}))
|
||||||
)),
|
.on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| {
|
||||||
|
this.handle_project_entry_drop(entry_id, cx)
|
||||||
|
})),
|
||||||
)
|
)
|
||||||
.children(
|
.children(
|
||||||
[
|
[
|
||||||
|
@ -1915,9 +1933,15 @@ impl Render for Pane {
|
||||||
.invisible()
|
.invisible()
|
||||||
.bg(drag_target_color)
|
.bg(drag_target_color)
|
||||||
.drag_over::<DraggedTab>(|style| style.visible())
|
.drag_over::<DraggedTab>(|style| style.visible())
|
||||||
|
.drag_over::<ProjectEntryId>(|style| style.visible())
|
||||||
|
.on_drop(cx.listener(move |this, dragged_tab: &DraggedTab, cx| {
|
||||||
|
this.handle_split_tab_drop(dragged_tab, direction, cx)
|
||||||
|
}))
|
||||||
.on_drop(cx.listener(
|
.on_drop(cx.listener(
|
||||||
move |this, dragged_tab: &View<DraggedTab>, cx| {
|
move |this, entry_id: &ProjectEntryId, cx| {
|
||||||
this.handle_split_tab_drop(dragged_tab, direction, cx)
|
this.handle_split_project_entry_drop(
|
||||||
|
entry_id, direction, cx,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
match direction {
|
match direction {
|
||||||
|
|
|
@ -16,7 +16,7 @@ const HANDLE_HITBOX_SIZE: f32 = 10.0; //todo!(change this back to 4)
|
||||||
const HORIZONTAL_MIN_SIZE: f32 = 80.;
|
const HORIZONTAL_MIN_SIZE: f32 = 80.;
|
||||||
const VERTICAL_MIN_SIZE: f32 = 100.;
|
const VERTICAL_MIN_SIZE: f32 = 100.;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone)]
|
||||||
pub struct PaneGroup {
|
pub struct PaneGroup {
|
||||||
pub(crate) root: Member,
|
pub(crate) root: Member,
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ impl PaneGroup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone)]
|
||||||
pub(crate) enum Member {
|
pub(crate) enum Member {
|
||||||
Axis(PaneAxis),
|
Axis(PaneAxis),
|
||||||
Pane(View<Pane>),
|
Pane(View<Pane>),
|
||||||
|
@ -426,12 +426,6 @@ pub(crate) struct PaneAxis {
|
||||||
pub bounding_boxes: Arc<Mutex<Vec<Option<Bounds<Pixels>>>>>,
|
pub bounding_boxes: Arc<Mutex<Vec<Option<Bounds<Pixels>>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for PaneAxis {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PaneAxis {
|
impl PaneAxis {
|
||||||
pub fn new(axis: Axis, members: Vec<Member>) -> Self {
|
pub fn new(axis: Axis, members: Vec<Member>) -> Self {
|
||||||
let flexes = Arc::new(Mutex::new(vec![1.; members.len()]));
|
let flexes = Arc::new(Mutex::new(vec![1.; members.len()]));
|
||||||
|
@ -816,7 +810,7 @@ mod element {
|
||||||
proposed_current_pixel_change -= current_pixel_change;
|
proposed_current_pixel_change -= current_pixel_change;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo!(reserialize workspace)
|
// todo!(schedule serialize)
|
||||||
// workspace.schedule_serialize(cx);
|
// workspace.schedule_serialize(cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
@ -851,7 +845,7 @@ mod element {
|
||||||
|
|
||||||
cx.on_mouse_event({
|
cx.on_mouse_event({
|
||||||
let dragged_handle = dragged_handle.clone();
|
let dragged_handle = dragged_handle.clone();
|
||||||
move |e: &MouseDownEvent, phase, cx| {
|
move |e: &MouseDownEvent, phase, _cx| {
|
||||||
if phase.bubble() && handle_bounds.contains(&e.position) {
|
if phase.bubble() && handle_bounds.contains(&e.position) {
|
||||||
dragged_handle.replace(Some(ix));
|
dragged_handle.replace(Some(ix));
|
||||||
}
|
}
|
||||||
|
@ -859,7 +853,7 @@ mod element {
|
||||||
});
|
});
|
||||||
cx.on_mouse_event(move |e: &MouseMoveEvent, phase, cx| {
|
cx.on_mouse_event(move |e: &MouseMoveEvent, phase, cx| {
|
||||||
let dragged_handle = dragged_handle.borrow();
|
let dragged_handle = dragged_handle.borrow();
|
||||||
if *dragged_handle == Some(ix) {
|
if phase.bubble() && *dragged_handle == Some(ix) {
|
||||||
Self::compute_resize(&flexes, e, ix, axis, axis_bounds, cx)
|
Self::compute_resize(&flexes, e, ix, axis, axis_bounds, cx)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -912,7 +906,7 @@ mod element {
|
||||||
let mut bounding_boxes = self.bounding_boxes.lock();
|
let mut bounding_boxes = self.bounding_boxes.lock();
|
||||||
bounding_boxes.clear();
|
bounding_boxes.clear();
|
||||||
|
|
||||||
for (ix, mut child) in self.children.iter_mut().enumerate() {
|
for (ix, child) in self.children.iter_mut().enumerate() {
|
||||||
//todo!(active_pane_magnification)
|
//todo!(active_pane_magnification)
|
||||||
// If usign active pane magnification, need to switch to using
|
// If usign active pane magnification, need to switch to using
|
||||||
// 1 for all non-active panes, and then the magnification for the
|
// 1 for all non-active panes, and then the magnification for the
|
||||||
|
@ -949,7 +943,7 @@ mod element {
|
||||||
cx.with_z_index(1, |cx| {
|
cx.with_z_index(1, |cx| {
|
||||||
cx.on_mouse_event({
|
cx.on_mouse_event({
|
||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
move |e: &MouseUpEvent, phase, cx| {
|
move |_: &MouseUpEvent, phase, _cx| {
|
||||||
if phase.bubble() {
|
if phase.bubble() {
|
||||||
state.replace(None);
|
state.replace(None);
|
||||||
}
|
}
|
||||||
|
@ -968,402 +962,4 @@ mod element {
|
||||||
fn flex_values_in_bounds(flexes: &[f32]) -> bool {
|
fn flex_values_in_bounds(flexes: &[f32]) -> bool {
|
||||||
(flexes.iter().copied().sum::<f32>() - flexes.len() as f32).abs() < 0.001
|
(flexes.iter().copied().sum::<f32>() - flexes.len() as f32).abs() < 0.001
|
||||||
}
|
}
|
||||||
// // use std::{cell::RefCell, iter::from_fn, ops::Range, rc::Rc};
|
|
||||||
|
|
||||||
// // use gpui::{
|
|
||||||
// // geometry::{
|
|
||||||
// // rect::Bounds<Pixels>,
|
|
||||||
// // vector::{vec2f, Vector2F},
|
|
||||||
// // },
|
|
||||||
// // json::{self, ToJson},
|
|
||||||
// // platform::{CursorStyle, MouseButton},
|
|
||||||
// // scene::MouseDrag,
|
|
||||||
// // AnyElement, Axis, CursorRegion, Element, EventContext, MouseRegion, Bounds<Pixels>Ext,
|
|
||||||
// // SizeConstraint, Vector2FExt, ViewContext,
|
|
||||||
// // };
|
|
||||||
|
|
||||||
// use crate::{
|
|
||||||
// pane_group::{HANDLE_HITBOX_SIZE, HORIZONTAL_MIN_SIZE, VERTICAL_MIN_SIZE},
|
|
||||||
// Workspace, WorkspaceSettings,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// pub struct PaneAxisElement {
|
|
||||||
// axis: Axis,
|
|
||||||
// basis: usize,
|
|
||||||
// active_pane_ix: Option<usize>,
|
|
||||||
// flexes: Rc<RefCell<Vec<f32>>>,
|
|
||||||
// children: Vec<AnyElement<Workspace>>,
|
|
||||||
// bounding_boxes: Rc<RefCell<Vec<Option<Bounds<Pixels>>>>>,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl PaneAxisElement {
|
|
||||||
// pub fn new(
|
|
||||||
// axis: Axis,
|
|
||||||
// basis: usize,
|
|
||||||
// flexes: Rc<RefCell<Vec<f32>>>,
|
|
||||||
// bounding_boxes: Rc<RefCell<Vec<Option<Bounds<Pixels>>>>>,
|
|
||||||
// ) -> Self {
|
|
||||||
// Self {
|
|
||||||
// axis,
|
|
||||||
// basis,
|
|
||||||
// flexes,
|
|
||||||
// bounding_boxes,
|
|
||||||
// active_pane_ix: None,
|
|
||||||
// children: Default::default(),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn set_active_pane(&mut self, active_pane_ix: Option<usize>) {
|
|
||||||
// self.active_pane_ix = active_pane_ix;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn layout_children(
|
|
||||||
// &mut self,
|
|
||||||
// active_pane_magnification: f32,
|
|
||||||
// constraint: SizeConstraint,
|
|
||||||
// remaining_space: &mut f32,
|
|
||||||
// remaining_flex: &mut f32,
|
|
||||||
// cross_axis_max: &mut f32,
|
|
||||||
// view: &mut Workspace,
|
|
||||||
// cx: &mut ViewContext<Workspace>,
|
|
||||||
// ) {
|
|
||||||
// let flexes = self.flexes.borrow();
|
|
||||||
// let cross_axis = self.axis.invert();
|
|
||||||
// for (ix, child) in self.children.iter_mut().enumerate() {
|
|
||||||
// let flex = if active_pane_magnification != 1. {
|
|
||||||
// if let Some(active_pane_ix) = self.active_pane_ix {
|
|
||||||
// if ix == active_pane_ix {
|
|
||||||
// active_pane_magnification
|
|
||||||
// } else {
|
|
||||||
// 1.
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// 1.
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// flexes[ix]
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let child_size = if *remaining_flex == 0.0 {
|
|
||||||
// *remaining_space
|
|
||||||
// } else {
|
|
||||||
// let space_per_flex = *remaining_space / *remaining_flex;
|
|
||||||
// space_per_flex * flex
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let child_constraint = match self.axis {
|
|
||||||
// Axis::Horizontal => SizeConstraint::new(
|
|
||||||
// vec2f(child_size, constraint.min.y()),
|
|
||||||
// vec2f(child_size, constraint.max.y()),
|
|
||||||
// ),
|
|
||||||
// Axis::Vertical => SizeConstraint::new(
|
|
||||||
// vec2f(constraint.min.x(), child_size),
|
|
||||||
// vec2f(constraint.max.x(), child_size),
|
|
||||||
// ),
|
|
||||||
// };
|
|
||||||
// let child_size = child.layout(child_constraint, view, cx);
|
|
||||||
// *remaining_space -= child_size.along(self.axis);
|
|
||||||
// *remaining_flex -= flex;
|
|
||||||
// *cross_axis_max = cross_axis_max.max(child_size.along(cross_axis));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn handle_resize(
|
|
||||||
// flexes: Rc<RefCell<Vec<f32>>>,
|
|
||||||
// axis: Axis,
|
|
||||||
// preceding_ix: usize,
|
|
||||||
// child_start: Vector2F,
|
|
||||||
// drag_bounds: Bounds<Pixels>,
|
|
||||||
// ) -> impl Fn(MouseDrag, &mut Workspace, &mut EventContext<Workspace>) {
|
|
||||||
// let size = move |ix, flexes: &[f32]| {
|
|
||||||
// drag_bounds.length_along(axis) * (flexes[ix] / flexes.len() as f32)
|
|
||||||
// };
|
|
||||||
|
|
||||||
// move |drag, workspace: &mut Workspace, cx| {
|
|
||||||
// if drag.end {
|
|
||||||
// // TODO: Clear cascading resize state
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// let min_size = match axis {
|
|
||||||
// Axis::Horizontal => HORIZONTAL_MIN_SIZE,
|
|
||||||
// Axis::Vertical => VERTICAL_MIN_SIZE,
|
|
||||||
// };
|
|
||||||
// let mut flexes = flexes.borrow_mut();
|
|
||||||
|
|
||||||
// // Don't allow resizing to less than the minimum size, if elements are already too small
|
|
||||||
// if min_size - 1. > size(preceding_ix, flexes.as_slice()) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let mut proposed_current_pixel_change = (drag.position - child_start).along(axis)
|
|
||||||
// - size(preceding_ix, flexes.as_slice());
|
|
||||||
|
|
||||||
// let flex_changes = |pixel_dx, target_ix, next: isize, flexes: &[f32]| {
|
|
||||||
// let flex_change = pixel_dx / drag_bounds.length_along(axis);
|
|
||||||
// let current_target_flex = flexes[target_ix] + flex_change;
|
|
||||||
// let next_target_flex =
|
|
||||||
// flexes[(target_ix as isize + next) as usize] - flex_change;
|
|
||||||
// (current_target_flex, next_target_flex)
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let mut successors = from_fn({
|
|
||||||
// let forward = proposed_current_pixel_change > 0.;
|
|
||||||
// let mut ix_offset = 0;
|
|
||||||
// let len = flexes.len();
|
|
||||||
// move || {
|
|
||||||
// let result = if forward {
|
|
||||||
// (preceding_ix + 1 + ix_offset < len).then(|| preceding_ix + ix_offset)
|
|
||||||
// } else {
|
|
||||||
// (preceding_ix as isize - ix_offset as isize >= 0)
|
|
||||||
// .then(|| preceding_ix - ix_offset)
|
|
||||||
// };
|
|
||||||
|
|
||||||
// ix_offset += 1;
|
|
||||||
|
|
||||||
// result
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// while proposed_current_pixel_change.abs() > 0. {
|
|
||||||
// let Some(current_ix) = successors.next() else {
|
|
||||||
// break;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let next_target_size = f32::max(
|
|
||||||
// size(current_ix + 1, flexes.as_slice()) - proposed_current_pixel_change,
|
|
||||||
// min_size,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let current_target_size = f32::max(
|
|
||||||
// size(current_ix, flexes.as_slice())
|
|
||||||
// + size(current_ix + 1, flexes.as_slice())
|
|
||||||
// - next_target_size,
|
|
||||||
// min_size,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let current_pixel_change =
|
|
||||||
// current_target_size - size(current_ix, flexes.as_slice());
|
|
||||||
|
|
||||||
// let (current_target_flex, next_target_flex) =
|
|
||||||
// flex_changes(current_pixel_change, current_ix, 1, flexes.as_slice());
|
|
||||||
|
|
||||||
// flexes[current_ix] = current_target_flex;
|
|
||||||
// flexes[current_ix + 1] = next_target_flex;
|
|
||||||
|
|
||||||
// proposed_current_pixel_change -= current_pixel_change;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// workspace.schedule_serialize(cx);
|
|
||||||
// cx.notify();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl Extend<AnyElement<Workspace>> for PaneAxisElement {
|
|
||||||
// fn extend<T: IntoIterator<Item = AnyElement<Workspace>>>(&mut self, children: T) {
|
|
||||||
// self.children.extend(children);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl Element<Workspace> for PaneAxisElement {
|
|
||||||
// type LayoutState = f32;
|
|
||||||
// type PaintState = ();
|
|
||||||
|
|
||||||
// fn layout(
|
|
||||||
// &mut self,
|
|
||||||
// constraint: SizeConstraint,
|
|
||||||
// view: &mut Workspace,
|
|
||||||
// cx: &mut ViewContext<Workspace>,
|
|
||||||
// ) -> (Vector2F, Self::LayoutState) {
|
|
||||||
// debug_assert!(self.children.len() == self.flexes.borrow().len());
|
|
||||||
|
|
||||||
// let active_pane_magnification =
|
|
||||||
// settings::get::<WorkspaceSettings>(cx).active_pane_magnification;
|
|
||||||
|
|
||||||
// let mut remaining_flex = 0.;
|
|
||||||
|
|
||||||
// if active_pane_magnification != 1. {
|
|
||||||
// let active_pane_flex = self
|
|
||||||
// .active_pane_ix
|
|
||||||
// .map(|_| active_pane_magnification)
|
|
||||||
// .unwrap_or(1.);
|
|
||||||
// remaining_flex += self.children.len() as f32 - 1. + active_pane_flex;
|
|
||||||
// } else {
|
|
||||||
// for flex in self.flexes.borrow().iter() {
|
|
||||||
// remaining_flex += flex;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let mut cross_axis_max: f32 = 0.0;
|
|
||||||
// let mut remaining_space = constraint.max_along(self.axis);
|
|
||||||
|
|
||||||
// if remaining_space.is_infinite() {
|
|
||||||
// panic!("flex contains flexible children but has an infinite constraint along the flex axis");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// self.layout_children(
|
|
||||||
// active_pane_magnification,
|
|
||||||
// constraint,
|
|
||||||
// &mut remaining_space,
|
|
||||||
// &mut remaining_flex,
|
|
||||||
// &mut cross_axis_max,
|
|
||||||
// view,
|
|
||||||
// cx,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let mut size = match self.axis {
|
|
||||||
// Axis::Horizontal => vec2f(constraint.max.x() - remaining_space, cross_axis_max),
|
|
||||||
// Axis::Vertical => vec2f(cross_axis_max, constraint.max.y() - remaining_space),
|
|
||||||
// };
|
|
||||||
|
|
||||||
// if constraint.min.x().is_finite() {
|
|
||||||
// size.set_x(size.x().max(constraint.min.x()));
|
|
||||||
// }
|
|
||||||
// if constraint.min.y().is_finite() {
|
|
||||||
// size.set_y(size.y().max(constraint.min.y()));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if size.x() > constraint.max.x() {
|
|
||||||
// size.set_x(constraint.max.x());
|
|
||||||
// }
|
|
||||||
// if size.y() > constraint.max.y() {
|
|
||||||
// size.set_y(constraint.max.y());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// (size, remaining_space)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn paint(
|
|
||||||
// &mut self,
|
|
||||||
// bounds: Bounds<Pixels>,
|
|
||||||
// visible_bounds: Bounds<Pixels>,
|
|
||||||
// remaining_space: &mut Self::LayoutState,
|
|
||||||
// view: &mut Workspace,
|
|
||||||
// cx: &mut ViewContext<Workspace>,
|
|
||||||
// ) -> Self::PaintState {
|
|
||||||
// let can_resize = settings::get::<WorkspaceSettings>(cx).active_pane_magnification == 1.;
|
|
||||||
// let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
|
|
||||||
|
|
||||||
// let overflowing = *remaining_space < 0.;
|
|
||||||
// if overflowing {
|
|
||||||
// cx.scene().push_layer(Some(visible_bounds));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let mut child_origin = bounds.origin();
|
|
||||||
|
|
||||||
// let mut bounding_boxes = self.bounding_boxes.borrow_mut();
|
|
||||||
// bounding_boxes.clear();
|
|
||||||
|
|
||||||
// let mut children_iter = self.children.iter_mut().enumerate().peekable();
|
|
||||||
// while let Some((ix, child)) = children_iter.next() {
|
|
||||||
// let child_start = child_origin.clone();
|
|
||||||
// child.paint(child_origin, visible_bounds, view, cx);
|
|
||||||
|
|
||||||
// bounding_boxes.push(Some(Bounds<Pixels>::new(child_origin, child.size())));
|
|
||||||
|
|
||||||
// match self.axis {
|
|
||||||
// Axis::Horizontal => child_origin += vec2f(child.size().x(), 0.0),
|
|
||||||
// Axis::Vertical => child_origin += vec2f(0.0, child.size().y()),
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if can_resize && children_iter.peek().is_some() {
|
|
||||||
// cx.scene().push_stacking_context(None, None);
|
|
||||||
|
|
||||||
// let handle_origin = match self.axis {
|
|
||||||
// Axis::Horizontal => child_origin - vec2f(HANDLE_HITBOX_SIZE / 2., 0.0),
|
|
||||||
// Axis::Vertical => child_origin - vec2f(0.0, HANDLE_HITBOX_SIZE / 2.),
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let handle_bounds = match self.axis {
|
|
||||||
// Axis::Horizontal => Bounds<Pixels>::new(
|
|
||||||
// handle_origin,
|
|
||||||
// vec2f(HANDLE_HITBOX_SIZE, visible_bounds.height()),
|
|
||||||
// ),
|
|
||||||
// Axis::Vertical => Bounds<Pixels>::new(
|
|
||||||
// handle_origin,
|
|
||||||
// vec2f(visible_bounds.width(), HANDLE_HITBOX_SIZE),
|
|
||||||
// ),
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let style = match self.axis {
|
|
||||||
// Axis::Horizontal => CursorStyle::ResizeLeftRight,
|
|
||||||
// Axis::Vertical => CursorStyle::ResizeUpDown,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// cx.scene().push_cursor_region(CursorRegion {
|
|
||||||
// bounds: handle_bounds,
|
|
||||||
// style,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// enum ResizeHandle {}
|
|
||||||
// let mut mouse_region = MouseRegion::new::<ResizeHandle>(
|
|
||||||
// cx.view_id(),
|
|
||||||
// self.basis + ix,
|
|
||||||
// handle_bounds,
|
|
||||||
// );
|
|
||||||
// mouse_region = mouse_region
|
|
||||||
// .on_drag(
|
|
||||||
// MouseButton::Left,
|
|
||||||
// Self::handle_resize(
|
|
||||||
// self.flexes.clone(),
|
|
||||||
// self.axis,
|
|
||||||
// ix,
|
|
||||||
// child_start,
|
|
||||||
// visible_bounds.clone(),
|
|
||||||
// ),
|
|
||||||
// )
|
|
||||||
// .on_click(MouseButton::Left, {
|
|
||||||
// let flexes = self.flexes.clone();
|
|
||||||
// move |e, v: &mut Workspace, cx| {
|
|
||||||
// if e.click_count >= 2 {
|
|
||||||
// let mut borrow = flexes.borrow_mut();
|
|
||||||
// *borrow = vec![1.; borrow.len()];
|
|
||||||
// v.schedule_serialize(cx);
|
|
||||||
// cx.notify();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// cx.scene().push_mouse_region(mouse_region);
|
|
||||||
|
|
||||||
// cx.scene().pop_stacking_context();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if overflowing {
|
|
||||||
// cx.scene().pop_layer();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn rect_for_text_range(
|
|
||||||
// &self,
|
|
||||||
// range_utf16: Range<usize>,
|
|
||||||
// _: Bounds<Pixels>,
|
|
||||||
// _: Bounds<Pixels>,
|
|
||||||
// _: &Self::LayoutState,
|
|
||||||
// _: &Self::PaintState,
|
|
||||||
// view: &Workspace,
|
|
||||||
// cx: &ViewContext<Workspace>,
|
|
||||||
// ) -> Option<Bounds<Pixels>> {
|
|
||||||
// self.children
|
|
||||||
// .iter()
|
|
||||||
// .find_map(|child| child.rect_for_text_range(range_utf16.clone(), view, cx))
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn debug(
|
|
||||||
// &self,
|
|
||||||
// bounds: Bounds<Pixels>,
|
|
||||||
// _: &Self::LayoutState,
|
|
||||||
// _: &Self::PaintState,
|
|
||||||
// view: &Workspace,
|
|
||||||
// cx: &ViewContext<Workspace>,
|
|
||||||
// ) -> json::Value {
|
|
||||||
// serde_json::json!({
|
|
||||||
// "type": "PaneAxis",
|
|
||||||
// "bounds": bounds.to_json(),
|
|
||||||
// "axis": self.axis.to_json(),
|
|
||||||
// "flexes": *self.flexes.borrow(),
|
|
||||||
// "children": self.children.iter().map(|child| child.debug(view, cx)).collect::<Vec<json::Value>>()
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,7 +193,7 @@ impl<T: SearchableItem> SearchableItemHandle for View<T> {
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
) -> Task<Vec<Box<dyn Any + Send>>> {
|
) -> Task<Vec<Box<dyn Any + Send>>> {
|
||||||
let matches = self.update(cx, |this, cx| this.find_matches(query, cx));
|
let matches = self.update(cx, |this, cx| this.find_matches(query, cx));
|
||||||
cx.spawn(|cx| async {
|
cx.spawn(|_| async {
|
||||||
let matches = matches.await;
|
let matches = matches.await;
|
||||||
matches
|
matches
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -253,7 +253,7 @@ pub trait WeakSearchableItemHandle: WeakItemHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: SearchableItem> WeakSearchableItemHandle for WeakView<T> {
|
impl<T: SearchableItem> WeakSearchableItemHandle for WeakView<T> {
|
||||||
fn upgrade(&self, cx: &AppContext) -> Option<Box<dyn SearchableItemHandle>> {
|
fn upgrade(&self, _cx: &AppContext) -> Option<Box<dyn SearchableItemHandle>> {
|
||||||
Some(Box::new(self.upgrade()?))
|
Some(Box::new(self.upgrade()?))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,14 +51,14 @@ impl Render for StatusBar {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StatusBar {
|
impl StatusBar {
|
||||||
fn render_left_tools(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
fn render_left_tools(&self, _: &mut ViewContext<Self>) -> impl IntoElement {
|
||||||
h_stack()
|
h_stack()
|
||||||
.items_center()
|
.items_center()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.children(self.left_items.iter().map(|item| item.to_any()))
|
.children(self.left_items.iter().map(|item| item.to_any()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_right_tools(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
fn render_right_tools(&self, _: &mut ViewContext<Self>) -> impl IntoElement {
|
||||||
h_stack()
|
h_stack()
|
||||||
.items_center()
|
.items_center()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
|
|
|
@ -109,8 +109,22 @@ impl Render for Toolbar {
|
||||||
.child(
|
.child(
|
||||||
h_stack()
|
h_stack()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
.child(h_stack().children(self.left_items().map(|item| item.to_any())))
|
.when(self.left_items().count() > 0, |this| {
|
||||||
.child(h_stack().children(self.right_items().map(|item| item.to_any()))),
|
this.child(
|
||||||
|
h_stack()
|
||||||
|
.flex_1()
|
||||||
|
.justify_start()
|
||||||
|
.children(self.left_items().map(|item| item.to_any())),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.when(self.right_items().count() > 0, |this| {
|
||||||
|
this.child(
|
||||||
|
h_stack()
|
||||||
|
.flex_1()
|
||||||
|
.justify_end()
|
||||||
|
.children(self.right_items().map(|item| item.to_any())),
|
||||||
|
)
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.children(secondary_item)
|
.children(secondary_item)
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue