update tabbar
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 5.5V18.5H19.25C19.9404 18.5 20.5 17.9404 20.5 17.25V6.75C20.5 6.05964 19.9404 5.5 19.25 5.5H9ZM2 6.75C2 5.23122 3.23122 4 4.75 4H19.25C20.7688 4 22 5.23122 22 6.75V17.25C22 18.7688 20.7688 20 19.25 20H4.75C3.23122 20 2 18.7688 2 17.25V6.75Z" fill="currentColor"/>
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.75 4C3.23122 4 2 5.23122 2 6.75V17.25C2 18.7688 3.23122 20 4.75 20H19.25C20.7688 20 22 18.7688 22 17.25V6.75C22 5.23122 20.7688 4 19.25 4H4.75ZM3.5 6.75C3.5 6.05964 4.05964 5.5 4.75 5.5H10.5V18.5H4.75C4.05964 18.5 3.5 17.9404 3.5 17.25V6.75Z" fill="currentColor"/><path fill-rule="evenodd" clip-rule="evenodd" d="M7 9.5C6.44772 9.5 6 9.05228 6 8.5C6 7.94772 6.44772 7.5 7 7.5C7.55228 7.5 8 7.94772 8 8.5C8 9.05228 7.55228 9.5 7 9.5ZM7 13C6.44772 13 6 12.5523 6 12C6 11.4477 6.44772 11 7 11C7.55228 11 8 11.4477 8 12C8 12.5523 7.55228 13 7 13ZM7 16.5C6.44772 16.5 6 16.0523 6 15.5C6 14.9477 6.44772 14.5 7 14.5C7.55228 14.5 8 14.9477 8 15.5C8 16.0523 7.55228 16.5 7 16.5Z" fill="currentColor"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 396 B After Width: | Height: | Size: 826 B |
@@ -1,3 +1,3 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
||||||
<path d="M2.75 6.75C2.75 5.64543 3.64543 4.75 4.75 4.75H19.25C20.3546 4.75 21.25 5.64543 21.25 6.75V17.25C21.25 18.3546 20.3546 19.25 19.25 19.25H4.75C3.64543 19.25 2.75 18.3546 2.75 17.25V6.75Z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M8.25 5V12V19" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>
|
<path d="M11.25 4.75H4.75C3.64543 4.75 2.75 5.64543 2.75 6.75V17.25C2.75 18.3546 3.64543 19.25 4.75 19.25H11.25M11.25 4.75H19.25C20.3546 4.75 21.25 5.64543 21.25 6.75V17.25C21.25 18.3546 20.3546 19.25 19.25 19.25H11.25M11.25 4.75V19.25" stroke="currentColor" stroke-width="1.5" stroke-linecap="square" stroke-linejoin="round"/><path d="M6.25 8.5C6.25 8.91421 6.58579 9.25 7 9.25C7.41421 9.25 7.75 8.91421 7.75 8.5C7.75 8.08579 7.41421 7.75 7 7.75C6.58579 7.75 6.25 8.08579 6.25 8.5ZM6.25 12C6.25 12.4142 6.58579 12.75 7 12.75C7.41421 12.75 7.75 12.4142 7.75 12C7.75 11.5858 7.41421 11.25 7 11.25C6.58579 11.25 6.25 11.5858 6.25 12ZM6.25 15.5C6.25 15.9142 6.58579 16.25 7 16.25C7.41421 16.25 7.75 15.9142 7.75 15.5C7.75 15.0858 7.41421 14.75 7 14.75C6.58579 14.75 6.25 15.0858 6.25 15.5Z" fill="currentColor" stroke="currentColor" stroke-width="0.5"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 433 B After Width: | Height: | Size: 931 B |
@@ -1983,12 +1983,13 @@ impl Panel for ChatPanel {
|
|||||||
let seed = this.display_image_seed(cx);
|
let seed = this.display_image_seed(cx);
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_1p5()
|
.gap_1()
|
||||||
|
.text_xs()
|
||||||
.child(Avatar::new(picture).seed(seed).xsmall())
|
.child(Avatar::new(picture).seed(seed).xsmall())
|
||||||
.child(label)
|
.child(label)
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
})
|
})
|
||||||
.unwrap_or(div().child("Unknown").into_any_element())
|
.unwrap_or(div().text_xs().child("Unknown").into_any_element())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toolbar_buttons(&self, _window: &Window, _cx: &App) -> Vec<Button> {
|
fn toolbar_buttons(&self, _window: &Window, _cx: &App) -> Vec<Button> {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use concord::cord06::RekeyScope;
|
|||||||
use concord::derive::{channel_group_key, grant_locator};
|
use concord::derive::{channel_group_key, grant_locator};
|
||||||
use concord::state::{ChannelCursor, ChannelKeyRef, CommunityState, HeldKey, HeldRoot};
|
use concord::state::{ChannelCursor, ChannelKeyRef, CommunityState, HeldKey, HeldRoot};
|
||||||
use concord::{ChannelId, CommunityId, Epoch};
|
use concord::{ChannelId, CommunityId, Epoch};
|
||||||
use gpui::{App, AppContext, Context, EventEmitter, Task};
|
use gpui::{App, AppContext, Context, EventEmitter, SharedString, Task};
|
||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
use smallvec::{SmallVec, smallvec};
|
use smallvec::{SmallVec, smallvec};
|
||||||
use state::NostrRegistry;
|
use state::NostrRegistry;
|
||||||
@@ -178,15 +178,16 @@ impl Community {
|
|||||||
&self.state
|
&self.state
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> String {
|
pub fn name(&self) -> SharedString {
|
||||||
if let Some(metadata) = &self.control.community {
|
if let Some(metadata) = &self.control.community {
|
||||||
return metadata.name.clone();
|
return SharedString::from(&metadata.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state
|
self.state
|
||||||
.name
|
.name
|
||||||
.clone()
|
.as_ref()
|
||||||
.unwrap_or_else(|| self.state.id.to_hex())
|
.map(SharedString::from)
|
||||||
|
.unwrap_or_else(|| SharedString::from("Unknown"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn control(&self) -> &ControlFold {
|
pub fn control(&self) -> &ControlFold {
|
||||||
|
|||||||
@@ -721,12 +721,13 @@ impl Panel for CommunityPanel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_1p5()
|
.gap_1()
|
||||||
|
.text_xs()
|
||||||
.child(avatar)
|
.child(avatar)
|
||||||
.child(SharedString::from(community.name()))
|
.child(community.name())
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|_| div().child("Unknown").into_any_element())
|
.unwrap_or_else(|_| div().text_xs().child("Unknown").into_any_element())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toolbar_buttons(&self, _window: &Window, _cx: &App) -> Vec<Button> {
|
fn toolbar_buttons(&self, _window: &Window, _cx: &App) -> Vec<Button> {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ pub(super) fn avatar_size(size: Size) -> AbsoluteLength {
|
|||||||
Size::Large => px(64.).into(),
|
Size::Large => px(64.).into(),
|
||||||
Size::Medium => px(32.).into(),
|
Size::Medium => px(32.).into(),
|
||||||
Size::Small => px(24.).into(),
|
Size::Small => px(24.).into(),
|
||||||
Size::XSmall => px(20.).into(),
|
Size::XSmall => px(18.).into(),
|
||||||
Size::Size(size) => size.into(),
|
Size::Size(size) => size.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-185
@@ -5,11 +5,11 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use gpui::prelude::FluentBuilder as _;
|
use gpui::prelude::FluentBuilder as _;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Anchor, AnyElement, AnyView, App, AppContext as _, Bounds, Context, Div, Empty, Entity,
|
AnyElement, AnyView, App, AppContext as _, Bounds, Context, Div, Empty, Entity,
|
||||||
GlobalElementId, InspectorElementId, InteractiveElement as _, IntoElement, LayoutId,
|
GlobalElementId, InspectorElementId, InteractiveElement as _, IntoElement, LayoutId,
|
||||||
MouseButton, MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels, Render, ScrollHandle,
|
MouseButton, MouseMoveEvent, MouseUpEvent, ParentElement as _, Pixels, Render, ScrollHandle,
|
||||||
SharedString, Stateful, StatefulInteractiveElement as _, Style, StyleRefinement, Styled as _,
|
SharedString, Stateful, StatefulInteractiveElement as _, Style, StyleRefinement, Styled as _,
|
||||||
WeakEntity, Window, actions, div, px, rems,
|
WeakEntity, Window, actions, div, px,
|
||||||
};
|
};
|
||||||
pub use gpui_base::dock::{DockArea, DockLayout, DockPlacement};
|
pub use gpui_base::dock::{DockArea, DockLayout, DockPlacement};
|
||||||
use gpui_base::dock::{
|
use gpui_base::dock::{
|
||||||
@@ -20,7 +20,6 @@ use gpui_base::{Placement, ResizeHandleContext, Side};
|
|||||||
use theme::{ActiveTheme, TABBAR_HEIGHT};
|
use theme::{ActiveTheme, TABBAR_HEIGHT};
|
||||||
|
|
||||||
use crate::button::{Button, ButtonVariants as _};
|
use crate::button::{Button, ButtonVariants as _};
|
||||||
use crate::menu::DropdownMenu as _;
|
|
||||||
use crate::resizable::{resize_handle, resize_handle_appearance};
|
use crate::resizable::{resize_handle, resize_handle_appearance};
|
||||||
use crate::tab::Tab;
|
use crate::tab::Tab;
|
||||||
use crate::tab::tab_bar::TabBar;
|
use crate::tab::tab_bar::TabBar;
|
||||||
@@ -429,9 +428,6 @@ impl TabGroupSkin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Whether this group is the left dock's root with a single panel.
|
/// Whether this group is the left dock's root with a single panel.
|
||||||
///
|
|
||||||
/// Such a group draws no tab bar, so its panel owns the window's top-left
|
|
||||||
/// corner — including the space the macOS traffic lights overlay.
|
|
||||||
fn is_plain_left_group(&self, group: &TabGroupContext, cx: &App) -> bool {
|
fn is_plain_left_group(&self, group: &TabGroupContext, cx: &App) -> bool {
|
||||||
let Some(area) = self.shared.area() else {
|
let Some(area) = self.shared.area() else {
|
||||||
return false;
|
return false;
|
||||||
@@ -444,9 +440,6 @@ impl TabGroupSkin {
|
|||||||
&& group.panels().len() == 1
|
&& group.panels().len() == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether this group is the topmost-left group on screen, which sits under
|
|
||||||
/// the native macOS traffic lights. The left dock's group is leftmost while
|
|
||||||
/// it is open and holds a panel; the center's is leftmost otherwise.
|
|
||||||
fn is_leftmost_top_group(&self, group: &TabGroupContext, cx: &App) -> bool {
|
fn is_leftmost_top_group(&self, group: &TabGroupContext, cx: &App) -> bool {
|
||||||
let Some(area) = self.shared.area() else {
|
let Some(area) = self.shared.area() else {
|
||||||
return false;
|
return false;
|
||||||
@@ -464,172 +457,6 @@ impl TabGroupSkin {
|
|||||||
tree.and_then(|tree| left_top_group(tree.root())) == Some(group.node())
|
tree.and_then(|tree| left_top_group(tree.root())) == Some(group.node())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_toolbar(
|
|
||||||
&self,
|
|
||||||
group: &TabGroupContext,
|
|
||||||
window: &mut Window,
|
|
||||||
cx: &mut App,
|
|
||||||
) -> impl IntoElement {
|
|
||||||
let zoomed = group.is_zoomed();
|
|
||||||
let closable = group.is_closable();
|
|
||||||
let zoomable = group.active_panel().is_some_and(|panel| panel.zoomable(cx));
|
|
||||||
|
|
||||||
let zoom_label = if zoomed { "Zoom Out" } else { "Zoom In" };
|
|
||||||
|
|
||||||
let buttons = group
|
|
||||||
.active_panel()
|
|
||||||
.and_then(PanelHandle::of)
|
|
||||||
.map(|handle| handle.panel().toolbar_buttons(window, cx))
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let menu_panel = group
|
|
||||||
.active_panel()
|
|
||||||
.and_then(PanelHandle::of)
|
|
||||||
.map(|handle| handle.panel().clone());
|
|
||||||
|
|
||||||
h_flex()
|
|
||||||
.p_0p5()
|
|
||||||
.gap_1p5()
|
|
||||||
.occlude()
|
|
||||||
.rounded_full()
|
|
||||||
.children(buttons.into_iter().map(|button| button.small().ghost()))
|
|
||||||
.when(zoomed, |this| {
|
|
||||||
this.child(
|
|
||||||
Button::new("zoom")
|
|
||||||
.icon(IconName::Zoom)
|
|
||||||
.small()
|
|
||||||
.ghost()
|
|
||||||
.tooltip("Zoom Out")
|
|
||||||
.on_click({
|
|
||||||
let group = TabGroupContext::clone(group);
|
|
||||||
move |_, window, cx| group.toggle_zoom(window, cx)
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.child(
|
|
||||||
Button::new("menu")
|
|
||||||
.icon(IconName::Ellipsis)
|
|
||||||
.small()
|
|
||||||
.ghost()
|
|
||||||
.dropdown_menu({
|
|
||||||
move |menu, _, cx| {
|
|
||||||
let menu = match menu_panel.clone() {
|
|
||||||
Some(panel) => panel.popup_menu(menu, cx),
|
|
||||||
None => menu,
|
|
||||||
};
|
|
||||||
|
|
||||||
menu.when(zoomable, |this| {
|
|
||||||
this.separator().menu(zoom_label, Box::new(ToggleZoom))
|
|
||||||
})
|
|
||||||
.when(closable, |this| {
|
|
||||||
this.separator().menu("Close", Box::new(ClosePanel))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.anchor(Anchor::TopRight),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_title(
|
|
||||||
&self,
|
|
||||||
group: &TabGroupContext,
|
|
||||||
ix: usize,
|
|
||||||
window: &mut Window,
|
|
||||||
cx: &mut App,
|
|
||||||
) -> AnyElement {
|
|
||||||
let panel = group.panels()[ix].clone();
|
|
||||||
let left_button = self.dock_toggle_button(DockPlacement::Left, group, cx);
|
|
||||||
let bottom_button = self.dock_toggle_button(DockPlacement::Bottom, group, cx);
|
|
||||||
let right_button = self.dock_toggle_button(DockPlacement::Right, group, cx);
|
|
||||||
let has_leading = left_button.is_some() || bottom_button.is_some();
|
|
||||||
let drag = tab_drag(group, ix, cx);
|
|
||||||
let is_title_bar = self.is_title_bar_group(group, cx);
|
|
||||||
let needs_traffic_light_padding =
|
|
||||||
cfg!(target_os = "macos") && self.is_leftmost_top_group(group, cx);
|
|
||||||
let trailing_chrome = is_title_bar
|
|
||||||
.then(|| self.shared.chrome.trailing(window, cx))
|
|
||||||
.flatten();
|
|
||||||
|
|
||||||
let bar = h_flex()
|
|
||||||
.id("tab-title-bar")
|
|
||||||
.justify_between()
|
|
||||||
.items_center()
|
|
||||||
.line_height(rems(1.0))
|
|
||||||
.h(TABBAR_HEIGHT)
|
|
||||||
.bg(cx.theme().panel_background)
|
|
||||||
.when(left_button.is_some(), |this| this.pl_2())
|
|
||||||
.when(right_button.is_some(), |this| this.pr_2())
|
|
||||||
.when(has_leading, |this| {
|
|
||||||
this.child(
|
|
||||||
h_flex()
|
|
||||||
.flex_shrink_0()
|
|
||||||
.mr_1()
|
|
||||||
.gap_1()
|
|
||||||
.children(left_button)
|
|
||||||
.children(bottom_button),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.when(needs_traffic_light_padding, |this| {
|
|
||||||
this.pl(px(TRAFFIC_LIGHT_PADDING))
|
|
||||||
})
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.id("tab")
|
|
||||||
.flex_initial()
|
|
||||||
.min_w_0()
|
|
||||||
.px_2()
|
|
||||||
.overflow_hidden()
|
|
||||||
.whitespace_nowrap()
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.w_full()
|
|
||||||
.text_ellipsis()
|
|
||||||
.text_sm()
|
|
||||||
.child(panel_title(&panel, cx)),
|
|
||||||
)
|
|
||||||
.when_some(drag, |this, drag| {
|
|
||||||
this.on_drag(drag, {
|
|
||||||
let panel = panel.clone();
|
|
||||||
move |drag, offset, _, cx| {
|
|
||||||
cx.stop_propagation();
|
|
||||||
drag.set_drag_offset(offset);
|
|
||||||
cx.new(|_| DragPreview {
|
|
||||||
panel: panel.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.child({
|
|
||||||
let space = div().id("tab-title-space").flex_1().h_full();
|
|
||||||
if is_title_bar {
|
|
||||||
title_bar_drag_handlers(space, window, cx).into_any_element()
|
|
||||||
} else {
|
|
||||||
space.into_any_element()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.child(
|
|
||||||
h_flex()
|
|
||||||
.flex_shrink_0()
|
|
||||||
.ml_1()
|
|
||||||
.gap_1()
|
|
||||||
.child(self.render_toolbar(group, window, cx))
|
|
||||||
.children(right_button),
|
|
||||||
)
|
|
||||||
.when_some(trailing_chrome, |this, chrome| this.child(chrome));
|
|
||||||
|
|
||||||
if is_title_bar {
|
|
||||||
h_flex()
|
|
||||||
.h(TABBAR_HEIGHT)
|
|
||||||
.bg(cx.theme().panel_background)
|
|
||||||
.child(bar.flex_1())
|
|
||||||
.child(window_controls())
|
|
||||||
.into_any_element()
|
|
||||||
} else {
|
|
||||||
bar.into_any_element()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_tabs(
|
fn render_tabs(
|
||||||
&self,
|
&self,
|
||||||
group: &TabGroupContext,
|
group: &TabGroupContext,
|
||||||
@@ -641,9 +468,12 @@ impl TabGroupSkin {
|
|||||||
let bottom_button = self.dock_toggle_button(DockPlacement::Bottom, group, cx);
|
let bottom_button = self.dock_toggle_button(DockPlacement::Bottom, group, cx);
|
||||||
let right_button = self.dock_toggle_button(DockPlacement::Right, group, cx);
|
let right_button = self.dock_toggle_button(DockPlacement::Right, group, cx);
|
||||||
let has_leading = left_button.is_some() || bottom_button.is_some();
|
let has_leading = left_button.is_some() || bottom_button.is_some();
|
||||||
|
|
||||||
let collapsed = group.is_collapsed();
|
let collapsed = group.is_collapsed();
|
||||||
let droppable = group.is_droppable();
|
let droppable = group.is_droppable();
|
||||||
let tabs_count = group.panels().len();
|
let tabs_count = group.panels().len();
|
||||||
|
let is_title_bar = self.is_title_bar_group(group, cx);
|
||||||
|
|
||||||
let displayed = group.active_panel().map(|panel| panel.panel_id(cx));
|
let displayed = group.active_panel().map(|panel| panel.panel_id(cx));
|
||||||
let displayed_ix = displayed.and_then(|displayed| {
|
let displayed_ix = displayed.and_then(|displayed| {
|
||||||
group
|
group
|
||||||
@@ -651,12 +481,14 @@ impl TabGroupSkin {
|
|||||||
.iter()
|
.iter()
|
||||||
.position(|panel| panel.panel_id(cx) == displayed)
|
.position(|panel| panel.panel_id(cx) == displayed)
|
||||||
});
|
});
|
||||||
let is_title_bar = self.is_title_bar_group(group, cx);
|
|
||||||
let needs_traffic_light_padding =
|
let needs_traffic_light_padding =
|
||||||
cfg!(target_os = "macos") && self.is_leftmost_top_group(group, cx);
|
cfg!(target_os = "macos") && self.is_leftmost_top_group(group, cx);
|
||||||
|
|
||||||
let trailing_chrome = is_title_bar
|
let trailing_chrome = is_title_bar
|
||||||
.then(|| self.shared.chrome.trailing(window, cx))
|
.then(|| self.shared.chrome.trailing(window, cx))
|
||||||
.flatten();
|
.flatten();
|
||||||
|
|
||||||
let empty_space = div()
|
let empty_space = div()
|
||||||
.id("tab-bar-empty-space")
|
.id("tab-bar-empty-space")
|
||||||
.h_full()
|
.h_full()
|
||||||
@@ -672,6 +504,7 @@ impl TabGroupSkin {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let empty_space = if is_title_bar {
|
let empty_space = if is_title_bar {
|
||||||
title_bar_drag_handlers(empty_space, window, cx).into_any_element()
|
title_bar_drag_handlers(empty_space, window, cx).into_any_element()
|
||||||
} else {
|
} else {
|
||||||
@@ -688,7 +521,9 @@ impl TabGroupSkin {
|
|||||||
.when(is_title_bar || has_leading, |this| {
|
.when(is_title_bar || has_leading, |this| {
|
||||||
this.prefix(
|
this.prefix(
|
||||||
h_flex()
|
h_flex()
|
||||||
.items_center()
|
.size(TABBAR_HEIGHT)
|
||||||
|
.flex_shrink_0()
|
||||||
|
.justify_center()
|
||||||
.top_0()
|
.top_0()
|
||||||
.right(-px(1.))
|
.right(-px(1.))
|
||||||
.pl_0p5()
|
.pl_0p5()
|
||||||
@@ -766,13 +601,13 @@ impl TabGroupSkin {
|
|||||||
.when(!collapsed, |this| {
|
.when(!collapsed, |this| {
|
||||||
this.suffix(
|
this.suffix(
|
||||||
h_flex()
|
h_flex()
|
||||||
|
.flex_shrink_0()
|
||||||
.items_center()
|
.items_center()
|
||||||
.top_0()
|
.top_0()
|
||||||
.right_0()
|
.right_0()
|
||||||
.h_full()
|
.h_full()
|
||||||
.px_0p5()
|
.px_0p5()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.child(self.render_toolbar(group, window, cx))
|
|
||||||
.children(right_button)
|
.children(right_button)
|
||||||
.children(trailing_chrome),
|
.children(trailing_chrome),
|
||||||
)
|
)
|
||||||
@@ -845,7 +680,13 @@ impl TabGroupSkin {
|
|||||||
.small()
|
.small()
|
||||||
.ghost()
|
.ghost()
|
||||||
.tab_stop(false)
|
.tab_stop(false)
|
||||||
.tooltip(if is_open { "Collapse" } else { "Expand" })
|
.map(|this| {
|
||||||
|
if is_open {
|
||||||
|
this.tooltip("Collapse")
|
||||||
|
} else {
|
||||||
|
this.tooltip("Expand")
|
||||||
|
}
|
||||||
|
})
|
||||||
.on_click(move |_, window, cx| {
|
.on_click(move |_, window, cx| {
|
||||||
area.update(cx, |area, cx| area.toggle_dock(placement, window, cx));
|
area.update(cx, |area, cx| area.toggle_dock(placement, window, cx));
|
||||||
}),
|
}),
|
||||||
@@ -900,13 +741,11 @@ impl TabGroupRenderer for TabGroupSkin {
|
|||||||
self.scroll_handle.scroll_to_item(visible_ix);
|
self.scroll_handle.scroll_to_item(visible_ix);
|
||||||
}
|
}
|
||||||
|
|
||||||
match visible.as_slice() {
|
if visible.is_empty() {
|
||||||
[] => Empty.into_any_element(),
|
return Empty.into_any_element();
|
||||||
// One panel in a group that is not asking for tabs gets the title
|
|
||||||
// instead of a tab bar.
|
|
||||||
[ix] => self.render_title(group, *ix, window, cx),
|
|
||||||
_ => self.render_tabs(group, visible.as_slice(), window, cx),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.render_tabs(group, visible.as_slice(), window, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_active_panel(
|
fn render_active_panel(
|
||||||
|
|||||||
+32
-40
@@ -3,9 +3,9 @@ use std::rc::Rc;
|
|||||||
use gpui::prelude::FluentBuilder as _;
|
use gpui::prelude::FluentBuilder as _;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
AnyElement, App, ClickEvent, Div, InteractiveElement, IntoElement, MouseButton, ParentElement,
|
AnyElement, App, ClickEvent, Div, InteractiveElement, IntoElement, MouseButton, ParentElement,
|
||||||
RenderOnce, SharedString, StatefulInteractiveElement, Styled, Window, div, px, relative,
|
RenderOnce, SharedString, StatefulInteractiveElement, Styled, Window, div, px,
|
||||||
};
|
};
|
||||||
use theme::{ActiveTheme, TABBAR_HEIGHT};
|
use theme::ActiveTheme;
|
||||||
|
|
||||||
use crate::{Icon, IconName, Selectable, h_flex};
|
use crate::{Icon, IconName, Selectable, h_flex};
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ impl RenderOnce for Tab {
|
|||||||
..
|
..
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
let fg = if disabled {
|
let foreground = if disabled {
|
||||||
cx.theme().text_muted
|
cx.theme().text_muted
|
||||||
} else if selected {
|
} else if selected {
|
||||||
cx.theme().tab_active_foreground
|
cx.theme().tab_active_foreground
|
||||||
@@ -200,20 +200,12 @@ impl RenderOnce for Tab {
|
|||||||
|
|
||||||
let content = h_flex()
|
let content = h_flex()
|
||||||
.flex_1()
|
.flex_1()
|
||||||
.map(|this| {
|
.h_6()
|
||||||
if segmented {
|
|
||||||
this.h(px(24.))
|
|
||||||
} else {
|
|
||||||
this.h(px(30.))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.line_height(relative(1.))
|
|
||||||
.whitespace_nowrap()
|
.whitespace_nowrap()
|
||||||
.items_center()
|
.items_center()
|
||||||
.justify_center()
|
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.when(segmented, |this| this.px_1())
|
.when(segmented, |this| this.justify_center().px_1())
|
||||||
.when(!segmented, |this| this.flex_shrink_0().px_3())
|
.when(!segmented, |this| this.justify_start())
|
||||||
.map(|this| match icon {
|
.map(|this| match icon {
|
||||||
Some(icon) => this.w(px(38.)).child(icon.size_4()),
|
Some(icon) => this.w(px(38.)).child(icon.size_4()),
|
||||||
None => this
|
None => this
|
||||||
@@ -225,13 +217,14 @@ impl RenderOnce for Tab {
|
|||||||
});
|
});
|
||||||
|
|
||||||
base.id(ix)
|
base.id(ix)
|
||||||
|
.group("tab")
|
||||||
.flex()
|
.flex()
|
||||||
.items_center()
|
.items_center()
|
||||||
.text_color(fg)
|
.text_color(foreground)
|
||||||
.when(segmented, |this| {
|
.when(segmented, |this| {
|
||||||
this.text_xs()
|
this.text_xs()
|
||||||
.flex_1()
|
.flex_1()
|
||||||
.h(px(24.))
|
.h_6()
|
||||||
.rounded(cx.theme().radius)
|
.rounded(cx.theme().radius)
|
||||||
.when(selected && !disabled, |this| {
|
.when(selected && !disabled, |this| {
|
||||||
this.bg(cx.theme().tab_active_background)
|
this.bg(cx.theme().tab_active_background)
|
||||||
@@ -242,18 +235,35 @@ impl RenderOnce for Tab {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.when(!segmented, |this| {
|
.when(!segmented, |this| {
|
||||||
this.text_sm()
|
this.flex_shrink_0()
|
||||||
.flex_wrap()
|
.min_w_32()
|
||||||
|
.h_7()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.flex_shrink_0()
|
.px_1p5()
|
||||||
.h(TABBAR_HEIGHT)
|
.text_sm()
|
||||||
.relative()
|
.rounded(cx.theme().radius)
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
|
.when(selected && !disabled, |this| {
|
||||||
|
this.bg(cx.theme().tab_background)
|
||||||
|
})
|
||||||
|
.when(!selected && !disabled, |this| {
|
||||||
|
this.hover(|this| {
|
||||||
|
this.bg(cx.theme().tab_hover_background)
|
||||||
|
.text_color(cx.theme().tab_active_foreground)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.when_some(prefix, |this, prefix| this.child(prefix))
|
.when_some(prefix, |this, prefix| this.child(prefix))
|
||||||
.child(content)
|
.child(content)
|
||||||
.when_some(suffix, |this, suffix| {
|
.when_some(suffix, |this, suffix| {
|
||||||
this.child(div().pr_2().child(suffix))
|
this.child(
|
||||||
|
div()
|
||||||
|
.flex_shrink_0()
|
||||||
|
.when(!selected, |this| {
|
||||||
|
this.invisible().group_hover("tab", |this| this.visible())
|
||||||
|
})
|
||||||
|
.child(suffix),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.on_mouse_down(MouseButton::Left, |_ev, _window, cx| {
|
.on_mouse_down(MouseButton::Left, |_ev, _window, cx| {
|
||||||
cx.stop_propagation();
|
cx.stop_propagation();
|
||||||
@@ -263,23 +273,5 @@ impl RenderOnce for Tab {
|
|||||||
this.on_click(move |event, window, cx| on_click(event, window, cx))
|
this.on_click(move |event, window, cx| on_click(event, window, cx))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.when(!segmented, |this| {
|
|
||||||
this.child(
|
|
||||||
div()
|
|
||||||
.absolute()
|
|
||||||
.bottom_0()
|
|
||||||
.left_0()
|
|
||||||
.right_0()
|
|
||||||
.h_0p5()
|
|
||||||
.when(selected && !disabled, |this| {
|
|
||||||
this.bg(cx.theme().element_active)
|
|
||||||
})
|
|
||||||
.when(!selected && !disabled, |this| {
|
|
||||||
this.invisible().group_hover("", |this| {
|
|
||||||
this.visible().bg(cx.theme().secondary_background)
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ impl RenderOnce for TabBar {
|
|||||||
.relative()
|
.relative()
|
||||||
.flex()
|
.flex()
|
||||||
.items_center()
|
.items_center()
|
||||||
|
.min_w_0()
|
||||||
.refine_style(&self.style)
|
.refine_style(&self.style)
|
||||||
.when(segmented, |this| {
|
.when(segmented, |this| {
|
||||||
this.bg(cx.theme().tab_background)
|
this.bg(cx.theme().tab_background)
|
||||||
|
|||||||
@@ -58,13 +58,16 @@ impl Panel for GreeterPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn title(&self, cx: &App) -> AnyElement {
|
fn title(&self, cx: &App) -> AnyElement {
|
||||||
div()
|
h_flex()
|
||||||
|
.gap_1()
|
||||||
|
.text_xs()
|
||||||
.child(
|
.child(
|
||||||
svg()
|
svg()
|
||||||
.path("brand/coop.svg")
|
.path("brand/coop.svg")
|
||||||
.size_4()
|
.size_4()
|
||||||
.text_color(cx.theme().text_muted),
|
.text_color(cx.theme().text_muted),
|
||||||
)
|
)
|
||||||
|
.child("Welcome")
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ impl Sidebar {
|
|||||||
.child(
|
.child(
|
||||||
Avatar::new(avatar.clone())
|
Avatar::new(avatar.clone())
|
||||||
.seed(avatar_seed.clone())
|
.seed(avatar_seed.clone())
|
||||||
.xsmall(),
|
.small(),
|
||||||
)
|
)
|
||||||
.small()
|
.small()
|
||||||
.caret()
|
.caret()
|
||||||
|
|||||||
@@ -141,13 +141,13 @@ impl RenderOnce for TreeRow {
|
|||||||
(seed, Some(picture)) => Some(
|
(seed, Some(picture)) => Some(
|
||||||
Avatar::from_source(picture)
|
Avatar::from_source(picture)
|
||||||
.when_some(seed, |avatar, seed| avatar.seed(seed))
|
.when_some(seed, |avatar, seed| avatar.seed(seed))
|
||||||
.xsmall()
|
.small()
|
||||||
.flex_shrink_0()
|
.flex_shrink_0()
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
),
|
),
|
||||||
(Some(seed), None) => Some(
|
(Some(seed), None) => Some(
|
||||||
PixelAvatar::new(seed)
|
PixelAvatar::new(seed)
|
||||||
.xsmall()
|
.small()
|
||||||
.flex_shrink_0()
|
.flex_shrink_0()
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user