mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-23 18:32:17 +00:00
Add png image loading to gpui
add zed logo into welcome experience Co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
parent
f89f33347d
commit
4c179875ab
11 changed files with 76 additions and 33 deletions
BIN
assets/images/zed-logo-90x90.png
Normal file
BIN
assets/images/zed-logo-90x90.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -823,7 +823,7 @@ impl CollabTitlebarItem {
|
|||
avatar_style: AvatarStyle,
|
||||
background_color: Color,
|
||||
) -> ElementBox {
|
||||
Image::new(avatar)
|
||||
Image::from_data(avatar)
|
||||
.with_style(avatar_style.image)
|
||||
.aligned()
|
||||
.contained()
|
||||
|
|
|
@ -128,7 +128,7 @@ impl PickerDelegate for ContactFinder {
|
|||
.style_for(mouse_state, selected);
|
||||
Flex::row()
|
||||
.with_children(user.avatar.clone().map(|avatar| {
|
||||
Image::new(avatar)
|
||||
Image::from_data(avatar)
|
||||
.with_style(theme.contact_finder.contact_avatar)
|
||||
.aligned()
|
||||
.left()
|
||||
|
|
|
@ -726,7 +726,7 @@ impl ContactList {
|
|||
) -> ElementBox {
|
||||
Flex::row()
|
||||
.with_children(user.avatar.clone().map(|avatar| {
|
||||
Image::new(avatar)
|
||||
Image::from_data(avatar)
|
||||
.with_style(theme.contact_avatar)
|
||||
.aligned()
|
||||
.left()
|
||||
|
@ -1080,7 +1080,7 @@ impl ContactList {
|
|||
};
|
||||
Stack::new()
|
||||
.with_child(
|
||||
Image::new(avatar)
|
||||
Image::from_data(avatar)
|
||||
.with_style(theme.contact_avatar)
|
||||
.aligned()
|
||||
.left()
|
||||
|
@ -1173,7 +1173,7 @@ impl ContactList {
|
|||
|
||||
let mut row = Flex::row()
|
||||
.with_children(user.avatar.clone().map(|avatar| {
|
||||
Image::new(avatar)
|
||||
Image::from_data(avatar)
|
||||
.with_style(theme.contact_avatar)
|
||||
.aligned()
|
||||
.left()
|
||||
|
|
|
@ -108,7 +108,7 @@ impl IncomingCallNotification {
|
|||
.unwrap_or(&default_project);
|
||||
Flex::row()
|
||||
.with_children(self.call.calling_user.avatar.clone().map(|avatar| {
|
||||
Image::new(avatar)
|
||||
Image::from_data(avatar)
|
||||
.with_style(theme.caller_avatar)
|
||||
.aligned()
|
||||
.boxed()
|
||||
|
|
|
@ -24,7 +24,7 @@ pub fn render_user_notification<V: View, A: Action + Clone>(
|
|||
.with_child(
|
||||
Flex::row()
|
||||
.with_children(user.avatar.clone().map(|avatar| {
|
||||
Image::new(avatar)
|
||||
Image::from_data(avatar)
|
||||
.with_style(theme.header_avatar)
|
||||
.aligned()
|
||||
.constrained()
|
||||
|
|
|
@ -108,7 +108,7 @@ impl ProjectSharedNotification {
|
|||
let theme = &cx.global::<Settings>().theme.project_shared_notification;
|
||||
Flex::row()
|
||||
.with_children(self.owner.avatar.clone().map(|avatar| {
|
||||
Image::new(avatar)
|
||||
Image::from_data(avatar)
|
||||
.with_style(theme.owner_avatar)
|
||||
.aligned()
|
||||
.boxed()
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use std::{borrow::Cow, cell::RefCell, collections::HashMap};
|
||||
use image::ImageFormat;
|
||||
use std::{borrow::Cow, cell::RefCell, collections::HashMap, sync::Arc};
|
||||
|
||||
use crate::ImageData;
|
||||
|
||||
pub trait AssetSource: 'static + Send + Sync {
|
||||
fn load(&self, path: &str) -> Result<Cow<[u8]>>;
|
||||
|
@ -22,6 +25,7 @@ impl AssetSource for () {
|
|||
pub struct AssetCache {
|
||||
source: Box<dyn AssetSource>,
|
||||
svgs: RefCell<HashMap<String, usvg::Tree>>,
|
||||
pngs: RefCell<HashMap<String, Arc<ImageData>>>,
|
||||
}
|
||||
|
||||
impl AssetCache {
|
||||
|
@ -29,6 +33,7 @@ impl AssetCache {
|
|||
Self {
|
||||
source: Box::new(source),
|
||||
svgs: RefCell::new(HashMap::new()),
|
||||
pngs: RefCell::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,4 +48,18 @@ impl AssetCache {
|
|||
Ok(svg)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn png(&self, path: &str) -> Result<Arc<ImageData>> {
|
||||
let mut pngs = self.pngs.borrow_mut();
|
||||
if let Some(png) = pngs.get(path) {
|
||||
Ok(png.clone())
|
||||
} else {
|
||||
let bytes = self.source.load(path)?;
|
||||
let image = ImageData::new(
|
||||
image::load_from_memory_with_format(&bytes, ImageFormat::Png)?.into_bgra8(),
|
||||
);
|
||||
pngs.insert(path.to_string(), image.clone());
|
||||
Ok(image)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,13 @@ use crate::{
|
|||
use serde::Deserialize;
|
||||
use std::{ops::Range, sync::Arc};
|
||||
|
||||
enum ImageSource {
|
||||
Path(&'static str),
|
||||
Data(Arc<ImageData>),
|
||||
}
|
||||
|
||||
pub struct Image {
|
||||
data: Arc<ImageData>,
|
||||
source: ImageSource,
|
||||
style: ImageStyle,
|
||||
}
|
||||
|
||||
|
@ -31,9 +36,16 @@ pub struct ImageStyle {
|
|||
}
|
||||
|
||||
impl Image {
|
||||
pub fn new(data: Arc<ImageData>) -> Self {
|
||||
pub fn new(asset_path: &'static str) -> Self {
|
||||
Self {
|
||||
data,
|
||||
source: ImageSource::Path(asset_path),
|
||||
style: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_data(data: Arc<ImageData>) -> Self {
|
||||
Self {
|
||||
source: ImageSource::Data(data),
|
||||
style: Default::default(),
|
||||
}
|
||||
}
|
||||
|
@ -45,39 +57,53 @@ impl Image {
|
|||
}
|
||||
|
||||
impl Element for Image {
|
||||
type LayoutState = ();
|
||||
type LayoutState = Option<Arc<ImageData>>;
|
||||
type PaintState = ();
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
constraint: SizeConstraint,
|
||||
_: &mut LayoutContext,
|
||||
cx: &mut LayoutContext,
|
||||
) -> (Vector2F, Self::LayoutState) {
|
||||
let data = match &self.source {
|
||||
ImageSource::Path(path) => match cx.asset_cache.png(path) {
|
||||
Ok(data) => data,
|
||||
Err(error) => {
|
||||
log::error!("could not load image: {}", error);
|
||||
return (Vector2F::zero(), None);
|
||||
}
|
||||
},
|
||||
ImageSource::Data(data) => data.clone(),
|
||||
};
|
||||
|
||||
let desired_size = vec2f(
|
||||
self.style.width.unwrap_or_else(|| constraint.max.x()),
|
||||
self.style.height.unwrap_or_else(|| constraint.max.y()),
|
||||
);
|
||||
let size = constrain_size_preserving_aspect_ratio(
|
||||
constraint.constrain(desired_size),
|
||||
self.data.size().to_f32(),
|
||||
data.size().to_f32(),
|
||||
);
|
||||
(size, ())
|
||||
|
||||
(size, Some(data))
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: RectF,
|
||||
_: RectF,
|
||||
_: &mut Self::LayoutState,
|
||||
layout: &mut Self::LayoutState,
|
||||
cx: &mut PaintContext,
|
||||
) -> Self::PaintState {
|
||||
cx.scene.push_image(scene::Image {
|
||||
bounds,
|
||||
border: self.style.border,
|
||||
corner_radius: self.style.corner_radius,
|
||||
grayscale: self.style.grayscale,
|
||||
data: self.data.clone(),
|
||||
});
|
||||
if let Some(data) = layout {
|
||||
cx.scene.push_image(scene::Image {
|
||||
bounds,
|
||||
border: self.style.border,
|
||||
corner_radius: self.style.corner_radius,
|
||||
grayscale: self.style.grayscale,
|
||||
data: data.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn rect_for_text_range(
|
||||
|
|
|
@ -1325,7 +1325,7 @@ impl View for ProjectPanel {
|
|||
Canvas::new(|bounds, _visible_bounds, cx| {
|
||||
cx.scene.push_quad(gpui::Quad {
|
||||
bounds,
|
||||
background: Some(Color::red()),
|
||||
background: Some(Color::transparent_black()),
|
||||
..Default::default()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use gpui::{
|
||||
color::Color,
|
||||
elements::{Canvas, Empty, Flex, Label, MouseEventHandler, ParentElement, Stack, Svg},
|
||||
elements::{Canvas, Empty, Flex, Image, Label, MouseEventHandler, ParentElement, Stack},
|
||||
geometry::rect::RectF,
|
||||
Action, Element, ElementBox, Entity, MouseButton, MouseRegion, MutableAppContext,
|
||||
RenderContext, Subscription, View, ViewContext,
|
||||
};
|
||||
use settings::{settings_file::SettingsFile, Settings, SettingsFileContent};
|
||||
use theme::{CheckboxStyle, ContainedText, Interactive};
|
||||
use theme::CheckboxStyle;
|
||||
use workspace::{item::Item, Welcome, Workspace};
|
||||
|
||||
pub fn init(cx: &mut MutableAppContext) {
|
||||
|
@ -72,15 +71,14 @@ impl View for WelcomePage {
|
|||
.with_children([
|
||||
Flex::row()
|
||||
.with_children([
|
||||
Svg::new("icons/terminal_16.svg")
|
||||
.with_color(Color::red())
|
||||
Image::new("images/zed-logo-90x90.png")
|
||||
.constrained()
|
||||
.with_width(100.)
|
||||
.with_height(100.)
|
||||
.with_width(90.)
|
||||
.with_height(90.)
|
||||
.aligned()
|
||||
.contained()
|
||||
.boxed(),
|
||||
Label::new("Zed", theme.editor.hover_popover.prose.clone()).boxed(),
|
||||
// Label::new("Zed", theme.editor.hover_popover.prose.clone()).boxed(),
|
||||
])
|
||||
.boxed(),
|
||||
Label::new(
|
||||
|
|
Loading…
Reference in a new issue