add simpler api for configuring the caret blink interval via element
This commit is contained in:
@@ -115,7 +115,20 @@
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! To use a blinking caret, construct a caret entity with a blinking interval when constructing the state:
|
||||
//! To use a blinking caret, you can use one of the templated functions:
|
||||
//! ```
|
||||
//! # use gpui::{prelude::*, App, Entity, Window, AppContext, ElementId};
|
||||
//! # fn test(window: &mut Window, cx: &mut App) -> gpui_elements::editable_text::EditableTextElement {
|
||||
//! use gpui_elements::editable_text::{text_input};
|
||||
//! let id = ElementId::from("my_input");
|
||||
//! text_input(id)
|
||||
//! .caret_blink_interval_500ms()
|
||||
//! // or use the parameterized one, e.g. 200ms
|
||||
//! .caret_blink_interval(std::time::Duration::from_millis(200))
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! or construct a caret entity with a blinking interval when constructing the state:
|
||||
//! ```
|
||||
//! # use gpui::{prelude::*, App, Entity, Window, AppContext, ElementId};
|
||||
//! # fn test(window: &mut Window, cx: &mut App) -> gpui_elements::editable_text::EditableTextElement {
|
||||
@@ -127,7 +140,7 @@
|
||||
//! // Ensure the caret exists, linked to the input element by id.
|
||||
//! window.use_keyed_state(id.clone(), cx, |window, cx| {
|
||||
//! // using the default interval of 500ms
|
||||
//! let mut caret = Caret::default().blink_interval_default();
|
||||
//! let mut caret = Caret::default().with_blink_interval_500ms();
|
||||
//! // ensures the caret receives events from the input state during typing & other actions
|
||||
//! caret.subscribe_to(&state, cx);
|
||||
//! caret
|
||||
|
||||
@@ -3,7 +3,7 @@ use smallvec::SmallVec;
|
||||
use std::time::Duration;
|
||||
|
||||
/// Default interval for caret blinking (500ms).
|
||||
pub const DEFAULT_BLINK_INTERVAL: Duration = Duration::from_millis(500);
|
||||
pub const BLINK_INTERVAL_500MS: Duration = Duration::from_millis(500);
|
||||
|
||||
/// Events emitted that the [`Caret`] listens to.
|
||||
pub enum CaretNotify {
|
||||
@@ -44,19 +44,28 @@ impl Default for Caret {
|
||||
}
|
||||
|
||||
impl Caret {
|
||||
/// Sets the blinking interval of the caret to the global "default".
|
||||
/// The true default of the caret is "do not blink".
|
||||
pub fn blink_interval_default(mut self) -> Self {
|
||||
self.interval = DEFAULT_BLINK_INTERVAL;
|
||||
self
|
||||
/// Returns the duration of the current blink interval
|
||||
pub fn blink_interval(&self) -> Duration {
|
||||
self.interval
|
||||
}
|
||||
|
||||
/// Sets the blinking interval of the caret.
|
||||
pub fn blink_interval(mut self, interval: Duration) -> Self {
|
||||
pub fn set_blink_interval(&mut self, interval: Duration) {
|
||||
self.interval = interval;
|
||||
}
|
||||
|
||||
/// Sets the blinking interval of the caret.
|
||||
pub fn with_blink_interval(mut self, interval: Duration) -> Self {
|
||||
self.set_blink_interval(interval);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the blinking interval of the caret to the global "default".
|
||||
/// The true default of the caret is "do not blink".
|
||||
pub fn with_blink_interval_500ms(self) -> Self {
|
||||
self.with_blink_interval(BLINK_INTERVAL_500MS)
|
||||
}
|
||||
|
||||
/// Listens for CaretNotify events on an entity (e.g. [`EditableTextState`]).
|
||||
pub fn subscribe_to<E>(&mut self, emitter: &Entity<E>, cx: &mut Context<Self>)
|
||||
where
|
||||
@@ -88,7 +97,7 @@ impl Caret {
|
||||
|
||||
// Caret has no blinking interval, it is always visible
|
||||
if self.interval.is_zero() {
|
||||
return true;
|
||||
return is_focused;
|
||||
}
|
||||
|
||||
match (is_focused, was_focused) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::editable_text::{
|
||||
Caret, EditableTextState,
|
||||
BLINK_INTERVAL_500MS, Caret, EditableTextState,
|
||||
actions::{DEFAULT_INPUT_CONTEXT, EditableTextActionElement, EditableTextActionHandler},
|
||||
layout::{EditableTextLayoutResult, EditableTextLayoutState, TextLineSegment},
|
||||
};
|
||||
@@ -12,7 +12,7 @@ use gpui::{
|
||||
px, size,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use std::{cell::RefCell, ops::Range, rc::Rc, sync::Arc};
|
||||
use std::{cell::RefCell, ops::Range, rc::Rc, sync::Arc, time::Duration};
|
||||
|
||||
const CARET_RENDER_WIDTH: f32 = 2.0;
|
||||
|
||||
@@ -29,6 +29,7 @@ pub fn editable_text(id: impl Into<ElementId>) -> EditableTextElement {
|
||||
placeholder: None,
|
||||
accepts_input: true,
|
||||
colors: EditableTextColors::default(),
|
||||
caret_blink_interval: None,
|
||||
};
|
||||
this.interactivity.element_id = Some(id.into());
|
||||
|
||||
@@ -63,6 +64,7 @@ pub struct EditableTextElement {
|
||||
placeholder: Option<SharedString>,
|
||||
accepts_input: bool,
|
||||
colors: EditableTextColors,
|
||||
caret_blink_interval: Option<Duration>,
|
||||
}
|
||||
|
||||
/// EditableText styling that goes beyond what Style/StyleRefinement supports
|
||||
@@ -140,6 +142,17 @@ impl EditableTextElement {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the blinking interval of the caret.
|
||||
pub fn caret_blink_interval(mut self, duration: Duration) -> Self {
|
||||
self.caret_blink_interval = Some(duration);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the blinking interval of the caret to 500ms
|
||||
pub fn caret_blink_interval_500ms(self) -> Self {
|
||||
self.caret_blink_interval(BLINK_INTERVAL_500MS)
|
||||
}
|
||||
|
||||
/// Sets the color of the placeholder text which is rendered when the element's stored text is empty.
|
||||
///
|
||||
/// Cannot be refined via [`StyleRefinement`](gpui::StyleRefinement) due to limitations in the fields of [`Style`](gpui::Style).
|
||||
@@ -256,6 +269,12 @@ impl Element for EditableTextElement {
|
||||
let entity = self.find_or_create_state(window, cx);
|
||||
let caret = self.find_or_create_caret(&entity, window, cx);
|
||||
|
||||
if let Some(duration) = self.caret_blink_interval.take()
|
||||
&& caret.read(cx).blink_interval() != duration
|
||||
{
|
||||
caret.update(cx, |caret, _cx| caret.set_blink_interval(duration));
|
||||
}
|
||||
|
||||
// Read new state information from the underlying entity.
|
||||
// Block-wrapped so that the state being read is dropped before continuing.
|
||||
let (prelayout, next_scroll_offset) = {
|
||||
|
||||
Reference in New Issue
Block a user