mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
Render a close tab button on tab hover
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
parent
bb95d58c79
commit
eca9f495a1
@ -12,8 +12,8 @@ pub struct MouseEventHandler {
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct MouseState {
|
||||
hovered: bool,
|
||||
clicked: bool,
|
||||
pub hovered: bool,
|
||||
pub clicked: bool,
|
||||
}
|
||||
|
||||
impl MouseEventHandler {
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
@ -11,14 +13,14 @@ use crate::{
|
||||
};
|
||||
|
||||
pub struct Svg {
|
||||
path: String,
|
||||
path: Cow<'static, str>,
|
||||
color: ColorU,
|
||||
}
|
||||
|
||||
impl Svg {
|
||||
pub fn new(path: String) -> Self {
|
||||
pub fn new(path: impl Into<Cow<'static, str>>) -> Self {
|
||||
Self {
|
||||
path,
|
||||
path: path.into(),
|
||||
color: ColorU::black(),
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
use etagere::BucketedAtlasAllocator;
|
||||
use metal::{MTLPixelFormat, TextureDescriptor};
|
||||
use ordered_float::OrderedFloat;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
use std::{borrow::Cow, collections::HashMap, sync::Arc};
|
||||
|
||||
#[derive(Hash, Eq, PartialEq)]
|
||||
struct GlyphDescriptor {
|
||||
@ -29,7 +29,7 @@ pub struct GlyphSprite {
|
||||
|
||||
#[derive(Hash, Eq, PartialEq)]
|
||||
struct IconDescriptor {
|
||||
path: String,
|
||||
path: Cow<'static, str>,
|
||||
width: i32,
|
||||
height: i32,
|
||||
}
|
||||
@ -138,7 +138,7 @@ impl SpriteCache {
|
||||
pub fn render_icon(
|
||||
&mut self,
|
||||
size: Vector2F,
|
||||
path: String,
|
||||
path: Cow<'static, str>,
|
||||
svg: usvg::Tree,
|
||||
scale_factor: f32,
|
||||
) -> IconSprite {
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
@ -51,7 +53,7 @@ pub struct Glyph {
|
||||
pub struct Icon {
|
||||
pub bounds: RectF,
|
||||
pub svg: usvg::Tree,
|
||||
pub path: String,
|
||||
pub path: Cow<'static, str>,
|
||||
pub color: ColorU,
|
||||
}
|
||||
|
||||
|
3
zed/assets/icons/x.svg
Normal file
3
zed/assets/icons/x.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.720011 0.72003C0.860631 0.57958 1.05126 0.50069 1.25001 0.50069C1.44876 0.50069 1.63938 0.57958 1.78001 0.72003L5.00001 3.94003L8.22001 0.72003C8.28871 0.64634 8.37151 0.58724 8.46351 0.54625C8.55551 0.50526 8.65481 0.48322 8.75551 0.48144C8.85621 0.47966 8.95621 0.49819 9.04961 0.53591C9.14301 0.57363 9.22781 0.62977 9.29901 0.70099C9.37031 0.77221 9.42641 0.85705 9.46411 0.95043C9.50181 1.04382 9.52041 1.14385 9.51861 1.24455C9.51681 1.34526 9.49481 1.44457 9.45381 1.53657C9.41281 1.62857 9.35371 1.71137 9.28001 1.78003L6.06001 5.00003L9.28001 8.22003C9.35371 8.28873 9.41281 8.37153 9.45381 8.46353C9.49481 8.55553 9.51681 8.65483 9.51861 8.75553C9.52041 8.85623 9.50181 8.95623 9.46411 9.04963C9.42641 9.14303 9.37031 9.22783 9.29901 9.29903C9.22781 9.37033 9.14301 9.42643 9.04961 9.46413C8.95621 9.50183 8.85621 9.52043 8.75551 9.51863C8.65481 9.51683 8.55551 9.49483 8.46351 9.45383C8.37151 9.41283 8.28871 9.35373 8.22001 9.28003L5.00001 6.06003L1.78001 9.28003C1.63783 9.41253 1.44978 9.48463 1.25548 9.48123C1.06118 9.47773 0.875801 9.39903 0.738381 9.26163C0.600971 9.12423 0.522261 8.93883 0.518831 8.74453C0.515401 8.55023 0.587531 8.36223 0.720011 8.22003L3.94001 5.00003L0.720011 1.78003C0.579561 1.63941 0.500671 1.44878 0.500671 1.25003C0.500671 1.05128 0.579561 0.86066 0.720011 0.72003Z" fill="#000000"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
@ -187,7 +187,7 @@ impl FileFinder {
|
||||
LineBox::new(
|
||||
settings.ui_font_family,
|
||||
settings.ui_font_size,
|
||||
Svg::new("icons/file-16.svg".into()).boxed(),
|
||||
Svg::new("icons/file-16.svg").boxed(),
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
|
@ -183,54 +183,61 @@ impl Pane {
|
||||
let mut row = Flex::row();
|
||||
let last_item_ix = self.items.len() - 1;
|
||||
for (ix, item) in self.items.iter().enumerate() {
|
||||
let title = item.title(ctx);
|
||||
|
||||
let mut border = Border::new(1.0, border_color);
|
||||
border.left = ix > 0;
|
||||
border.right = ix == last_item_ix;
|
||||
border.bottom = ix != self.active_item;
|
||||
|
||||
let padding = 6.;
|
||||
let mut container = Container::new(
|
||||
Stack::new()
|
||||
.with_child(
|
||||
Align::new(
|
||||
Label::new(title, settings.ui_font_family, settings.ui_font_size)
|
||||
.boxed(),
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(
|
||||
LineBox::new(
|
||||
settings.ui_font_family,
|
||||
settings.ui_font_size,
|
||||
Align::new(Self::render_modified_icon(item.is_dirty(ctx)))
|
||||
.right()
|
||||
.boxed(),
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.with_vertical_padding(padding)
|
||||
.with_horizontal_padding(10.)
|
||||
.with_border(border);
|
||||
|
||||
if ix == self.active_item {
|
||||
container = container
|
||||
.with_background_color(ColorU::white())
|
||||
.with_padding_bottom(padding + border.width);
|
||||
} else {
|
||||
container = container.with_background_color(ColorU::from_u32(0xeaeaebff));
|
||||
}
|
||||
|
||||
enum Tab {}
|
||||
|
||||
row.add_child(
|
||||
Expanded::new(
|
||||
1.0,
|
||||
MouseEventHandler::new::<Tab, _>(item.id(), ctx, |mouse_state| {
|
||||
log::info!("mouse event handler {:?}", mouse_state);
|
||||
let title = item.title(ctx);
|
||||
|
||||
let mut border = Border::new(1.0, border_color);
|
||||
border.left = ix > 0;
|
||||
border.right = ix == last_item_ix;
|
||||
border.bottom = ix != self.active_item;
|
||||
|
||||
let padding = 6.;
|
||||
let mut container = Container::new(
|
||||
Stack::new()
|
||||
.with_child(
|
||||
Align::new(
|
||||
Label::new(
|
||||
title,
|
||||
settings.ui_font_family,
|
||||
settings.ui_font_size,
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(
|
||||
LineBox::new(
|
||||
settings.ui_font_family,
|
||||
settings.ui_font_size,
|
||||
Align::new(Self::render_tab_icon(
|
||||
mouse_state.hovered,
|
||||
item.is_dirty(ctx),
|
||||
))
|
||||
.right()
|
||||
.boxed(),
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.with_vertical_padding(padding)
|
||||
.with_horizontal_padding(10.)
|
||||
.with_border(border);
|
||||
|
||||
if ix == self.active_item {
|
||||
container = container
|
||||
.with_background_color(ColorU::white())
|
||||
.with_padding_bottom(padding + border.width);
|
||||
} else {
|
||||
container =
|
||||
container.with_background_color(ColorU::from_u32(0xeaeaebff));
|
||||
}
|
||||
|
||||
ConstrainedBox::new(
|
||||
EventHandler::new(container.boxed())
|
||||
.on_mouse_down(move |ctx| {
|
||||
@ -290,25 +297,36 @@ impl Pane {
|
||||
row.named("tabs")
|
||||
}
|
||||
|
||||
fn render_modified_icon(is_modified: bool) -> ElementBox {
|
||||
let diameter = 8.;
|
||||
ConstrainedBox::new(
|
||||
Canvas::new(move |bounds, ctx| {
|
||||
if is_modified {
|
||||
let square = RectF::new(bounds.origin(), vec2f(diameter, diameter));
|
||||
ctx.scene.push_quad(Quad {
|
||||
bounds: square,
|
||||
background: Some(ColorF::new(0.639, 0.839, 1.0, 1.0).to_u8()),
|
||||
border: Default::default(),
|
||||
corner_radius: diameter / 2.,
|
||||
});
|
||||
}
|
||||
})
|
||||
.boxed(),
|
||||
)
|
||||
.with_width(diameter)
|
||||
.with_height(diameter)
|
||||
.named("tab-right-icon")
|
||||
fn render_tab_icon(tab_hovered: bool, is_modified: bool) -> ElementBox {
|
||||
let modified_color = ColorU::from_u32(0x556de8ff);
|
||||
if tab_hovered {
|
||||
let mut icon = Svg::new("icons/x.svg");
|
||||
if is_modified {
|
||||
icon = icon.with_color(modified_color);
|
||||
}
|
||||
ConstrainedBox::new(icon.boxed())
|
||||
.with_width(10.)
|
||||
.named("close-tab-icon")
|
||||
} else {
|
||||
let diameter = 8.;
|
||||
ConstrainedBox::new(
|
||||
Canvas::new(move |bounds, ctx| {
|
||||
if is_modified {
|
||||
let square = RectF::new(bounds.origin(), vec2f(diameter, diameter));
|
||||
ctx.scene.push_quad(Quad {
|
||||
bounds: square,
|
||||
background: Some(modified_color),
|
||||
border: Default::default(),
|
||||
corner_radius: diameter / 2.,
|
||||
});
|
||||
}
|
||||
})
|
||||
.boxed(),
|
||||
)
|
||||
.with_width(diameter)
|
||||
.with_height(diameter)
|
||||
.named("unsaved-tab-icon")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user