panel: Add set_active, set_zoomed method to Panel trait. (#501)

It will called when the panel active, zoom state changed.
This commit is contained in:
Jason Lee 2024-12-19 10:29:58 +08:00 committed by GitHub
parent 4e3b988e24
commit 4b211bfe21
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 92 additions and 11 deletions

View file

@ -78,6 +78,12 @@ pub fn init(cx: &mut AppContext) {
let view = cx.new_view(|cx| {
let (title, description, closeable, zoomable, story) = story_state.to_story(cx);
let mut container = StoryContainer::new(cx).story(story, story_state.story_klass);
cx.on_focus_in(&container.focus_handle, |this: &mut StoryContainer, _| {
println!("StoryContainer focus in: {}", this.name);
})
.detach();
container.name = title.into();
container.description = description.into();
container.closeable = closeable;
@ -298,6 +304,14 @@ impl Panel for StoryContainer {
self.zoomable
}
fn set_zoomed(&self, zoomed: bool, _cx: &ViewContext<Self>) {
println!("panel: {} zoomed: {}", self.name, zoomed);
}
fn set_active(&self, active: bool, _cx: &ViewContext<Self>) {
println!("panel: {} active: {}", self.name, active);
}
fn popup_menu(&self, menu: PopupMenu, _cx: &WindowContext) -> PopupMenu {
menu.track_focus(&self.focus_handle)
.menu("Info", Box::new(ShowPanelInfo))

View file

@ -3,7 +3,7 @@ use std::{collections::HashMap, sync::Arc};
use crate::{button::Button, popup_menu::PopupMenu};
use gpui::{
AnyElement, AnyView, AppContext, EventEmitter, FocusHandle, FocusableView, Global, Hsla,
IntoElement, SharedString, View, WeakView, WindowContext,
IntoElement, SharedString, View, ViewContext, WeakView, WindowContext,
};
use rust_i18n::t;
@ -30,6 +30,8 @@ pub struct TitleStyle {
pub foreground: Hsla,
}
/// The Panel trait used to define the panel.
#[allow(unused_variables)]
pub trait Panel: EventEmitter<PanelEvent> + FocusableView {
/// The name of the panel used to serialize, deserialize and identify the panel.
///
@ -38,47 +40,66 @@ pub trait Panel: EventEmitter<PanelEvent> + FocusableView {
fn panel_name(&self) -> &'static str;
/// The title of the panel
fn title(&self, _cx: &WindowContext) -> AnyElement {
fn title(&self, cx: &WindowContext) -> AnyElement {
SharedString::from(t!("Dock.Unnamed")).into_any_element()
}
/// The theme of the panel title, default is `None`.
fn title_style(&self, _cx: &WindowContext) -> Option<TitleStyle> {
fn title_style(&self, cx: &WindowContext) -> Option<TitleStyle> {
None
}
/// Whether the panel can be closed, default is `true`.
fn closeable(&self, _cx: &WindowContext) -> bool {
fn closeable(&self, cx: &WindowContext) -> bool {
true
}
/// Return true if the panel is zoomable, default is `false`.
fn zoomable(&self, _cx: &WindowContext) -> bool {
fn zoomable(&self, cx: &WindowContext) -> bool {
true
}
/// Set active state of the panel.
///
/// This method will be called when the panel is active or inactive.
///
/// The last_active_panel and current_active_panel will be touched when the panel is active.
#[allow(unused_variables)]
fn set_active(&self, active: bool, cx: &ViewContext<Self>) {}
/// Set zoomed state of the panel.
///
/// This method will be called when the panel is zoomed or unzoomed.
///
/// Only current Panel will touch this method.
fn set_zoomed(&self, zoomed: bool, cx: &ViewContext<Self>) {}
/// The addition popup menu of the panel, default is `None`.
fn popup_menu(&self, this: PopupMenu, _cx: &WindowContext) -> PopupMenu {
fn popup_menu(&self, this: PopupMenu, cx: &WindowContext) -> PopupMenu {
this
}
/// The addition toolbar buttons of the panel used to show in the right of the title bar, default is `None`.
fn toolbar_buttons(&self, _cx: &WindowContext) -> Vec<Button> {
fn toolbar_buttons(&self, cx: &WindowContext) -> Vec<Button> {
vec![]
}
/// Dump the panel, used to serialize the panel.
fn dump(&self, _cx: &AppContext) -> PanelState {
fn dump(&self, cx: &AppContext) -> PanelState {
PanelState::new(self)
}
}
/// The PanelView trait used to define the panel view.
#[allow(unused_variables)]
pub trait PanelView: 'static + Send + Sync {
fn panel_name(&self, _cx: &AppContext) -> &'static str;
fn title(&self, _cx: &WindowContext) -> AnyElement;
fn title_style(&self, _cx: &WindowContext) -> Option<TitleStyle>;
fn panel_name(&self, cx: &AppContext) -> &'static str;
fn title(&self, cx: &WindowContext) -> AnyElement;
fn title_style(&self, cx: &WindowContext) -> Option<TitleStyle>;
fn closeable(&self, cx: &WindowContext) -> bool;
fn zoomable(&self, cx: &WindowContext) -> bool;
fn set_active(&self, active: bool, cx: &mut WindowContext);
fn set_zoomed(&self, zoomed: bool, cx: &mut WindowContext);
fn popup_menu(&self, menu: PopupMenu, cx: &WindowContext) -> PopupMenu;
fn toolbar_buttons(&self, cx: &WindowContext) -> Vec<Button>;
fn view(&self) -> AnyView;
@ -107,6 +128,18 @@ impl<T: Panel> PanelView for View<T> {
self.read(cx).zoomable(cx)
}
fn set_active(&self, active: bool, cx: &mut WindowContext) {
self.update(cx, |this, cx| {
this.set_active(active, cx);
})
}
fn set_zoomed(&self, zoomed: bool, cx: &mut WindowContext) {
self.update(cx, |this, cx| {
this.set_zoomed(zoomed, cx);
})
}
fn popup_menu(&self, menu: PopupMenu, cx: &WindowContext) -> PopupMenu {
self.read(cx).popup_menu(menu, cx)
}

View file

@ -165,9 +165,31 @@ impl TabPanel {
}
fn set_active_ix(&mut self, ix: usize, cx: &mut ViewContext<Self>) {
if ix == self.active_ix {
return;
}
let last_active_ix = self.active_ix;
self.active_ix = ix;
self.tab_bar_scroll_handle.scroll_to_item(ix);
self.focus_active_panel(cx);
// Sync the active state to all panels
cx.spawn(|view, mut cx| async move {
_ = cx.update(|cx| {
_ = view.update(cx, |view, cx| {
if let Some(last_active) = view.panels.get(last_active_ix) {
last_active.set_active(false, cx);
}
if let Some(active) = view.panels.get(view.active_ix) {
active.set_active(true, cx);
}
});
});
})
.detach();
cx.emit(PanelEvent::LayoutChanged);
cx.notify();
}
@ -879,6 +901,18 @@ impl TabPanel {
cx.emit(PanelEvent::ZoomOut)
}
self.is_zoomed = !self.is_zoomed;
cx.spawn(|view, mut cx| {
let is_zoomed = self.is_zoomed;
async move {
_ = cx.update(|cx| {
_ = view.update(cx, |view, cx| {
view.set_zoomed(is_zoomed, cx);
});
});
}
})
.detach();
}
fn on_action_close_panel(&mut self, _: &ClosePanel, cx: &mut ViewContext<Self>) {