Uncomment last tests (#4009)
With this, we're done all known things that need porting. Release Notes: -
This commit is contained in:
@@ -525,43 +525,4 @@ impl Render for FeedbackModal {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Testing of various button states, dismissal prompts, etc.
|
||||
|
||||
// #[cfg(test)]
|
||||
// mod test {
|
||||
// use super::*;
|
||||
|
||||
// #[test]
|
||||
// fn test_invalid_email_addresses() {
|
||||
// let markdown = markdown.await.log_err();
|
||||
// let buffer = project.update(&mut cx, |project, cx| {
|
||||
// project.create_buffer("", markdown, cx)
|
||||
// })??;
|
||||
|
||||
// workspace.update(&mut cx, |workspace, cx| {
|
||||
// let system_specs = SystemSpecs::new(cx);
|
||||
|
||||
// workspace.toggle_modal(cx, move |cx| {
|
||||
// let feedback_modal = FeedbackModal::new(system_specs, project, buffer, cx);
|
||||
|
||||
// assert!(!feedback_modal.can_submit());
|
||||
// assert!(!feedback_modal.valid_email_address(cx));
|
||||
// assert!(!feedback_modal.valid_character_count());
|
||||
|
||||
// feedback_modal
|
||||
// .email_address_editor
|
||||
// .update(cx, |this, cx| this.set_text("a", cx));
|
||||
// feedback_modal.set_submission_state(cx);
|
||||
|
||||
// assert!(!feedback_modal.valid_email_address(cx));
|
||||
|
||||
// feedback_modal
|
||||
// .email_address_editor
|
||||
// .update(cx, |this, cx| this.set_text("a&b.com", cx));
|
||||
// feedback_modal.set_submission_state(cx);
|
||||
|
||||
// assert!(feedback_modal.valid_email_address(cx));
|
||||
// });
|
||||
// })?;
|
||||
// }
|
||||
// }
|
||||
// TODO: Testing of various button states, dismissal prompts, etc. :)
|
||||
|
||||
@@ -170,7 +170,7 @@ impl ActionRegistry {
|
||||
macro_rules! actions {
|
||||
($namespace:path, [ $($name:ident),* $(,)? ]) => {
|
||||
$(
|
||||
#[derive(::std::cmp::PartialEq, ::std::clone::Clone, ::std::default::Default, gpui::private::serde_derive::Deserialize)]
|
||||
#[derive(::std::cmp::PartialEq, ::std::clone::Clone, ::std::default::Default, ::std::fmt::Debug, gpui::private::serde_derive::Deserialize)]
|
||||
#[serde(crate = "gpui::private::serde")]
|
||||
pub struct $name;
|
||||
|
||||
|
||||
+320
-315
@@ -28,11 +28,11 @@ impl KeystrokeMatcher {
|
||||
|
||||
/// Pushes a keystroke onto the matcher.
|
||||
/// The result of the new keystroke is returned:
|
||||
/// KeyMatch::None =>
|
||||
/// - KeyMatch::None =>
|
||||
/// No match is valid for this key given any pending keystrokes.
|
||||
/// KeyMatch::Pending =>
|
||||
/// - KeyMatch::Pending =>
|
||||
/// There exist bindings which are still waiting for more keys.
|
||||
/// KeyMatch::Complete(matches) =>
|
||||
/// - KeyMatch::Complete(matches) =>
|
||||
/// One or more bindings have received the necessary key presses.
|
||||
/// Bindings added later will take precedence over earlier bindings.
|
||||
pub fn match_keystroke(
|
||||
@@ -77,12 +77,10 @@ impl KeystrokeMatcher {
|
||||
|
||||
if let Some(pending_key) = pending_key {
|
||||
self.pending_keystrokes.push(pending_key);
|
||||
}
|
||||
|
||||
if self.pending_keystrokes.is_empty() {
|
||||
KeyMatch::None
|
||||
} else {
|
||||
KeyMatch::Pending
|
||||
} else {
|
||||
self.pending_keystrokes.clear();
|
||||
KeyMatch::None
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,367 +96,374 @@ impl KeyMatch {
|
||||
pub fn is_some(&self) -> bool {
|
||||
matches!(self, KeyMatch::Some(_))
|
||||
}
|
||||
|
||||
pub fn matches(self) -> Option<Vec<Box<dyn Action>>> {
|
||||
match self {
|
||||
KeyMatch::Some(matches) => Some(matches),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #[cfg(test)]
|
||||
// mod tests {
|
||||
// use anyhow::Result;
|
||||
// use serde::Deserialize;
|
||||
impl PartialEq for KeyMatch {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(KeyMatch::None, KeyMatch::None) => true,
|
||||
(KeyMatch::Pending, KeyMatch::Pending) => true,
|
||||
(KeyMatch::Some(a), KeyMatch::Some(b)) => {
|
||||
if a.len() != b.len() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// use crate::{actions, impl_actions, keymap_matcher::ActionContext};
|
||||
for (a, b) in a.iter().zip(b.iter()) {
|
||||
if !a.partial_eq(b.as_ref()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// use super::*;
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn test_keymap_and_view_ordering() -> Result<()> {
|
||||
// actions!(test, [EditorAction, ProjectPanelAction]);
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
// let mut editor = ActionContext::default();
|
||||
// editor.add_identifier("Editor");
|
||||
use serde_derive::Deserialize;
|
||||
|
||||
// let mut project_panel = ActionContext::default();
|
||||
// project_panel.add_identifier("ProjectPanel");
|
||||
use super::*;
|
||||
use crate::{self as gpui, KeyBindingContextPredicate, Modifiers};
|
||||
use crate::{actions, KeyBinding};
|
||||
|
||||
// // Editor 'deeper' in than project panel
|
||||
// let dispatch_path = vec![(2, editor), (1, project_panel)];
|
||||
#[test]
|
||||
fn test_keymap_and_view_ordering() {
|
||||
actions!(test, [EditorAction, ProjectPanelAction]);
|
||||
|
||||
// // But editor actions 'higher' up in keymap
|
||||
// let keymap = Keymap::new(vec![
|
||||
// Binding::new("left", EditorAction, Some("Editor")),
|
||||
// Binding::new("left", ProjectPanelAction, Some("ProjectPanel")),
|
||||
// ]);
|
||||
let mut editor = KeyContext::default();
|
||||
editor.add("Editor");
|
||||
|
||||
// let mut matcher = KeymapMatcher::new(keymap);
|
||||
let mut project_panel = KeyContext::default();
|
||||
project_panel.add("ProjectPanel");
|
||||
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("left")?, dispatch_path.clone()),
|
||||
// KeyMatch::Matches(vec![
|
||||
// (2, Box::new(EditorAction)),
|
||||
// (1, Box::new(ProjectPanelAction)),
|
||||
// ]),
|
||||
// );
|
||||
// Editor 'deeper' in than project panel
|
||||
let dispatch_path = vec![project_panel, editor];
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
// But editor actions 'higher' up in keymap
|
||||
let keymap = Keymap::new(vec![
|
||||
KeyBinding::new("left", EditorAction, Some("Editor")),
|
||||
KeyBinding::new("left", ProjectPanelAction, Some("ProjectPanel")),
|
||||
]);
|
||||
|
||||
// #[test]
|
||||
// fn test_push_keystroke() -> Result<()> {
|
||||
// actions!(test, [B, AB, C, D, DA, E, EF]);
|
||||
let mut matcher = KeystrokeMatcher::new(Arc::new(Mutex::new(keymap)));
|
||||
|
||||
// let mut context1 = ActionContext::default();
|
||||
// context1.add_identifier("1");
|
||||
let matches = matcher
|
||||
.match_keystroke(&Keystroke::parse("left").unwrap(), &dispatch_path)
|
||||
.matches()
|
||||
.unwrap();
|
||||
|
||||
// let mut context2 = ActionContext::default();
|
||||
// context2.add_identifier("2");
|
||||
assert!(matches[0].partial_eq(&EditorAction));
|
||||
assert!(matches.get(1).is_none());
|
||||
}
|
||||
|
||||
// let dispatch_path = vec![(2, context2), (1, context1)];
|
||||
#[test]
|
||||
fn test_multi_keystroke_match() {
|
||||
actions!(test, [B, AB, C, D, DA, E, EF]);
|
||||
|
||||
// let keymap = Keymap::new(vec![
|
||||
// Binding::new("a b", AB, Some("1")),
|
||||
// Binding::new("b", B, Some("2")),
|
||||
// Binding::new("c", C, Some("2")),
|
||||
// Binding::new("d", D, Some("1")),
|
||||
// Binding::new("d", D, Some("2")),
|
||||
// Binding::new("d a", DA, Some("2")),
|
||||
// ]);
|
||||
let mut context1 = KeyContext::default();
|
||||
context1.add("1");
|
||||
|
||||
// let mut matcher = KeymapMatcher::new(keymap);
|
||||
let mut context2 = KeyContext::default();
|
||||
context2.add("2");
|
||||
|
||||
// // Binding with pending prefix always takes precedence
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("a")?, dispatch_path.clone()),
|
||||
// KeyMatch::Pending,
|
||||
// );
|
||||
// // B alone doesn't match because a was pending, so AB is returned instead
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("b")?, dispatch_path.clone()),
|
||||
// KeyMatch::Matches(vec![(1, Box::new(AB))]),
|
||||
// );
|
||||
// assert!(!matcher.has_pending_keystrokes());
|
||||
let dispatch_path = vec![context2, context1];
|
||||
|
||||
// // Without an a prefix, B is dispatched like expected
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("b")?, dispatch_path.clone()),
|
||||
// KeyMatch::Matches(vec![(2, Box::new(B))]),
|
||||
// );
|
||||
// assert!(!matcher.has_pending_keystrokes());
|
||||
let keymap = Keymap::new(vec![
|
||||
KeyBinding::new("a b", AB, Some("1")),
|
||||
KeyBinding::new("b", B, Some("2")),
|
||||
KeyBinding::new("c", C, Some("2")),
|
||||
KeyBinding::new("d", D, Some("1")),
|
||||
KeyBinding::new("d", D, Some("2")),
|
||||
KeyBinding::new("d a", DA, Some("2")),
|
||||
]);
|
||||
|
||||
// // If a is prefixed, C will not be dispatched because there
|
||||
// // was a pending binding for it
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("a")?, dispatch_path.clone()),
|
||||
// KeyMatch::Pending,
|
||||
// );
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("c")?, dispatch_path.clone()),
|
||||
// KeyMatch::None,
|
||||
// );
|
||||
// assert!(!matcher.has_pending_keystrokes());
|
||||
let mut matcher = KeystrokeMatcher::new(Arc::new(Mutex::new(keymap)));
|
||||
|
||||
// // If a single keystroke matches multiple bindings in the tree
|
||||
// // all of them are returned so that we can fallback if the action
|
||||
// // handler decides to propagate the action
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("d")?, dispatch_path.clone()),
|
||||
// KeyMatch::Matches(vec![(2, Box::new(D)), (1, Box::new(D))]),
|
||||
// );
|
||||
// Binding with pending prefix always takes precedence
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("a").unwrap(), &dispatch_path),
|
||||
KeyMatch::Pending,
|
||||
);
|
||||
// B alone doesn't match because a was pending, so AB is returned instead
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("b").unwrap(), &dispatch_path),
|
||||
KeyMatch::Some(vec![Box::new(AB)]),
|
||||
);
|
||||
assert!(!matcher.has_pending_keystrokes());
|
||||
|
||||
// // If none of the d action handlers consume the binding, a pending
|
||||
// // binding may then be used
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("a")?, dispatch_path.clone()),
|
||||
// KeyMatch::Matches(vec![(2, Box::new(DA))]),
|
||||
// );
|
||||
// assert!(!matcher.has_pending_keystrokes());
|
||||
// Without an a prefix, B is dispatched like expected
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("b").unwrap(), &dispatch_path[0..1]),
|
||||
KeyMatch::Some(vec![Box::new(B)]),
|
||||
);
|
||||
assert!(!matcher.has_pending_keystrokes());
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
eprintln!("PROBLEM AREA");
|
||||
// If a is prefixed, C will not be dispatched because there
|
||||
// was a pending binding for it
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("a").unwrap(), &dispatch_path),
|
||||
KeyMatch::Pending,
|
||||
);
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("c").unwrap(), &dispatch_path),
|
||||
KeyMatch::None,
|
||||
);
|
||||
assert!(!matcher.has_pending_keystrokes());
|
||||
|
||||
// #[test]
|
||||
// fn test_keystroke_parsing() -> Result<()> {
|
||||
// assert_eq!(
|
||||
// Keystroke::parse("ctrl-p")?,
|
||||
// Keystroke {
|
||||
// key: "p".into(),
|
||||
// ctrl: true,
|
||||
// alt: false,
|
||||
// shift: false,
|
||||
// cmd: false,
|
||||
// function: false,
|
||||
// ime_key: None,
|
||||
// }
|
||||
// );
|
||||
// If a single keystroke matches multiple bindings in the tree
|
||||
// only one of them is returned.
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("d").unwrap(), &dispatch_path),
|
||||
KeyMatch::Some(vec![Box::new(D)]),
|
||||
);
|
||||
}
|
||||
|
||||
// assert_eq!(
|
||||
// Keystroke::parse("alt-shift-down")?,
|
||||
// Keystroke {
|
||||
// key: "down".into(),
|
||||
// ctrl: false,
|
||||
// alt: true,
|
||||
// shift: true,
|
||||
// cmd: false,
|
||||
// function: false,
|
||||
// ime_key: None,
|
||||
// }
|
||||
// );
|
||||
#[test]
|
||||
fn test_keystroke_parsing() {
|
||||
assert_eq!(
|
||||
Keystroke::parse("ctrl-p").unwrap(),
|
||||
Keystroke {
|
||||
key: "p".into(),
|
||||
modifiers: Modifiers {
|
||||
control: true,
|
||||
alt: false,
|
||||
shift: false,
|
||||
command: false,
|
||||
function: false,
|
||||
},
|
||||
ime_key: None,
|
||||
}
|
||||
);
|
||||
|
||||
// assert_eq!(
|
||||
// Keystroke::parse("shift-cmd--")?,
|
||||
// Keystroke {
|
||||
// key: "-".into(),
|
||||
// ctrl: false,
|
||||
// alt: false,
|
||||
// shift: true,
|
||||
// cmd: true,
|
||||
// function: false,
|
||||
// ime_key: None,
|
||||
// }
|
||||
// );
|
||||
assert_eq!(
|
||||
Keystroke::parse("alt-shift-down").unwrap(),
|
||||
Keystroke {
|
||||
key: "down".into(),
|
||||
modifiers: Modifiers {
|
||||
control: false,
|
||||
alt: true,
|
||||
shift: true,
|
||||
command: false,
|
||||
function: false,
|
||||
},
|
||||
ime_key: None,
|
||||
}
|
||||
);
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
assert_eq!(
|
||||
Keystroke::parse("shift-cmd--").unwrap(),
|
||||
Keystroke {
|
||||
key: "-".into(),
|
||||
modifiers: Modifiers {
|
||||
control: false,
|
||||
alt: false,
|
||||
shift: true,
|
||||
command: true,
|
||||
function: false,
|
||||
},
|
||||
ime_key: None,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn test_context_predicate_parsing() -> Result<()> {
|
||||
// use KeymapContextPredicate::*;
|
||||
#[test]
|
||||
fn test_context_predicate_parsing() {
|
||||
use KeyBindingContextPredicate::*;
|
||||
|
||||
// assert_eq!(
|
||||
// KeymapContextPredicate::parse("a && (b == c || d != e)")?,
|
||||
// And(
|
||||
// Box::new(Identifier("a".into())),
|
||||
// Box::new(Or(
|
||||
// Box::new(Equal("b".into(), "c".into())),
|
||||
// Box::new(NotEqual("d".into(), "e".into())),
|
||||
// ))
|
||||
// )
|
||||
// );
|
||||
assert_eq!(
|
||||
KeyBindingContextPredicate::parse("a && (b == c || d != e)").unwrap(),
|
||||
And(
|
||||
Box::new(Identifier("a".into())),
|
||||
Box::new(Or(
|
||||
Box::new(Equal("b".into(), "c".into())),
|
||||
Box::new(NotEqual("d".into(), "e".into())),
|
||||
))
|
||||
)
|
||||
);
|
||||
|
||||
// assert_eq!(
|
||||
// KeymapContextPredicate::parse("!a")?,
|
||||
// Not(Box::new(Identifier("a".into())),)
|
||||
// );
|
||||
assert_eq!(
|
||||
KeyBindingContextPredicate::parse("!a").unwrap(),
|
||||
Not(Box::new(Identifier("a".into())),)
|
||||
);
|
||||
}
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
#[test]
|
||||
fn test_context_predicate_eval() {
|
||||
let predicate = KeyBindingContextPredicate::parse("a && b || c == d").unwrap();
|
||||
|
||||
// #[test]
|
||||
// fn test_context_predicate_eval() {
|
||||
// let predicate = KeymapContextPredicate::parse("a && b || c == d").unwrap();
|
||||
let mut context = KeyContext::default();
|
||||
context.add("a");
|
||||
assert!(!predicate.eval(&[context]));
|
||||
|
||||
// let mut context = ActionContext::default();
|
||||
// context.add_identifier("a");
|
||||
// assert!(!predicate.eval(&[context]));
|
||||
let mut context = KeyContext::default();
|
||||
context.add("a");
|
||||
context.add("b");
|
||||
assert!(predicate.eval(&[context]));
|
||||
|
||||
// let mut context = ActionContext::default();
|
||||
// context.add_identifier("a");
|
||||
// context.add_identifier("b");
|
||||
// assert!(predicate.eval(&[context]));
|
||||
let mut context = KeyContext::default();
|
||||
context.add("a");
|
||||
context.set("c", "x");
|
||||
assert!(!predicate.eval(&[context]));
|
||||
|
||||
// let mut context = ActionContext::default();
|
||||
// context.add_identifier("a");
|
||||
// context.add_key("c", "x");
|
||||
// assert!(!predicate.eval(&[context]));
|
||||
let mut context = KeyContext::default();
|
||||
context.add("a");
|
||||
context.set("c", "d");
|
||||
assert!(predicate.eval(&[context]));
|
||||
|
||||
// let mut context = ActionContext::default();
|
||||
// context.add_identifier("a");
|
||||
// context.add_key("c", "d");
|
||||
// assert!(predicate.eval(&[context]));
|
||||
let predicate = KeyBindingContextPredicate::parse("!a").unwrap();
|
||||
assert!(predicate.eval(&[KeyContext::default()]));
|
||||
}
|
||||
|
||||
// let predicate = KeymapContextPredicate::parse("!a").unwrap();
|
||||
// assert!(predicate.eval(&[ActionContext::default()]));
|
||||
// }
|
||||
#[test]
|
||||
fn test_context_child_predicate_eval() {
|
||||
let predicate = KeyBindingContextPredicate::parse("a && b > c").unwrap();
|
||||
let contexts = [
|
||||
context_set(&["a", "b"]),
|
||||
context_set(&["c", "d"]), // match this context
|
||||
context_set(&["e", "f"]),
|
||||
];
|
||||
|
||||
// #[test]
|
||||
// fn test_context_child_predicate_eval() {
|
||||
// let predicate = KeymapContextPredicate::parse("a && b > c").unwrap();
|
||||
// let contexts = [
|
||||
// context_set(&["e", "f"]),
|
||||
// context_set(&["c", "d"]), // match this context
|
||||
// context_set(&["a", "b"]),
|
||||
// ];
|
||||
assert!(!predicate.eval(&contexts[..=0]));
|
||||
assert!(predicate.eval(&contexts[..=1]));
|
||||
assert!(!predicate.eval(&contexts[..=2]));
|
||||
|
||||
// assert!(!predicate.eval(&contexts[0..]));
|
||||
// assert!(predicate.eval(&contexts[1..]));
|
||||
// assert!(!predicate.eval(&contexts[2..]));
|
||||
let predicate = KeyBindingContextPredicate::parse("a && b > c && !d > e").unwrap();
|
||||
let contexts = [
|
||||
context_set(&["a", "b"]),
|
||||
context_set(&["c", "d"]),
|
||||
context_set(&["e"]),
|
||||
context_set(&["a", "b"]),
|
||||
context_set(&["c"]),
|
||||
context_set(&["e"]), // only match this context
|
||||
context_set(&["f"]),
|
||||
];
|
||||
|
||||
// let predicate = KeymapContextPredicate::parse("a && b > c && !d > e").unwrap();
|
||||
// let contexts = [
|
||||
// context_set(&["f"]),
|
||||
// context_set(&["e"]), // only match this context
|
||||
// context_set(&["c"]),
|
||||
// context_set(&["a", "b"]),
|
||||
// context_set(&["e"]),
|
||||
// context_set(&["c", "d"]),
|
||||
// context_set(&["a", "b"]),
|
||||
// ];
|
||||
assert!(!predicate.eval(&contexts[..=0]));
|
||||
assert!(!predicate.eval(&contexts[..=1]));
|
||||
assert!(!predicate.eval(&contexts[..=2]));
|
||||
assert!(!predicate.eval(&contexts[..=3]));
|
||||
assert!(!predicate.eval(&contexts[..=4]));
|
||||
assert!(predicate.eval(&contexts[..=5]));
|
||||
assert!(!predicate.eval(&contexts[..=6]));
|
||||
|
||||
// assert!(!predicate.eval(&contexts[0..]));
|
||||
// assert!(predicate.eval(&contexts[1..]));
|
||||
// assert!(!predicate.eval(&contexts[2..]));
|
||||
// assert!(!predicate.eval(&contexts[3..]));
|
||||
// assert!(!predicate.eval(&contexts[4..]));
|
||||
// assert!(!predicate.eval(&contexts[5..]));
|
||||
// assert!(!predicate.eval(&contexts[6..]));
|
||||
fn context_set(names: &[&str]) -> KeyContext {
|
||||
let mut keymap = KeyContext::default();
|
||||
names.iter().for_each(|name| keymap.add(name.to_string()));
|
||||
keymap
|
||||
}
|
||||
}
|
||||
|
||||
// fn context_set(names: &[&str]) -> ActionContext {
|
||||
// let mut keymap = ActionContext::new();
|
||||
// names
|
||||
// .iter()
|
||||
// .for_each(|name| keymap.add_identifier(name.to_string()));
|
||||
// keymap
|
||||
// }
|
||||
// }
|
||||
#[test]
|
||||
fn test_matcher() {
|
||||
#[derive(Clone, Deserialize, PartialEq, Eq, Debug)]
|
||||
pub struct A(pub String);
|
||||
impl_actions!(test, [A]);
|
||||
actions!(test, [B, Ab, Dollar, Quote, Ess, Backtick]);
|
||||
|
||||
// #[test]
|
||||
// fn test_matcher() -> Result<()> {
|
||||
// #[derive(Clone, Deserialize, PartialEq, Eq, Debug)]
|
||||
// pub struct A(pub String);
|
||||
// impl_actions!(test, [A]);
|
||||
// actions!(test, [B, Ab, Dollar, Quote, Ess, Backtick]);
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
struct ActionArg {
|
||||
a: &'static str,
|
||||
}
|
||||
|
||||
// #[derive(Clone, Debug, Eq, PartialEq)]
|
||||
// struct ActionArg {
|
||||
// a: &'static str,
|
||||
// }
|
||||
let keymap = Keymap::new(vec![
|
||||
KeyBinding::new("a", A("x".to_string()), Some("a")),
|
||||
KeyBinding::new("b", B, Some("a")),
|
||||
KeyBinding::new("a b", Ab, Some("a || b")),
|
||||
KeyBinding::new("$", Dollar, Some("a")),
|
||||
KeyBinding::new("\"", Quote, Some("a")),
|
||||
KeyBinding::new("alt-s", Ess, Some("a")),
|
||||
KeyBinding::new("ctrl-`", Backtick, Some("a")),
|
||||
]);
|
||||
|
||||
// let keymap = Keymap::new(vec![
|
||||
// Binding::new("a", A("x".to_string()), Some("a")),
|
||||
// Binding::new("b", B, Some("a")),
|
||||
// Binding::new("a b", Ab, Some("a || b")),
|
||||
// Binding::new("$", Dollar, Some("a")),
|
||||
// Binding::new("\"", Quote, Some("a")),
|
||||
// Binding::new("alt-s", Ess, Some("a")),
|
||||
// Binding::new("ctrl-`", Backtick, Some("a")),
|
||||
// ]);
|
||||
let mut context_a = KeyContext::default();
|
||||
context_a.add("a");
|
||||
|
||||
// let mut context_a = ActionContext::default();
|
||||
// context_a.add_identifier("a");
|
||||
let mut context_b = KeyContext::default();
|
||||
context_b.add("b");
|
||||
|
||||
// let mut context_b = ActionContext::default();
|
||||
// context_b.add_identifier("b");
|
||||
let mut matcher = KeystrokeMatcher::new(Arc::new(Mutex::new(keymap)));
|
||||
|
||||
// let mut matcher = KeymapMatcher::new(keymap);
|
||||
// Basic match
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("a").unwrap(), &[context_a.clone()]),
|
||||
KeyMatch::Some(vec![Box::new(A("x".to_string()))])
|
||||
);
|
||||
matcher.clear_pending();
|
||||
|
||||
// // Basic match
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("a")?, vec![(1, context_a.clone())]),
|
||||
// KeyMatch::Matches(vec![(1, Box::new(A("x".to_string())))])
|
||||
// );
|
||||
// matcher.clear_pending();
|
||||
// Multi-keystroke match
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("a").unwrap(), &[context_b.clone()]),
|
||||
KeyMatch::Pending
|
||||
);
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("b").unwrap(), &[context_b.clone()]),
|
||||
KeyMatch::Some(vec![Box::new(Ab)])
|
||||
);
|
||||
matcher.clear_pending();
|
||||
|
||||
// // Multi-keystroke match
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("a")?, vec![(1, context_b.clone())]),
|
||||
// KeyMatch::Pending
|
||||
// );
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("b")?, vec![(1, context_b.clone())]),
|
||||
// KeyMatch::Matches(vec![(1, Box::new(Ab))])
|
||||
// );
|
||||
// matcher.clear_pending();
|
||||
// Failed matches don't interfere with matching subsequent keys
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("x").unwrap(), &[context_a.clone()]),
|
||||
KeyMatch::None
|
||||
);
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("a").unwrap(), &[context_a.clone()]),
|
||||
KeyMatch::Some(vec![Box::new(A("x".to_string()))])
|
||||
);
|
||||
matcher.clear_pending();
|
||||
|
||||
// // Failed matches don't interfere with matching subsequent keys
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("x")?, vec![(1, context_a.clone())]),
|
||||
// KeyMatch::None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("a")?, vec![(1, context_a.clone())]),
|
||||
// KeyMatch::Matches(vec![(1, Box::new(A("x".to_string())))])
|
||||
// );
|
||||
// matcher.clear_pending();
|
||||
let mut context_c = KeyContext::default();
|
||||
context_c.add("c");
|
||||
|
||||
// // Pending keystrokes are cleared when the context changes
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("a")?, vec![(1, context_b.clone())]),
|
||||
// KeyMatch::Pending
|
||||
// );
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("b")?, vec![(1, context_a.clone())]),
|
||||
// KeyMatch::None
|
||||
// );
|
||||
// matcher.clear_pending();
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(
|
||||
&Keystroke::parse("a").unwrap(),
|
||||
&[context_c.clone(), context_b.clone()]
|
||||
),
|
||||
KeyMatch::Pending
|
||||
);
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("b").unwrap(), &[context_b.clone()]),
|
||||
KeyMatch::Some(vec![Box::new(Ab)])
|
||||
);
|
||||
|
||||
// let mut context_c = ActionContext::default();
|
||||
// context_c.add_identifier("c");
|
||||
// handle Czech $ (option + 4 key)
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("alt-ç->$").unwrap(), &[context_a.clone()]),
|
||||
KeyMatch::Some(vec![Box::new(Dollar)])
|
||||
);
|
||||
|
||||
// // Pending keystrokes are maintained per-view
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(
|
||||
// Keystroke::parse("a")?,
|
||||
// vec![(1, context_b.clone()), (2, context_c.clone())]
|
||||
// ),
|
||||
// KeyMatch::Pending
|
||||
// );
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("b")?, vec![(1, context_b.clone())]),
|
||||
// KeyMatch::Matches(vec![(1, Box::new(Ab))])
|
||||
// );
|
||||
// handle Brazillian quote (quote key then space key)
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(
|
||||
&Keystroke::parse("space->\"").unwrap(),
|
||||
&[context_a.clone()]
|
||||
),
|
||||
KeyMatch::Some(vec![Box::new(Quote)])
|
||||
);
|
||||
|
||||
// // handle Czech $ (option + 4 key)
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("alt-ç->$")?, vec![(1, context_a.clone())]),
|
||||
// KeyMatch::Matches(vec![(1, Box::new(Dollar))])
|
||||
// );
|
||||
// handle ctrl+` on a brazillian keyboard
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("ctrl-->`").unwrap(), &[context_a.clone()]),
|
||||
KeyMatch::Some(vec![Box::new(Backtick)])
|
||||
);
|
||||
|
||||
// // handle Brazillian quote (quote key then space key)
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("space->\"")?, vec![(1, context_a.clone())]),
|
||||
// KeyMatch::Matches(vec![(1, Box::new(Quote))])
|
||||
// );
|
||||
|
||||
// // handle ctrl+` on a brazillian keyboard
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("ctrl-->`")?, vec![(1, context_a.clone())]),
|
||||
// KeyMatch::Matches(vec![(1, Box::new(Backtick))])
|
||||
// );
|
||||
|
||||
// // handle alt-s on a US keyboard
|
||||
// assert_eq!(
|
||||
// matcher.match_keystroke(Keystroke::parse("alt-s->ß")?, vec![(1, context_a.clone())]),
|
||||
// KeyMatch::Matches(vec![(1, Box::new(Ess))])
|
||||
// );
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
// }
|
||||
// handle alt-s on a US keyboard
|
||||
assert_eq!(
|
||||
matcher.match_keystroke(&Keystroke::parse("alt-s->ß").unwrap(), &[context_a.clone()]),
|
||||
KeyMatch::Some(vec![Box::new(Ess)])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -592,169 +592,49 @@ impl From<FontStyle> for FontkitStyle {
|
||||
}
|
||||
}
|
||||
|
||||
// #[cfg(test)]
|
||||
// mod tests {
|
||||
// use super::*;
|
||||
// use crate::AppContext;
|
||||
// use font_kit::properties::{Style, Weight};
|
||||
// use platform::FontSystem as _;
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{font, px, FontRun, MacTextSystem, PlatformTextSystem};
|
||||
|
||||
// #[crate::test(self, retries = 5)]
|
||||
// fn test_layout_str(_: &mut AppContext) {
|
||||
// // This is failing intermittently on CI and we don't have time to figure it out
|
||||
// let fonts = FontSystem::new();
|
||||
// let menlo = fonts.load_family("Menlo", &Default::default()).unwrap();
|
||||
// let menlo_regular = RunStyle {
|
||||
// font_id: fonts.select_font(&menlo, &Properties::new()).unwrap(),
|
||||
// color: Default::default(),
|
||||
// underline: Default::default(),
|
||||
// };
|
||||
// let menlo_italic = RunStyle {
|
||||
// font_id: fonts
|
||||
// .select_font(&menlo, Properties::new().style(Style::Italic))
|
||||
// .unwrap(),
|
||||
// color: Default::default(),
|
||||
// underline: Default::default(),
|
||||
// };
|
||||
// let menlo_bold = RunStyle {
|
||||
// font_id: fonts
|
||||
// .select_font(&menlo, Properties::new().weight(Weight::BOLD))
|
||||
// .unwrap(),
|
||||
// color: Default::default(),
|
||||
// underline: Default::default(),
|
||||
// };
|
||||
// assert_ne!(menlo_regular, menlo_italic);
|
||||
// assert_ne!(menlo_regular, menlo_bold);
|
||||
// assert_ne!(menlo_italic, menlo_bold);
|
||||
#[test]
|
||||
fn test_wrap_line() {
|
||||
let fonts = MacTextSystem::new();
|
||||
let font_id = fonts.font_id(&font("Helvetica")).unwrap();
|
||||
|
||||
// let line = fonts.layout_line(
|
||||
// "hello world",
|
||||
// 16.0,
|
||||
// &[(2, menlo_bold), (4, menlo_italic), (5, menlo_regular)],
|
||||
// );
|
||||
// assert_eq!(line.runs.len(), 3);
|
||||
// assert_eq!(line.runs[0].font_id, menlo_bold.font_id);
|
||||
// assert_eq!(line.runs[0].glyphs.len(), 2);
|
||||
// assert_eq!(line.runs[1].font_id, menlo_italic.font_id);
|
||||
// assert_eq!(line.runs[1].glyphs.len(), 4);
|
||||
// assert_eq!(line.runs[2].font_id, menlo_regular.font_id);
|
||||
// assert_eq!(line.runs[2].glyphs.len(), 5);
|
||||
// }
|
||||
let line = "one two three four five\n";
|
||||
let wrap_boundaries = fonts.wrap_line(line, font_id, px(16.), px(64.0));
|
||||
assert_eq!(wrap_boundaries, &["one two ".len(), "one two three ".len()]);
|
||||
|
||||
// #[test]
|
||||
// fn test_glyph_offsets() -> crate::Result<()> {
|
||||
// let fonts = FontSystem::new();
|
||||
// let zapfino = fonts.load_family("Zapfino", &Default::default())?;
|
||||
// let zapfino_regular = RunStyle {
|
||||
// font_id: fonts.select_font(&zapfino, &Properties::new())?,
|
||||
// color: Default::default(),
|
||||
// underline: Default::default(),
|
||||
// };
|
||||
// let menlo = fonts.load_family("Menlo", &Default::default())?;
|
||||
// let menlo_regular = RunStyle {
|
||||
// font_id: fonts.select_font(&menlo, &Properties::new())?,
|
||||
// color: Default::default(),
|
||||
// underline: Default::default(),
|
||||
// };
|
||||
let line = "aaa ααα ✋✋✋ 🎉🎉🎉\n";
|
||||
let wrap_boundaries = fonts.wrap_line(line, font_id, px(16.), px(64.0));
|
||||
assert_eq!(
|
||||
wrap_boundaries,
|
||||
&["aaa ααα ".len(), "aaa ααα ✋✋✋ ".len(),]
|
||||
);
|
||||
}
|
||||
|
||||
// let text = "This is, m𐍈re 𐍈r less, Zapfino!𐍈";
|
||||
// let line = fonts.layout_line(
|
||||
// text,
|
||||
// 16.0,
|
||||
// &[
|
||||
// (9, zapfino_regular),
|
||||
// (13, menlo_regular),
|
||||
// (text.len() - 22, zapfino_regular),
|
||||
// ],
|
||||
// );
|
||||
// assert_eq!(
|
||||
// line.runs
|
||||
// .iter()
|
||||
// .flat_map(|r| r.glyphs.iter())
|
||||
// .map(|g| g.index)
|
||||
// .collect::<Vec<_>>(),
|
||||
// vec![0, 2, 4, 5, 7, 8, 9, 10, 14, 15, 16, 17, 21, 22, 23, 24, 26, 27, 28, 29, 36, 37],
|
||||
// );
|
||||
// Ok(())
|
||||
// }
|
||||
#[test]
|
||||
fn test_layout_line_bom_char() {
|
||||
let fonts = MacTextSystem::new();
|
||||
let font_id = fonts.font_id(&font("Helvetica")).unwrap();
|
||||
let line = "\u{feff}";
|
||||
let mut style = FontRun {
|
||||
font_id,
|
||||
len: line.len(),
|
||||
};
|
||||
|
||||
// #[test]
|
||||
// #[ignore]
|
||||
// fn test_rasterize_glyph() {
|
||||
// use std::{fs::File, io::BufWriter, path::Path};
|
||||
let layout = fonts.layout_line(line, px(16.), &[style]);
|
||||
assert_eq!(layout.len, line.len());
|
||||
assert!(layout.runs.is_empty());
|
||||
|
||||
// let fonts = FontSystem::new();
|
||||
// let font_ids = fonts.load_family("Fira Code", &Default::default()).unwrap();
|
||||
// let font_id = fonts.select_font(&font_ids, &Default::default()).unwrap();
|
||||
// let glyph_id = fonts.glyph_for_char(font_id, 'G').unwrap();
|
||||
|
||||
// const VARIANTS: usize = 1;
|
||||
// for i in 0..VARIANTS {
|
||||
// let variant = i as f32 / VARIANTS as f32;
|
||||
// let (bounds, bytes) = fonts
|
||||
// .rasterize_glyph(
|
||||
// font_id,
|
||||
// 16.0,
|
||||
// glyph_id,
|
||||
// vec2f(variant, variant),
|
||||
// 2.,
|
||||
// RasterizationOptions::Alpha,
|
||||
// )
|
||||
// .unwrap();
|
||||
|
||||
// let name = format!("/Users/as-cii/Desktop/twog-{}.png", i);
|
||||
// let path = Path::new(&name);
|
||||
// let file = File::create(path).unwrap();
|
||||
// let w = &mut BufWriter::new(file);
|
||||
|
||||
// let mut encoder = png::Encoder::new(w, bounds.width() as u32, bounds.height() as u32);
|
||||
// encoder.set_color(png::ColorType::Grayscale);
|
||||
// encoder.set_depth(png::BitDepth::Eight);
|
||||
// let mut writer = encoder.write_header().unwrap();
|
||||
// writer.write_image_data(&bytes).unwrap();
|
||||
// }
|
||||
// }
|
||||
|
||||
// #[test]
|
||||
// fn test_wrap_line() {
|
||||
// let fonts = FontSystem::new();
|
||||
// let font_ids = fonts.load_family("Helvetica", &Default::default()).unwrap();
|
||||
// let font_id = fonts.select_font(&font_ids, &Default::default()).unwrap();
|
||||
|
||||
// let line = "one two three four five\n";
|
||||
// let wrap_boundaries = fonts.wrap_line(line, font_id, 16., 64.0);
|
||||
// assert_eq!(wrap_boundaries, &["one two ".len(), "one two three ".len()]);
|
||||
|
||||
// let line = "aaa ααα ✋✋✋ 🎉🎉🎉\n";
|
||||
// let wrap_boundaries = fonts.wrap_line(line, font_id, 16., 64.0);
|
||||
// assert_eq!(
|
||||
// wrap_boundaries,
|
||||
// &["aaa ααα ".len(), "aaa ααα ✋✋✋ ".len(),]
|
||||
// );
|
||||
// }
|
||||
|
||||
// #[test]
|
||||
// fn test_layout_line_bom_char() {
|
||||
// let fonts = FontSystem::new();
|
||||
// let font_ids = fonts.load_family("Helvetica", &Default::default()).unwrap();
|
||||
// let style = RunStyle {
|
||||
// font_id: fonts.select_font(&font_ids, &Default::default()).unwrap(),
|
||||
// color: Default::default(),
|
||||
// underline: Default::default(),
|
||||
// };
|
||||
|
||||
// let line = "\u{feff}";
|
||||
// let layout = fonts.layout_line(line, 16., &[(line.len(), style)]);
|
||||
// assert_eq!(layout.len, line.len());
|
||||
// assert!(layout.runs.is_empty());
|
||||
|
||||
// let line = "a\u{feff}b";
|
||||
// let layout = fonts.layout_line(line, 16., &[(line.len(), style)]);
|
||||
// assert_eq!(layout.len, line.len());
|
||||
// assert_eq!(layout.runs.len(), 1);
|
||||
// assert_eq!(layout.runs[0].glyphs.len(), 2);
|
||||
// assert_eq!(layout.runs[0].glyphs[0].id, 68); // a
|
||||
// // There's no glyph for \u{feff}
|
||||
// assert_eq!(layout.runs[0].glyphs[1].id, 69); // b
|
||||
// }
|
||||
// }
|
||||
let line = "a\u{feff}b";
|
||||
style.len = line.len();
|
||||
let layout = fonts.layout_line(line, px(16.), &[style]);
|
||||
assert_eq!(layout.len, line.len());
|
||||
assert_eq!(layout.runs.len(), 1);
|
||||
assert_eq!(layout.runs[0].glyphs.len(), 2);
|
||||
assert_eq!(layout.runs[0].glyphs[0].id, 68u32.into()); // a
|
||||
// There's no glyph for \u{feff}
|
||||
assert_eq!(layout.runs[0].glyphs[1].id, 69u32.into()); // b
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1906,7 +1906,8 @@ impl<'a> WindowContext<'a> {
|
||||
.platform_window
|
||||
.on_should_close(Box::new(move || {
|
||||
this.update(|_, cx| {
|
||||
// Ensure that the window is removed from the app if it's been closed.
|
||||
// Ensure that the window is removed from the app if it's been closed
|
||||
// by always pre-empting the system close event.
|
||||
if f(cx) {
|
||||
cx.remove_window();
|
||||
}
|
||||
|
||||
@@ -255,8 +255,8 @@ impl Pane {
|
||||
let focus_handle = cx.focus_handle();
|
||||
|
||||
let subscriptions = vec![
|
||||
cx.on_focus_in(&focus_handle, move |this, cx| this.focus_in(cx)),
|
||||
cx.on_focus_out(&focus_handle, move |this, cx| this.focus_out(cx)),
|
||||
cx.on_focus_in(&focus_handle, Pane::focus_in),
|
||||
cx.on_focus_out(&focus_handle, Pane::focus_out),
|
||||
];
|
||||
|
||||
let handle = cx.view().downgrade();
|
||||
|
||||
+354
-308
@@ -672,7 +672,7 @@ impl Workspace {
|
||||
// );
|
||||
|
||||
// this.show_notification(1, cx, |cx| {
|
||||
// cx.build_view(|_cx| {
|
||||
// cx.new_view(|_cx| {
|
||||
// simple_message_notification::MessageNotification::new(format!("Error:"))
|
||||
// .with_click_message("click here because!")
|
||||
// })
|
||||
@@ -4363,12 +4363,15 @@ mod tests {
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use super::*;
|
||||
use crate::item::{
|
||||
test::{TestItem, TestProjectItem},
|
||||
ItemEvent,
|
||||
use crate::{
|
||||
dock::{test::TestPanel, PanelEvent},
|
||||
item::{
|
||||
test::{TestItem, TestProjectItem},
|
||||
ItemEvent,
|
||||
},
|
||||
};
|
||||
use fs::FakeFs;
|
||||
use gpui::TestAppContext;
|
||||
use gpui::{px, DismissEvent, TestAppContext, VisualTestContext};
|
||||
use project::{Project, ProjectEntryId};
|
||||
use serde_json::json;
|
||||
use settings::SettingsStore;
|
||||
@@ -4935,362 +4938,405 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_toggle_docks_and_panels(cx: &mut gpui::TestAppContext) {
|
||||
// init_test(cx);
|
||||
// let fs = FakeFs::new(cx.executor());
|
||||
#[gpui::test]
|
||||
async fn test_toggle_docks_and_panels(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
|
||||
// let project = Project::test(fs, [], cx).await;
|
||||
// let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
|
||||
let project = Project::test(fs, [], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
|
||||
|
||||
// let panel = workspace.update(cx, |workspace, cx| {
|
||||
// let panel = cx.build_view(|cx| TestPanel::new(DockPosition::Right, cx));
|
||||
// workspace.add_panel(panel.clone(), cx);
|
||||
let panel = workspace.update(cx, |workspace, cx| {
|
||||
let panel = cx.new_view(|cx| TestPanel::new(DockPosition::Right, cx));
|
||||
workspace.add_panel(panel.clone(), cx);
|
||||
|
||||
// workspace
|
||||
// .right_dock()
|
||||
// .update(cx, |right_dock, cx| right_dock.set_open(true, cx));
|
||||
workspace
|
||||
.right_dock()
|
||||
.update(cx, |right_dock, cx| right_dock.set_open(true, cx));
|
||||
|
||||
// panel
|
||||
// });
|
||||
panel
|
||||
});
|
||||
|
||||
// let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
|
||||
// pane.update(cx, |pane, cx| {
|
||||
// let item = cx.build_view(|cx| TestItem::new(cx));
|
||||
// pane.add_item(Box::new(item), true, true, None, cx);
|
||||
// });
|
||||
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
|
||||
pane.update(cx, |pane, cx| {
|
||||
let item = cx.new_view(|cx| TestItem::new(cx));
|
||||
pane.add_item(Box::new(item), true, true, None, cx);
|
||||
});
|
||||
|
||||
// // Transfer focus from center to panel
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// workspace.toggle_panel_focus::<TestPanel>(cx);
|
||||
// });
|
||||
// Transfer focus from center to panel
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_panel_focus::<TestPanel>(cx);
|
||||
});
|
||||
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// assert!(workspace.right_dock().read(cx).is_open());
|
||||
// assert!(!panel.is_zoomed(cx));
|
||||
// assert!(panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
// });
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert!(!panel.is_zoomed(cx));
|
||||
assert!(panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
});
|
||||
|
||||
// // Transfer focus from panel to center
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// workspace.toggle_panel_focus::<TestPanel>(cx);
|
||||
// });
|
||||
// Transfer focus from panel to center
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_panel_focus::<TestPanel>(cx);
|
||||
});
|
||||
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// assert!(workspace.right_dock().read(cx).is_open());
|
||||
// assert!(!panel.is_zoomed(cx));
|
||||
// assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
// });
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert!(!panel.is_zoomed(cx));
|
||||
assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
});
|
||||
|
||||
// // Close the dock
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// workspace.toggle_dock(DockPosition::Right, cx);
|
||||
// });
|
||||
// Close the dock
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_dock(DockPosition::Right, cx);
|
||||
});
|
||||
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// assert!(!workspace.right_dock().read(cx).is_open());
|
||||
// assert!(!panel.is_zoomed(cx));
|
||||
// assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
// });
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
assert!(!workspace.right_dock().read(cx).is_open());
|
||||
assert!(!panel.is_zoomed(cx));
|
||||
assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
});
|
||||
|
||||
// // Open the dock
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// workspace.toggle_dock(DockPosition::Right, cx);
|
||||
// });
|
||||
// Open the dock
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_dock(DockPosition::Right, cx);
|
||||
});
|
||||
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// assert!(workspace.right_dock().read(cx).is_open());
|
||||
// assert!(!panel.is_zoomed(cx));
|
||||
// assert!(panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
// });
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert!(!panel.is_zoomed(cx));
|
||||
assert!(panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
});
|
||||
|
||||
// // Focus and zoom panel
|
||||
// panel.update(cx, |panel, cx| {
|
||||
// cx.focus_self();
|
||||
// panel.set_zoomed(true, cx)
|
||||
// });
|
||||
// Focus and zoom panel
|
||||
panel.update(cx, |panel, cx| {
|
||||
cx.focus_self();
|
||||
panel.set_zoomed(true, cx)
|
||||
});
|
||||
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// assert!(workspace.right_dock().read(cx).is_open());
|
||||
// assert!(panel.is_zoomed(cx));
|
||||
// assert!(panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
// });
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert!(panel.is_zoomed(cx));
|
||||
assert!(panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
});
|
||||
|
||||
// // Transfer focus to the center closes the dock
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// workspace.toggle_panel_focus::<TestPanel>(cx);
|
||||
// });
|
||||
// Transfer focus to the center closes the dock
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_panel_focus::<TestPanel>(cx);
|
||||
});
|
||||
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// assert!(!workspace.right_dock().read(cx).is_open());
|
||||
// assert!(panel.is_zoomed(cx));
|
||||
// assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
// });
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
assert!(!workspace.right_dock().read(cx).is_open());
|
||||
assert!(panel.is_zoomed(cx));
|
||||
assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
});
|
||||
|
||||
// // Transferring focus back to the panel keeps it zoomed
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// workspace.toggle_panel_focus::<TestPanel>(cx);
|
||||
// });
|
||||
// Transferring focus back to the panel keeps it zoomed
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_panel_focus::<TestPanel>(cx);
|
||||
});
|
||||
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// assert!(workspace.right_dock().read(cx).is_open());
|
||||
// assert!(panel.is_zoomed(cx));
|
||||
// assert!(panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
// });
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert!(panel.is_zoomed(cx));
|
||||
assert!(panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
});
|
||||
|
||||
// // Close the dock while it is zoomed
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// workspace.toggle_dock(DockPosition::Right, cx)
|
||||
// });
|
||||
// Close the dock while it is zoomed
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_dock(DockPosition::Right, cx)
|
||||
});
|
||||
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// assert!(!workspace.right_dock().read(cx).is_open());
|
||||
// assert!(panel.is_zoomed(cx));
|
||||
// assert!(workspace.zoomed.is_none());
|
||||
// assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
// });
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
assert!(!workspace.right_dock().read(cx).is_open());
|
||||
assert!(panel.is_zoomed(cx));
|
||||
assert!(workspace.zoomed.is_none());
|
||||
assert!(!panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
});
|
||||
|
||||
// // Opening the dock, when it's zoomed, retains focus
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// workspace.toggle_dock(DockPosition::Right, cx)
|
||||
// });
|
||||
// Opening the dock, when it's zoomed, retains focus
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_dock(DockPosition::Right, cx)
|
||||
});
|
||||
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// assert!(workspace.right_dock().read(cx).is_open());
|
||||
// assert!(panel.is_zoomed(cx));
|
||||
// assert!(workspace.zoomed.is_some());
|
||||
// assert!(panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
// });
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert!(panel.is_zoomed(cx));
|
||||
assert!(workspace.zoomed.is_some());
|
||||
assert!(panel.read(cx).focus_handle(cx).contains_focused(cx));
|
||||
});
|
||||
|
||||
// // Unzoom and close the panel, zoom the active pane.
|
||||
// panel.update(cx, |panel, cx| panel.set_zoomed(false, cx));
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// workspace.toggle_dock(DockPosition::Right, cx)
|
||||
// });
|
||||
// pane.update(cx, |pane, cx| pane.toggle_zoom(&Default::default(), cx));
|
||||
// Unzoom and close the panel, zoom the active pane.
|
||||
panel.update(cx, |panel, cx| panel.set_zoomed(false, cx));
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_dock(DockPosition::Right, cx)
|
||||
});
|
||||
pane.update(cx, |pane, cx| pane.toggle_zoom(&Default::default(), cx));
|
||||
|
||||
// // Opening a dock unzooms the pane.
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// workspace.toggle_dock(DockPosition::Right, cx)
|
||||
// });
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// let pane = pane.read(cx);
|
||||
// assert!(!pane.is_zoomed());
|
||||
// assert!(!pane.focus_handle(cx).is_focused(cx));
|
||||
// assert!(workspace.right_dock().read(cx).is_open());
|
||||
// assert!(workspace.zoomed.is_none());
|
||||
// });
|
||||
// }
|
||||
// Opening a dock unzooms the pane.
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.toggle_dock(DockPosition::Right, cx)
|
||||
});
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
let pane = pane.read(cx);
|
||||
assert!(!pane.is_zoomed());
|
||||
assert!(!pane.focus_handle(cx).is_focused(cx));
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert!(workspace.zoomed.is_none());
|
||||
});
|
||||
}
|
||||
|
||||
// #[gpui::test]
|
||||
// async fn test_panels(cx: &mut gpui::TestAppContext) {
|
||||
// init_test(cx);
|
||||
// let fs = FakeFs::new(cx.executor());
|
||||
struct TestModal(FocusHandle);
|
||||
|
||||
// let project = Project::test(fs, [], cx).await;
|
||||
// let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
|
||||
impl TestModal {
|
||||
fn new(cx: &mut ViewContext<Self>) -> Self {
|
||||
Self(cx.focus_handle())
|
||||
}
|
||||
}
|
||||
|
||||
// let (panel_1, panel_2) = workspace.update(cx, |workspace, cx| {
|
||||
// // Add panel_1 on the left, panel_2 on the right.
|
||||
// let panel_1 = cx.build_view(|cx| TestPanel::new(DockPosition::Left, cx));
|
||||
// workspace.add_panel(panel_1.clone(), cx);
|
||||
// workspace
|
||||
// .left_dock()
|
||||
// .update(cx, |left_dock, cx| left_dock.set_open(true, cx));
|
||||
// let panel_2 = cx.build_view(|cx| TestPanel::new(DockPosition::Right, cx));
|
||||
// workspace.add_panel(panel_2.clone(), cx);
|
||||
// workspace
|
||||
// .right_dock()
|
||||
// .update(cx, |right_dock, cx| right_dock.set_open(true, cx));
|
||||
impl EventEmitter<DismissEvent> for TestModal {}
|
||||
|
||||
// let left_dock = workspace.left_dock();
|
||||
// assert_eq!(
|
||||
// left_dock.read(cx).visible_panel().unwrap().panel_id(),
|
||||
// panel_1.panel_id()
|
||||
// );
|
||||
// assert_eq!(
|
||||
// left_dock.read(cx).active_panel_size(cx).unwrap(),
|
||||
// panel_1.size(cx)
|
||||
// );
|
||||
impl FocusableView for TestModal {
|
||||
fn focus_handle(&self, _cx: &AppContext) -> FocusHandle {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
// left_dock.update(cx, |left_dock, cx| {
|
||||
// left_dock.resize_active_panel(Some(1337.), cx)
|
||||
// });
|
||||
// assert_eq!(
|
||||
// workspace
|
||||
// .right_dock()
|
||||
// .read(cx)
|
||||
// .visible_panel()
|
||||
// .unwrap()
|
||||
// .panel_id(),
|
||||
// panel_2.panel_id(),
|
||||
// );
|
||||
impl ModalView for TestModal {}
|
||||
|
||||
// (panel_1, panel_2)
|
||||
// });
|
||||
impl Render for TestModal {
|
||||
fn render(&mut self, _cx: &mut ViewContext<TestModal>) -> impl IntoElement {
|
||||
div().track_focus(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
// // Move panel_1 to the right
|
||||
// panel_1.update(cx, |panel_1, cx| {
|
||||
// panel_1.set_position(DockPosition::Right, cx)
|
||||
// });
|
||||
#[gpui::test]
|
||||
async fn test_panels(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// // Since panel_1 was visible on the left, it should now be visible now that it's been moved to the right.
|
||||
// // Since it was the only panel on the left, the left dock should now be closed.
|
||||
// assert!(!workspace.left_dock().read(cx).is_open());
|
||||
// assert!(workspace.left_dock().read(cx).visible_panel().is_none());
|
||||
// let right_dock = workspace.right_dock();
|
||||
// assert_eq!(
|
||||
// right_dock.read(cx).visible_panel().unwrap().panel_id(),
|
||||
// panel_1.panel_id()
|
||||
// );
|
||||
// assert_eq!(right_dock.read(cx).active_panel_size(cx).unwrap(), 1337.);
|
||||
let project = Project::test(fs, [], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|cx| Workspace::test_new(project, cx));
|
||||
|
||||
// // Now we move panel_2 to the left
|
||||
// panel_2.set_position(DockPosition::Left, cx);
|
||||
// });
|
||||
let (panel_1, panel_2) = workspace.update(cx, |workspace, cx| {
|
||||
let panel_1 = cx.new_view(|cx| TestPanel::new(DockPosition::Left, cx));
|
||||
workspace.add_panel(panel_1.clone(), cx);
|
||||
workspace
|
||||
.left_dock()
|
||||
.update(cx, |left_dock, cx| left_dock.set_open(true, cx));
|
||||
let panel_2 = cx.new_view(|cx| TestPanel::new(DockPosition::Right, cx));
|
||||
workspace.add_panel(panel_2.clone(), cx);
|
||||
workspace
|
||||
.right_dock()
|
||||
.update(cx, |right_dock, cx| right_dock.set_open(true, cx));
|
||||
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// // Since panel_2 was not visible on the right, we don't open the left dock.
|
||||
// assert!(!workspace.left_dock().read(cx).is_open());
|
||||
// // And the right dock is unaffected in it's displaying of panel_1
|
||||
// assert!(workspace.right_dock().read(cx).is_open());
|
||||
// assert_eq!(
|
||||
// workspace
|
||||
// .right_dock()
|
||||
// .read(cx)
|
||||
// .visible_panel()
|
||||
// .unwrap()
|
||||
// .panel_id(),
|
||||
// panel_1.panel_id(),
|
||||
// );
|
||||
// });
|
||||
let left_dock = workspace.left_dock();
|
||||
assert_eq!(
|
||||
left_dock.read(cx).visible_panel().unwrap().panel_id(),
|
||||
panel_1.panel_id()
|
||||
);
|
||||
assert_eq!(
|
||||
left_dock.read(cx).active_panel_size(cx).unwrap(),
|
||||
panel_1.size(cx)
|
||||
);
|
||||
|
||||
// // Move panel_1 back to the left
|
||||
// panel_1.update(cx, |panel_1, cx| {
|
||||
// panel_1.set_position(DockPosition::Left, cx)
|
||||
// });
|
||||
left_dock.update(cx, |left_dock, cx| {
|
||||
left_dock.resize_active_panel(Some(px(1337.)), cx)
|
||||
});
|
||||
assert_eq!(
|
||||
workspace
|
||||
.right_dock()
|
||||
.read(cx)
|
||||
.visible_panel()
|
||||
.unwrap()
|
||||
.panel_id(),
|
||||
panel_2.panel_id(),
|
||||
);
|
||||
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// // Since panel_1 was visible on the right, we open the left dock and make panel_1 active.
|
||||
// let left_dock = workspace.left_dock();
|
||||
// assert!(left_dock.read(cx).is_open());
|
||||
// assert_eq!(
|
||||
// left_dock.read(cx).visible_panel().unwrap().panel_id(),
|
||||
// panel_1.panel_id()
|
||||
// );
|
||||
// assert_eq!(left_dock.read(cx).active_panel_size(cx).unwrap(), 1337.);
|
||||
// // And right the dock should be closed as it no longer has any panels.
|
||||
// assert!(!workspace.right_dock().read(cx).is_open());
|
||||
(panel_1, panel_2)
|
||||
});
|
||||
|
||||
// // Now we move panel_1 to the bottom
|
||||
// panel_1.set_position(DockPosition::Bottom, cx);
|
||||
// });
|
||||
// Move panel_1 to the right
|
||||
panel_1.update(cx, |panel_1, cx| {
|
||||
panel_1.set_position(DockPosition::Right, cx)
|
||||
});
|
||||
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// // Since panel_1 was visible on the left, we close the left dock.
|
||||
// assert!(!workspace.left_dock().read(cx).is_open());
|
||||
// // The bottom dock is sized based on the panel's default size,
|
||||
// // since the panel orientation changed from vertical to horizontal.
|
||||
// let bottom_dock = workspace.bottom_dock();
|
||||
// assert_eq!(
|
||||
// bottom_dock.read(cx).active_panel_size(cx).unwrap(),
|
||||
// panel_1.size(cx),
|
||||
// );
|
||||
// // Close bottom dock and move panel_1 back to the left.
|
||||
// bottom_dock.update(cx, |bottom_dock, cx| bottom_dock.set_open(false, cx));
|
||||
// panel_1.set_position(DockPosition::Left, cx);
|
||||
// });
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
// Since panel_1 was visible on the left, it should now be visible now that it's been moved to the right.
|
||||
// Since it was the only panel on the left, the left dock should now be closed.
|
||||
assert!(!workspace.left_dock().read(cx).is_open());
|
||||
assert!(workspace.left_dock().read(cx).visible_panel().is_none());
|
||||
let right_dock = workspace.right_dock();
|
||||
assert_eq!(
|
||||
right_dock.read(cx).visible_panel().unwrap().panel_id(),
|
||||
panel_1.panel_id()
|
||||
);
|
||||
assert_eq!(
|
||||
right_dock.read(cx).active_panel_size(cx).unwrap(),
|
||||
px(1337.)
|
||||
);
|
||||
|
||||
// // Emit activated event on panel 1
|
||||
// panel_1.update(cx, |_, cx| cx.emit(PanelEvent::Activate));
|
||||
// Now we move panel_2 to the left
|
||||
panel_2.set_position(DockPosition::Left, cx);
|
||||
});
|
||||
|
||||
// // Now the left dock is open and panel_1 is active and focused.
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// let left_dock = workspace.left_dock();
|
||||
// assert!(left_dock.read(cx).is_open());
|
||||
// assert_eq!(
|
||||
// left_dock.read(cx).visible_panel().unwrap().panel_id(),
|
||||
// panel_1.panel_id(),
|
||||
// );
|
||||
// assert!(panel_1.focus_handle(cx).is_focused(cx));
|
||||
// });
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
// Since panel_2 was not visible on the right, we don't open the left dock.
|
||||
assert!(!workspace.left_dock().read(cx).is_open());
|
||||
// And the right dock is unaffected in it's displaying of panel_1
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert_eq!(
|
||||
workspace
|
||||
.right_dock()
|
||||
.read(cx)
|
||||
.visible_panel()
|
||||
.unwrap()
|
||||
.panel_id(),
|
||||
panel_1.panel_id(),
|
||||
);
|
||||
});
|
||||
|
||||
// // Emit closed event on panel 2, which is not active
|
||||
// panel_2.update(cx, |_, cx| cx.emit(PanelEvent::Close));
|
||||
// Move panel_1 back to the left
|
||||
panel_1.update(cx, |panel_1, cx| {
|
||||
panel_1.set_position(DockPosition::Left, cx)
|
||||
});
|
||||
|
||||
// // Wo don't close the left dock, because panel_2 wasn't the active panel
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// let left_dock = workspace.left_dock();
|
||||
// assert!(left_dock.read(cx).is_open());
|
||||
// assert_eq!(
|
||||
// left_dock.read(cx).visible_panel().unwrap().panel_id(),
|
||||
// panel_1.panel_id(),
|
||||
// );
|
||||
// });
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
// Since panel_1 was visible on the right, we open the left dock and make panel_1 active.
|
||||
let left_dock = workspace.left_dock();
|
||||
assert!(left_dock.read(cx).is_open());
|
||||
assert_eq!(
|
||||
left_dock.read(cx).visible_panel().unwrap().panel_id(),
|
||||
panel_1.panel_id()
|
||||
);
|
||||
assert_eq!(left_dock.read(cx).active_panel_size(cx).unwrap(), px(1337.));
|
||||
// And the right dock should be closed as it no longer has any panels.
|
||||
assert!(!workspace.right_dock().read(cx).is_open());
|
||||
|
||||
// // Emitting a ZoomIn event shows the panel as zoomed.
|
||||
// panel_1.update(cx, |_, cx| cx.emit(PanelEvent::ZoomIn));
|
||||
// workspace.update(cx, |workspace, _| {
|
||||
// assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade()));
|
||||
// assert_eq!(workspace.zoomed_position, Some(DockPosition::Left));
|
||||
// });
|
||||
// Now we move panel_1 to the bottom
|
||||
panel_1.set_position(DockPosition::Bottom, cx);
|
||||
});
|
||||
|
||||
// // Move panel to another dock while it is zoomed
|
||||
// panel_1.update(cx, |panel, cx| panel.set_position(DockPosition::Right, cx));
|
||||
// workspace.update(cx, |workspace, _| {
|
||||
// assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade()));
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
// Since panel_1 was visible on the left, we close the left dock.
|
||||
assert!(!workspace.left_dock().read(cx).is_open());
|
||||
// The bottom dock is sized based on the panel's default size,
|
||||
// since the panel orientation changed from vertical to horizontal.
|
||||
let bottom_dock = workspace.bottom_dock();
|
||||
assert_eq!(
|
||||
bottom_dock.read(cx).active_panel_size(cx).unwrap(),
|
||||
panel_1.size(cx),
|
||||
);
|
||||
// Close bottom dock and move panel_1 back to the left.
|
||||
bottom_dock.update(cx, |bottom_dock, cx| bottom_dock.set_open(false, cx));
|
||||
panel_1.set_position(DockPosition::Left, cx);
|
||||
});
|
||||
|
||||
// assert_eq!(workspace.zoomed_position, Some(DockPosition::Right));
|
||||
// });
|
||||
// Emit activated event on panel 1
|
||||
panel_1.update(cx, |_, cx| cx.emit(PanelEvent::Activate));
|
||||
|
||||
// // If focus is transferred to another view that's not a panel or another pane, we still show
|
||||
// // the panel as zoomed.
|
||||
// let other_focus_handle = cx.update(|cx| cx.focus_handle());
|
||||
// cx.update(|cx| cx.focus(&other_focus_handle));
|
||||
// workspace.update(cx, |workspace, _| {
|
||||
// assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade()));
|
||||
// assert_eq!(workspace.zoomed_position, Some(DockPosition::Right));
|
||||
// });
|
||||
// Now the left dock is open and panel_1 is active and focused.
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
let left_dock = workspace.left_dock();
|
||||
assert!(left_dock.read(cx).is_open());
|
||||
assert_eq!(
|
||||
left_dock.read(cx).visible_panel().unwrap().panel_id(),
|
||||
panel_1.panel_id(),
|
||||
);
|
||||
assert!(panel_1.focus_handle(cx).is_focused(cx));
|
||||
});
|
||||
|
||||
// // If focus is transferred elsewhere in the workspace, the panel is no longer zoomed.
|
||||
// workspace.update(cx, |_, cx| cx.focus_self());
|
||||
// workspace.update(cx, |workspace, _| {
|
||||
// assert_eq!(workspace.zoomed, None);
|
||||
// assert_eq!(workspace.zoomed_position, None);
|
||||
// });
|
||||
// Emit closed event on panel 2, which is not active
|
||||
panel_2.update(cx, |_, cx| cx.emit(PanelEvent::Close));
|
||||
|
||||
// // If focus is transferred again to another view that's not a panel or a pane, we won't
|
||||
// // show the panel as zoomed because it wasn't zoomed before.
|
||||
// cx.update(|cx| cx.focus(&other_focus_handle));
|
||||
// workspace.update(cx, |workspace, _| {
|
||||
// assert_eq!(workspace.zoomed, None);
|
||||
// assert_eq!(workspace.zoomed_position, None);
|
||||
// });
|
||||
// Wo don't close the left dock, because panel_2 wasn't the active panel
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
let left_dock = workspace.left_dock();
|
||||
assert!(left_dock.read(cx).is_open());
|
||||
assert_eq!(
|
||||
left_dock.read(cx).visible_panel().unwrap().panel_id(),
|
||||
panel_1.panel_id(),
|
||||
);
|
||||
});
|
||||
|
||||
// // When focus is transferred back to the panel, it is zoomed again.
|
||||
// panel_1.update(cx, |_, cx| cx.focus_self());
|
||||
// workspace.update(cx, |workspace, _| {
|
||||
// assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade()));
|
||||
// assert_eq!(workspace.zoomed_position, Some(DockPosition::Right));
|
||||
// });
|
||||
// Emitting a ZoomIn event shows the panel as zoomed.
|
||||
panel_1.update(cx, |_, cx| cx.emit(PanelEvent::ZoomIn));
|
||||
workspace.update(cx, |workspace, _| {
|
||||
assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade()));
|
||||
assert_eq!(workspace.zoomed_position, Some(DockPosition::Left));
|
||||
});
|
||||
|
||||
// // Emitting a ZoomOut event unzooms the panel.
|
||||
// panel_1.update(cx, |_, cx| cx.emit(PanelEvent::ZoomOut));
|
||||
// workspace.update(cx, |workspace, _| {
|
||||
// assert_eq!(workspace.zoomed, None);
|
||||
// assert_eq!(workspace.zoomed_position, None);
|
||||
// });
|
||||
// Move panel to another dock while it is zoomed
|
||||
panel_1.update(cx, |panel, cx| panel.set_position(DockPosition::Right, cx));
|
||||
workspace.update(cx, |workspace, _| {
|
||||
assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade()));
|
||||
|
||||
// // Emit closed event on panel 1, which is active
|
||||
// panel_1.update(cx, |_, cx| cx.emit(PanelEvent::Close));
|
||||
assert_eq!(workspace.zoomed_position, Some(DockPosition::Right));
|
||||
});
|
||||
|
||||
// // Now the left dock is closed, because panel_1 was the active panel
|
||||
// workspace.update(cx, |workspace, cx| {
|
||||
// let right_dock = workspace.right_dock();
|
||||
// assert!(!right_dock.read(cx).is_open());
|
||||
// });
|
||||
// }
|
||||
// This is a helper for getting a:
|
||||
// - valid focus on an element,
|
||||
// - that isn't a part of the panes and panels system of the Workspace,
|
||||
// - and doesn't trigger the 'on_focus_lost' API.
|
||||
let focus_other_view = {
|
||||
let workspace = workspace.clone();
|
||||
move |cx: &mut VisualTestContext| {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
if let Some(_) = workspace.active_modal::<TestModal>(cx) {
|
||||
workspace.toggle_modal(cx, TestModal::new);
|
||||
workspace.toggle_modal(cx, TestModal::new);
|
||||
} else {
|
||||
workspace.toggle_modal(cx, TestModal::new);
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
// If focus is transferred to another view that's not a panel or another pane, we still show
|
||||
// the panel as zoomed.
|
||||
focus_other_view(cx);
|
||||
workspace.update(cx, |workspace, _| {
|
||||
assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade()));
|
||||
assert_eq!(workspace.zoomed_position, Some(DockPosition::Right));
|
||||
});
|
||||
|
||||
// If focus is transferred elsewhere in the workspace, the panel is no longer zoomed.
|
||||
workspace.update(cx, |_, cx| cx.focus_self());
|
||||
workspace.update(cx, |workspace, _| {
|
||||
assert_eq!(workspace.zoomed, None);
|
||||
assert_eq!(workspace.zoomed_position, None);
|
||||
});
|
||||
|
||||
// If focus is transferred again to another view that's not a panel or a pane, we won't
|
||||
// show the panel as zoomed because it wasn't zoomed before.
|
||||
focus_other_view(cx);
|
||||
workspace.update(cx, |workspace, _| {
|
||||
assert_eq!(workspace.zoomed, None);
|
||||
assert_eq!(workspace.zoomed_position, None);
|
||||
});
|
||||
|
||||
// When the panel is activated, it is zoomed again.
|
||||
cx.dispatch_action(ToggleRightDock);
|
||||
workspace.update(cx, |workspace, _| {
|
||||
assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade()));
|
||||
assert_eq!(workspace.zoomed_position, Some(DockPosition::Right));
|
||||
});
|
||||
|
||||
// Emitting a ZoomOut event unzooms the panel.
|
||||
panel_1.update(cx, |_, cx| cx.emit(PanelEvent::ZoomOut));
|
||||
workspace.update(cx, |workspace, _| {
|
||||
assert_eq!(workspace.zoomed, None);
|
||||
assert_eq!(workspace.zoomed_position, None);
|
||||
});
|
||||
|
||||
// Emit closed event on panel 1, which is active
|
||||
panel_1.update(cx, |_, cx| cx.emit(PanelEvent::Close));
|
||||
|
||||
// Now the left dock is closed, because panel_1 was the active panel
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
let right_dock = workspace.right_dock();
|
||||
assert!(!right_dock.read(cx).is_open());
|
||||
});
|
||||
}
|
||||
|
||||
pub fn init_test(cx: &mut TestAppContext) {
|
||||
cx.update(|cx| {
|
||||
|
||||
Reference in New Issue
Block a user