fix: clippy issues

This commit is contained in:
2025-02-01 15:32:53 +07:00
parent 09a0d089bc
commit c982c802e2
10 changed files with 205 additions and 67 deletions

View File

@@ -16,7 +16,7 @@ chrono.workspace = true
paste = "1" paste = "1"
regex = "1" regex = "1"
unicode-segmentation = "1.11.0" unicode-segmentation = "1.12.0"
uuid = "1.10" uuid = "1.10"
once_cell = "1.19.0" once_cell = "1.19.0"
image = "0.25.1" image = "0.25.1"

View File

@@ -1,18 +1,22 @@
use crate::{
button::{Button, ButtonVariants as _},
h_flex, IconName, Sizable as _,
};
use gpui::{ use gpui::{
prelude::FluentBuilder, AnyElement, App, ClipboardItem, Element, ElementId, GlobalElementId, prelude::FluentBuilder, AnyElement, App, ClipboardItem, Element, ElementId, GlobalElementId,
IntoElement, LayoutId, ParentElement, SharedString, Styled, Window, IntoElement, LayoutId, ParentElement, SharedString, Styled, Window,
}; };
use std::{cell::RefCell, rc::Rc, time::Duration}; use std::{cell::RefCell, rc::Rc, time::Duration};
use crate::{
button::{Button, ButtonVariants as _},
h_flex, IconName, Sizable as _,
};
type ContentBuilder = Option<Box<dyn Fn(&mut Window, &mut App) -> AnyElement>>;
type CopiedCallback = Option<Rc<dyn Fn(SharedString, &mut Window, &mut App)>>;
pub struct Clipboard { pub struct Clipboard {
id: ElementId, id: ElementId,
value: SharedString, value: SharedString,
content_builder: Option<Box<dyn Fn(&mut Window, &mut App) -> AnyElement>>, content_builder: ContentBuilder,
copied_callback: Option<Rc<dyn Fn(SharedString, &mut Window, &mut App)>>, copied_callback: CopiedCallback,
} }
impl Clipboard { impl Clipboard {

View File

@@ -19,11 +19,13 @@ pub trait ContextMenuExt: ParentElement + Sized {
impl<E> ContextMenuExt for Stateful<E> where E: ParentElement {} impl<E> ContextMenuExt for Stateful<E> where E: ParentElement {}
impl<E> ContextMenuExt for FocusableWrapper<E> where E: ParentElement {} impl<E> ContextMenuExt for FocusableWrapper<E> where E: ParentElement {}
type Menu =
Option<Box<dyn Fn(PopupMenu, &mut Window, &mut Context<PopupMenu>) -> PopupMenu + 'static>>;
/// A context menu that can be shown on right-click. /// A context menu that can be shown on right-click.
pub struct ContextMenu { pub struct ContextMenu {
id: ElementId, id: ElementId,
menu: menu: Menu,
Option<Box<dyn Fn(PopupMenu, &mut Window, &mut Context<PopupMenu>) -> PopupMenu + 'static>>,
anchor: Corner, anchor: Corner,
} }

View File

@@ -1,9 +1,3 @@
use crate::{
h_flex,
list::{self, List, ListDelegate, ListItem},
theme::{scale::ColorScaleStep, ActiveTheme},
v_flex, Icon, IconName, Sizable, Size, StyleSized, StyledExt,
};
use gpui::{ use gpui::{
actions, anchored, canvas, deferred, div, prelude::FluentBuilder, px, rems, AnyElement, App, actions, anchored, canvas, deferred, div, prelude::FluentBuilder, px, rems, AnyElement, App,
AppContext, Bounds, ClickEvent, Context, DismissEvent, ElementId, Entity, EventEmitter, AppContext, Bounds, ClickEvent, Context, DismissEvent, ElementId, Entity, EventEmitter,
@@ -11,6 +5,13 @@ use gpui::{
Pixels, Render, SharedString, StatefulInteractiveElement, Styled, Task, WeakEntity, Window, Pixels, Render, SharedString, StatefulInteractiveElement, Styled, Task, WeakEntity, Window,
}; };
use crate::{
h_flex,
list::{self, List, ListDelegate, ListItem},
theme::{scale::ColorScaleStep, ActiveTheme},
v_flex, Icon, IconName, Sizable, Size, StyleSized, StyledExt,
};
actions!(dropdown, [Up, Down, Enter, Escape]); actions!(dropdown, [Up, Down, Enter, Escape]);
const CONTEXT: &str = "Dropdown"; const CONTEXT: &str = "Dropdown";
@@ -524,11 +525,6 @@ where
cx.notify(); cx.notify();
} }
fn clean(&mut self, _: &ClickEvent, window: &mut Window, cx: &mut Context<Self>) {
self.set_selected_index(None, window, cx);
cx.emit(DropdownEvent::Confirm(None));
}
fn display_title(&self, window: &Window, cx: &App) -> impl IntoElement { fn display_title(&self, window: &Window, cx: &App) -> impl IntoElement {
let title = if let Some(selected_index) = &self.selected_index(window, cx) { let title = if let Some(selected_index) = &self.selected_index(window, cx) {
let title = self let title = self

View File

@@ -271,7 +271,7 @@ impl TextElement {
// print_points_as_svg_path(&line_corners, &points); // print_points_as_svg_path(&line_corners, &points);
let first_p = *points.get(0).unwrap(); let first_p = *points.first().unwrap();
let mut builder = gpui::PathBuilder::fill(); let mut builder = gpui::PathBuilder::fill();
builder.move_to(bounds.origin + first_p); builder.move_to(bounds.origin + first_p);
for p in points.iter().skip(1) { for p in points.iter().skip(1) {
@@ -503,6 +503,16 @@ impl Element for TextElement {
let origin = bounds.origin; let origin = bounds.origin;
let mut offset_y = px(0.); let mut offset_y = px(0.);
if self.input.read(cx).masked {
// Move down offset for vertical centering the *****
if cfg!(target_os = "macos") {
offset_y = px(3.);
} else {
offset_y = px(2.5);
}
}
for line in prepaint.lines.iter() { for line in prepaint.lines.iter() {
let p = point(origin.x, origin.y + offset_y); let p = point(origin.x, origin.y + offset_y);
_ = line.paint(p, line_height, window, cx); _ = line.paint(p, line_height, window, cx);

View File

@@ -1,7 +1,13 @@
//! A text input field that allows the user to enter text. use gpui::{
//! actions, div, point, prelude::FluentBuilder as _, px, AnyElement, App, AppContext, Bounds,
//! Based on the `Input` example from the `gpui` crate. ClipboardItem, Context, Entity, EntityInputHandler, EventEmitter, FocusHandle, Focusable, Half,
//! https://github.com/zed-industries/zed/blob/main/crates/gpui/examples/input.rs InteractiveElement as _, IntoElement, KeyBinding, KeyDownEvent, MouseButton, MouseDownEvent,
MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels, Point, Rems, Render, ScrollHandle,
ScrollWheelEvent, SharedString, Styled as _, UTF16Selection, Window, WrappedLine,
};
use smallvec::SmallVec;
use std::{cell::Cell, ops::Range, rc::Rc};
use unicode_segmentation::*;
use super::{blink_cursor::BlinkCursor, change::Change, element::TextElement}; use super::{blink_cursor::BlinkCursor, change::Change, element::TextElement};
use crate::{ use crate::{
@@ -11,16 +17,6 @@ use crate::{
theme::{scale::ColorScaleStep, ActiveTheme}, theme::{scale::ColorScaleStep, ActiveTheme},
Sizable, Size, StyleSized, StyledExt, Sizable, Size, StyleSized, StyledExt,
}; };
use gpui::{
actions, div, point, prelude::FluentBuilder as _, px, AnyElement, App, AppContext, Bounds,
ClickEvent, ClipboardItem, Context, Entity, EntityInputHandler, EventEmitter, FocusHandle,
Focusable, Half, InteractiveElement as _, IntoElement, KeyBinding, KeyDownEvent, MouseButton,
MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels, Point, Rems, Render,
ScrollHandle, ScrollWheelEvent, SharedString, Styled as _, UTF16Selection, Window, WrappedLine,
};
use smallvec::SmallVec;
use std::{cell::Cell, ops::Range, rc::Rc};
use unicode_segmentation::*;
actions!( actions!(
input, input,
@@ -29,6 +25,8 @@ actions!(
Delete, Delete,
DeleteToBeginningOfLine, DeleteToBeginningOfLine,
DeleteToEndOfLine, DeleteToEndOfLine,
DeleteToPreviousWordStart,
DeleteToNextWordEnd,
Enter, Enter,
Up, Up,
Down, Down,
@@ -45,6 +43,8 @@ actions!(
SelectToEndOfLine, SelectToEndOfLine,
SelectToStart, SelectToStart,
SelectToEnd, SelectToEnd,
SelectToPreviousWordStart,
SelectToNextWordEnd,
ShowCharacterPalette, ShowCharacterPalette,
Copy, Copy,
Cut, Cut,
@@ -55,6 +55,8 @@ actions!(
MoveToEndOfLine, MoveToEndOfLine,
MoveToStart, MoveToStart,
MoveToEnd, MoveToEnd,
MoveToPreviousWord,
MoveToNextWord,
TextChanged, TextChanged,
] ]
); );
@@ -77,6 +79,14 @@ pub fn init(cx: &mut App) {
KeyBinding::new("cmd-backspace", DeleteToBeginningOfLine, Some(CONTEXT)), KeyBinding::new("cmd-backspace", DeleteToBeginningOfLine, Some(CONTEXT)),
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
KeyBinding::new("cmd-delete", DeleteToEndOfLine, Some(CONTEXT)), KeyBinding::new("cmd-delete", DeleteToEndOfLine, Some(CONTEXT)),
#[cfg(target_os = "macos")]
KeyBinding::new("alt-backspace", DeleteToPreviousWordStart, Some(CONTEXT)),
#[cfg(not(target_os = "macos"))]
KeyBinding::new("ctrl-backspace", DeleteToPreviousWordStart, Some(CONTEXT)),
#[cfg(target_os = "macos")]
KeyBinding::new("alt-delete", DeleteToNextWordEnd, Some(CONTEXT)),
#[cfg(not(target_os = "macos"))]
KeyBinding::new("ctrl-delete", DeleteToNextWordEnd, Some(CONTEXT)),
KeyBinding::new("enter", Enter, Some(CONTEXT)), KeyBinding::new("enter", Enter, Some(CONTEXT)),
KeyBinding::new("up", Up, Some(CONTEXT)), KeyBinding::new("up", Up, Some(CONTEXT)),
KeyBinding::new("down", Down, Some(CONTEXT)), KeyBinding::new("down", Down, Some(CONTEXT)),
@@ -99,6 +109,14 @@ pub fn init(cx: &mut App) {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
KeyBinding::new("shift-cmd-right", SelectToEndOfLine, Some(CONTEXT)), KeyBinding::new("shift-cmd-right", SelectToEndOfLine, Some(CONTEXT)),
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
KeyBinding::new("alt-shift-left", SelectToPreviousWordStart, Some(CONTEXT)),
#[cfg(not(target_os = "macos"))]
KeyBinding::new("ctrl-shift-left", SelectToPreviousWordStart, Some(CONTEXT)),
#[cfg(target_os = "macos")]
KeyBinding::new("alt-shift-right", SelectToNextWordEnd, Some(CONTEXT)),
#[cfg(not(target_os = "macos"))]
KeyBinding::new("ctrl-shift-right", SelectToNextWordEnd, Some(CONTEXT)),
#[cfg(target_os = "macos")]
KeyBinding::new("ctrl-cmd-space", ShowCharacterPalette, Some(CONTEXT)), KeyBinding::new("ctrl-cmd-space", ShowCharacterPalette, Some(CONTEXT)),
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
KeyBinding::new("cmd-a", SelectAll, Some(CONTEXT)), KeyBinding::new("cmd-a", SelectAll, Some(CONTEXT)),
@@ -133,6 +151,14 @@ pub fn init(cx: &mut App) {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
KeyBinding::new("cmd-down", MoveToEnd, Some(CONTEXT)), KeyBinding::new("cmd-down", MoveToEnd, Some(CONTEXT)),
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
KeyBinding::new("alt-left", MoveToPreviousWord, Some(CONTEXT)),
#[cfg(target_os = "macos")]
KeyBinding::new("alt-right", MoveToNextWord, Some(CONTEXT)),
#[cfg(not(target_os = "macos"))]
KeyBinding::new("ctrl-left", MoveToPreviousWord, Some(CONTEXT)),
#[cfg(not(target_os = "macos"))]
KeyBinding::new("ctrl-right", MoveToNextWord, Some(CONTEXT)),
#[cfg(target_os = "macos")]
KeyBinding::new("cmd-shift-up", SelectToStart, Some(CONTEXT)), KeyBinding::new("cmd-shift-up", SelectToStart, Some(CONTEXT)),
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
KeyBinding::new("cmd-shift-down", SelectToEnd, Some(CONTEXT)), KeyBinding::new("cmd-shift-down", SelectToEnd, Some(CONTEXT)),
@@ -438,13 +464,13 @@ impl TextInput {
} }
/// Set the disabled state of the input field. /// Set the disabled state of the input field.
pub fn set_disabled(&mut self, disabled: bool, window: &mut Window, cx: &mut Context<Self>) { pub fn set_disabled(&mut self, disabled: bool, _window: &mut Window, cx: &mut Context<Self>) {
self.disabled = disabled; self.disabled = disabled;
cx.notify(); cx.notify();
} }
/// Set the masked state of the input field. /// Set the masked state of the input field.
pub fn set_masked(&mut self, masked: bool, window: &mut Window, cx: &mut Context<Self>) { pub fn set_masked(&mut self, masked: bool, _window: &mut Window, cx: &mut Context<Self>) {
self.masked = masked; self.masked = masked;
cx.notify(); cx.notify();
} }
@@ -474,7 +500,7 @@ impl TextInput {
} }
/// Set the Input size /// Set the Input size
pub fn set_size(&mut self, size: Size, window: &mut Window, cx: &mut Context<Self>) { pub fn set_size(&mut self, size: Size, _window: &mut Window, cx: &mut Context<Self>) {
self.size = size; self.size = size;
cx.notify(); cx.notify();
} }
@@ -550,7 +576,7 @@ impl TextInput {
} }
/// Set true to show indicator at the input right. /// Set true to show indicator at the input right.
pub fn set_loading(&mut self, loading: bool, window: &mut Window, cx: &mut Context<Self>) { pub fn set_loading(&mut self, loading: bool, _window: &mut Window, cx: &mut Context<Self>) {
self.loading = loading; self.loading = loading;
cx.notify(); cx.notify();
} }
@@ -565,7 +591,7 @@ impl TextInput {
} }
/// Focus the input field. /// Focus the input field.
pub fn focus(&self, window: &mut Window, cx: &mut Context<Self>) { pub fn focus(&self, window: &mut Window, _cx: &mut Context<Self>) {
self.focus_handle.focus(window); self.focus_handle.focus(window);
} }
@@ -653,6 +679,25 @@ impl TextInput {
self.move_to(end, window, cx); self.move_to(end, window, cx);
} }
fn move_to_previous_word(
&mut self,
_: &MoveToPreviousWord,
window: &mut Window,
cx: &mut Context<Self>,
) {
let offset = self.previous_start_of_word();
self.move_to(offset, window, cx);
}
fn move_to_next_word(
&mut self,
_: &MoveToNextWord,
window: &mut Window,
cx: &mut Context<Self>,
) {
let offset = self.next_end_of_word();
self.move_to(offset, window, cx);
}
fn select_to_start(&mut self, _: &SelectToStart, window: &mut Window, cx: &mut Context<Self>) { fn select_to_start(&mut self, _: &SelectToStart, window: &mut Window, cx: &mut Context<Self>) {
self.select_to(0, window, cx); self.select_to(0, window, cx);
} }
@@ -682,6 +727,47 @@ impl TextInput {
self.select_to(self.next_boundary(offset), window, cx); self.select_to(self.next_boundary(offset), window, cx);
} }
fn select_to_previous_word(
&mut self,
_: &SelectToPreviousWordStart,
window: &mut Window,
cx: &mut Context<Self>,
) {
let offset = self.previous_start_of_word();
self.select_to(offset, window, cx);
}
fn select_to_next_word(
&mut self,
_: &SelectToNextWordEnd,
window: &mut Window,
cx: &mut Context<Self>,
) {
let offset = self.next_end_of_word();
self.select_to(offset, window, cx);
}
/// Return the start offset of the previous word.
fn previous_start_of_word(&mut self) -> usize {
let offset = self.selected_range.start;
let prev_str = &self.text[..offset].to_string();
UnicodeSegmentation::split_word_bound_indices(prev_str as &str)
.filter(|(_, s)| !s.trim_start().is_empty())
.next_back()
.map(|(i, _)| i)
.unwrap_or(0)
}
/// Return the next end offset of the next word.
fn next_end_of_word(&mut self) -> usize {
let offset = self.cursor_offset();
let next_str = &self.text[offset..].to_string();
UnicodeSegmentation::split_word_bound_indices(next_str as &str)
.find(|(_, s)| !s.trim_start().is_empty())
.map(|(i, s)| offset + i + s.len())
.unwrap_or(self.text.len())
}
/// Get start of line /// Get start of line
fn start_of_line(&mut self, window: &mut Window, cx: &mut Context<Self>) -> usize { fn start_of_line(&mut self, window: &mut Window, cx: &mut Context<Self>) -> usize {
if self.is_single_line() { if self.is_single_line() {
@@ -689,13 +775,12 @@ impl TextInput {
} }
let offset = self.previous_boundary(self.cursor_offset()); let offset = self.previous_boundary(self.cursor_offset());
let line = self
.text_for_range(self.range_to_utf16(&(0..offset + 1)), &mut None, window, cx) self.text_for_range(self.range_to_utf16(&(0..offset + 1)), &mut None, window, cx)
.unwrap_or_default() .unwrap_or_default()
.rfind('\n') .rfind('\n')
.map(|i| i + 1) .map(|i| i + 1)
.unwrap_or(0); .unwrap_or(0)
line
} }
/// Get end of line /// Get end of line
@@ -779,6 +864,38 @@ impl TextInput {
self.pause_blink_cursor(cx); self.pause_blink_cursor(cx);
} }
fn delete_previous_word(
&mut self,
_: &DeleteToPreviousWordStart,
window: &mut Window,
cx: &mut Context<Self>,
) {
let offset = self.previous_start_of_word();
self.replace_text_in_range(
Some(self.range_to_utf16(&(offset..self.cursor_offset()))),
"",
window,
cx,
);
self.pause_blink_cursor(cx);
}
fn delete_next_word(
&mut self,
_: &DeleteToNextWordEnd,
window: &mut Window,
cx: &mut Context<Self>,
) {
let offset = self.next_end_of_word();
self.replace_text_in_range(
Some(self.range_to_utf16(&(self.cursor_offset()..offset))),
"",
window,
cx,
);
self.pause_blink_cursor(cx);
}
fn enter(&mut self, _: &Enter, window: &mut Window, cx: &mut Context<Self>) { fn enter(&mut self, _: &Enter, window: &mut Window, cx: &mut Context<Self>) {
if self.is_multi_line() { if self.is_multi_line() {
let is_eof = self.selected_range.end == self.text.len(); let is_eof = self.selected_range.end == self.text.len();
@@ -795,10 +912,6 @@ impl TextInput {
cx.emit(InputEvent::PressEnter); cx.emit(InputEvent::PressEnter);
} }
fn clean(&mut self, _: &ClickEvent, window: &mut Window, cx: &mut Context<Self>) {
self.replace_text("", window, cx);
}
fn on_mouse_down( fn on_mouse_down(
&mut self, &mut self,
event: &MouseDownEvent, event: &MouseDownEvent,
@@ -1122,7 +1235,7 @@ impl TextInput {
cx.notify() cx.notify()
} }
fn unselect(&mut self, window: &mut Window, cx: &mut Context<Self>) { fn unselect(&mut self, _window: &mut Window, cx: &mut Context<Self>) {
self.selected_range = self.cursor_offset()..self.cursor_offset(); self.selected_range = self.cursor_offset()..self.cursor_offset();
cx.notify() cx.notify()
} }
@@ -1209,7 +1322,7 @@ impl TextInput {
fn on_key_down_for_blink_cursor( fn on_key_down_for_blink_cursor(
&mut self, &mut self,
_: &KeyDownEvent, _: &KeyDownEvent,
window: &mut Window, _window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
self.pause_blink_cursor(cx) self.pause_blink_cursor(cx)
@@ -1272,7 +1385,7 @@ impl EntityInputHandler for TextInput {
range_utf16: Range<usize>, range_utf16: Range<usize>,
adjusted_range: &mut Option<Range<usize>>, adjusted_range: &mut Option<Range<usize>>,
_window: &mut Window, _window: &mut Window,
cx: &mut Context<Self>, _cx: &mut Context<Self>,
) -> Option<String> { ) -> Option<String> {
let range = self.range_from_utf16(&range_utf16); let range = self.range_from_utf16(&range_utf16);
adjusted_range.replace(self.range_to_utf16(&range)); adjusted_range.replace(self.range_to_utf16(&range));
@@ -1283,7 +1396,7 @@ impl EntityInputHandler for TextInput {
&mut self, &mut self,
_ignore_disabled_input: bool, _ignore_disabled_input: bool,
_window: &mut Window, _window: &mut Window,
cx: &mut Context<Self>, _cx: &mut Context<Self>,
) -> Option<UTF16Selection> { ) -> Option<UTF16Selection> {
Some(UTF16Selection { Some(UTF16Selection {
range: self.range_to_utf16(&self.selected_range), range: self.range_to_utf16(&self.selected_range),
@@ -1294,14 +1407,14 @@ impl EntityInputHandler for TextInput {
fn marked_text_range( fn marked_text_range(
&self, &self,
_window: &mut Window, _window: &mut Window,
cx: &mut Context<Self>, _cx: &mut Context<Self>,
) -> Option<Range<usize>> { ) -> Option<Range<usize>> {
self.marked_range self.marked_range
.as_ref() .as_ref()
.map(|range| self.range_to_utf16(range)) .map(|range| self.range_to_utf16(range))
} }
fn unmark_text(&mut self, _window: &mut Window, cx: &mut Context<Self>) { fn unmark_text(&mut self, _window: &mut Window, _cx: &mut Context<Self>) {
self.marked_range = None; self.marked_range = None;
} }
@@ -1437,6 +1550,8 @@ impl Render for TextInput {
.on_action(cx.listener(Self::delete)) .on_action(cx.listener(Self::delete))
.on_action(cx.listener(Self::delete_to_beginning_of_line)) .on_action(cx.listener(Self::delete_to_beginning_of_line))
.on_action(cx.listener(Self::delete_to_end_of_line)) .on_action(cx.listener(Self::delete_to_end_of_line))
.on_action(cx.listener(Self::delete_previous_word))
.on_action(cx.listener(Self::delete_next_word))
.on_action(cx.listener(Self::enter)) .on_action(cx.listener(Self::enter))
}) })
.on_action(cx.listener(Self::left)) .on_action(cx.listener(Self::left))
@@ -1452,10 +1567,14 @@ impl Render for TextInput {
.on_action(cx.listener(Self::select_all)) .on_action(cx.listener(Self::select_all))
.on_action(cx.listener(Self::select_to_start_of_line)) .on_action(cx.listener(Self::select_to_start_of_line))
.on_action(cx.listener(Self::select_to_end_of_line)) .on_action(cx.listener(Self::select_to_end_of_line))
.on_action(cx.listener(Self::select_to_previous_word))
.on_action(cx.listener(Self::select_to_next_word))
.on_action(cx.listener(Self::home)) .on_action(cx.listener(Self::home))
.on_action(cx.listener(Self::end)) .on_action(cx.listener(Self::end))
.on_action(cx.listener(Self::move_to_start)) .on_action(cx.listener(Self::move_to_start))
.on_action(cx.listener(Self::move_to_end)) .on_action(cx.listener(Self::move_to_end))
.on_action(cx.listener(Self::move_to_previous_word))
.on_action(cx.listener(Self::move_to_next_word))
.on_action(cx.listener(Self::select_to_start)) .on_action(cx.listener(Self::select_to_start))
.on_action(cx.listener(Self::select_to_end)) .on_action(cx.listener(Self::select_to_end))
.on_action(cx.listener(Self::show_character_palette)) .on_action(cx.listener(Self::show_character_palette))

View File

@@ -20,6 +20,8 @@ pub fn init(cx: &mut App) {
cx.bind_keys([KeyBinding::new("escape", Escape, Some(CONTEXT))]) cx.bind_keys([KeyBinding::new("escape", Escape, Some(CONTEXT))])
} }
type OnClose = Rc<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>;
#[derive(IntoElement)] #[derive(IntoElement)]
pub struct Modal { pub struct Modal {
base: Div, base: Div,
@@ -29,7 +31,7 @@ pub struct Modal {
width: Pixels, width: Pixels,
max_width: Option<Pixels>, max_width: Option<Pixels>,
margin_top: Option<Pixels>, margin_top: Option<Pixels>,
on_close: Rc<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>, on_close: OnClose,
show_close: bool, show_close: bool,
keyboard: bool, keyboard: bool,
/// This will be change when open the modal, the focus handle is create when open the modal. /// This will be change when open the modal, the focus handle is create when open the modal.

View File

@@ -16,10 +16,12 @@ pub fn init(cx: &mut App) {
cx.bind_keys([KeyBinding::new("escape", Escape, Some(CONTEXT))]) cx.bind_keys([KeyBinding::new("escape", Escape, Some(CONTEXT))])
} }
type PopoverChild<T> = Rc<dyn Fn(&mut Window, &mut Context<T>) -> AnyElement>;
pub struct PopoverContent { pub struct PopoverContent {
focus_handle: FocusHandle, focus_handle: FocusHandle,
content: Rc<dyn Fn(&mut Window, &mut Context<Self>) -> AnyElement>,
max_width: Option<Pixels>, max_width: Option<Pixels>,
child: PopoverChild<Self>,
} }
impl PopoverContent { impl PopoverContent {
@@ -31,7 +33,7 @@ impl PopoverContent {
Self { Self {
focus_handle, focus_handle,
content: Rc::new(content), child: Rc::new(content),
max_width: None, max_width: None,
} }
} }
@@ -58,15 +60,18 @@ impl Render for PopoverContent {
.on_action(cx.listener(|_, _: &Escape, _, cx| cx.emit(DismissEvent))) .on_action(cx.listener(|_, _: &Escape, _, cx| cx.emit(DismissEvent)))
.p_2() .p_2()
.when_some(self.max_width, |this, v| this.max_w(v)) .when_some(self.max_width, |this, v| this.max_w(v))
.child(self.content.clone()(window, cx)) .child(self.child.clone()(window, cx))
} }
} }
type Trigger = Option<Box<dyn FnOnce(bool, &Window, &App) -> AnyElement + 'static>>;
type Content<M> = Option<Rc<dyn Fn(&mut Window, &mut App) -> Entity<M> + 'static>>;
pub struct Popover<M: ManagedView> { pub struct Popover<M: ManagedView> {
id: ElementId, id: ElementId,
anchor: Corner, anchor: Corner,
trigger: Option<Box<dyn FnOnce(bool, &Window, &App) -> AnyElement + 'static>>, trigger: Trigger,
content: Option<Rc<dyn Fn(&mut Window, &mut App) -> Entity<M> + 'static>>, content: Content<M>,
/// Style for trigger element. /// Style for trigger element.
/// This is used for hotfix the trigger element style to support w_full. /// This is used for hotfix the trigger element style to support w_full.
trigger_style: Option<StyleRefinement>, trigger_style: Option<StyleRefinement>,

View File

@@ -67,10 +67,13 @@ enum PopupMenuItem {
icon: Option<Icon>, icon: Option<Icon>,
label: SharedString, label: SharedString,
action: Option<Box<dyn Action>>, action: Option<Box<dyn Action>>,
#[allow(clippy::type_complexity)]
handler: Rc<dyn Fn(&mut Window, &mut App)>, handler: Rc<dyn Fn(&mut Window, &mut App)>,
}, },
ElementItem { ElementItem {
#[allow(clippy::type_complexity)]
render: Box<dyn Fn(&mut Window, &mut App) -> AnyElement + 'static>, render: Box<dyn Fn(&mut Window, &mut App) -> AnyElement + 'static>,
#[allow(clippy::type_complexity)]
handler: Rc<dyn Fn(&mut Window, &mut App)>, handler: Rc<dyn Fn(&mut Window, &mut App)>,
}, },
Submenu { Submenu {
@@ -249,6 +252,7 @@ impl PopupMenu {
self self
} }
#[allow(clippy::type_complexity)]
fn wrap_handler(&self, action: Box<dyn Action>) -> Rc<dyn Fn(&mut Window, &mut App)> { fn wrap_handler(&self, action: Box<dyn Action>) -> Rc<dyn Fn(&mut Window, &mut App)> {
let action_focus_handle = self.action_focus_handle.clone(); let action_focus_handle = self.action_focus_handle.clone();

View File

@@ -1,5 +1,3 @@
use super::resize_handle;
use crate::{h_flex, v_flex, AxisExt};
use gpui::{ use gpui::{
canvas, div, prelude::FluentBuilder, px, relative, Along, AnyElement, AnyView, App, AppContext, canvas, div, prelude::FluentBuilder, px, relative, Along, AnyElement, AnyView, App, AppContext,
Axis, Bounds, Context, Element, Entity, EntityId, EventEmitter, IntoElement, IsZero, Axis, Bounds, Context, Element, Entity, EntityId, EventEmitter, IntoElement, IsZero,
@@ -8,6 +6,9 @@ use gpui::{
}; };
use std::rc::Rc; use std::rc::Rc;
use super::resize_handle;
use crate::{h_flex, v_flex, AxisExt};
pub(crate) const PANEL_MIN_SIZE: Pixels = px(100.); pub(crate) const PANEL_MIN_SIZE: Pixels = px(100.);
pub enum ResizablePanelEvent { pub enum ResizablePanelEvent {
@@ -90,11 +91,6 @@ impl ResizablePanelGroup {
self self
} }
/// Returns the sizes of the resizable panels.
pub(crate) fn sizes(&self) -> Vec<Pixels> {
self.sizes.clone()
}
/// Calculates the sum of all panel sizes within the group. /// Calculates the sum of all panel sizes within the group.
pub fn total_size(&self) -> Pixels { pub fn total_size(&self) -> Pixels {
self.sizes.iter().fold(px(0.0), |acc, &size| acc + size) self.sizes.iter().fold(px(0.0), |acc, &size| acc + size)