pub struct Img { /* private fields */ }Expand description
A terminal-rendered image backing the <img> markup tag.
On the Kitty-placeholder graphics tier a PNG src renders as real pixels
with no further setup: the source is interned process-wide, uploaded by
the renderer on first reference, and placed in the cell box derived from
w/h (aspect-derived when h is omitted). On every other tier, PNG
and binary PPM sources decode to colored half-block cells. JPEG, GIF,
and WebP sources are header-probed only: the component reserves their
aspect-correct cell box and paints a themed placeholder. The trim flag
crops fully transparent margins before half-block sampling (terminal
compositors always show the full source), so padded logo sources stay
visible even as tiny thumbnails.
Implementations§
Source§impl Img
impl Img
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates an image with no source.
Examples found in repository?
107fn build_ui(viewport: Size, context: UiContext) -> Ui {
108 let ids = PROVIDERS
109 .iter()
110 .enumerate()
111 .map(|(index, provider)| {
112 (format!("{ASSET_DIR}/{}.png", provider.id), u32::try_from(index + 1).unwrap())
113 })
114 .collect::<HashMap<_, _>>();
115 let elements = Elements::builder()
116 .with("logo", move |_: &str, props: Props, _: Vec<Cached>| {
117 let source = props.str_of(Prop::Src).map_or("", |value| value.as_str());
118 let id = ids.get(source).copied().unwrap_or(1);
119 Box::new(
120 Img::new()
121 .with_str(Prop::Src, source)
122 .with(Prop::W, 4_u16)
123 .kitty(id, 2, 4),
124 ) as Box<dyn omp_tui::Component>
125 })
126 .build();
127 let root = dom! {
128 <col gap=1>
129 <row gap=1>
130 <i:log-in/>
131 <text bold fg="accent..info">{"Choose a provider"}</text>
132 <text dim>{format!("{} providers", PROVIDERS.len())}</text>
133 </row>
134 <scroll id={SCROLL_ID} h={scroll_height(viewport)}>
135 <row wrap gap=1 justify=center>
136 for provider in PROVIDERS.iter() {
137 <box focus id={provider.id} w={CARD_W} border=round bc="muted..muted"
138 hover="#38bdf8..#c084fc" lift=1 anim=220 ease=in-out
139 align=center pad-x=1>
140 <logo src={format!("{ASSET_DIR}/{}.png", provider.id)}/>
141 <text bold truncate align=center>{provider.name}</text>
142 </box>
143 }
144 </row>
145 </scroll>
146 <row gap=2>
147 <text dim>{"↹/←→/↑↓ pick · ↵ login · wheel scroll · Ctrl-C quit"}</text>
148 <text id={HUD_ID} dim>{"repaint: 0 cells"}</text>
149 </row>
150 </col>
151 };
152 let context = UiContext { elements, ..context };
153 Ui::from_root(root, viewport.width, context)
154}Sourcepub fn with(self, prop: Prop, value: impl Into<PropValue>) -> Self
pub fn with(self, prop: Prop, value: impl Into<PropValue>) -> Self
Sets one image property.
Examples found in repository?
107fn build_ui(viewport: Size, context: UiContext) -> Ui {
108 let ids = PROVIDERS
109 .iter()
110 .enumerate()
111 .map(|(index, provider)| {
112 (format!("{ASSET_DIR}/{}.png", provider.id), u32::try_from(index + 1).unwrap())
113 })
114 .collect::<HashMap<_, _>>();
115 let elements = Elements::builder()
116 .with("logo", move |_: &str, props: Props, _: Vec<Cached>| {
117 let source = props.str_of(Prop::Src).map_or("", |value| value.as_str());
118 let id = ids.get(source).copied().unwrap_or(1);
119 Box::new(
120 Img::new()
121 .with_str(Prop::Src, source)
122 .with(Prop::W, 4_u16)
123 .kitty(id, 2, 4),
124 ) as Box<dyn omp_tui::Component>
125 })
126 .build();
127 let root = dom! {
128 <col gap=1>
129 <row gap=1>
130 <i:log-in/>
131 <text bold fg="accent..info">{"Choose a provider"}</text>
132 <text dim>{format!("{} providers", PROVIDERS.len())}</text>
133 </row>
134 <scroll id={SCROLL_ID} h={scroll_height(viewport)}>
135 <row wrap gap=1 justify=center>
136 for provider in PROVIDERS.iter() {
137 <box focus id={provider.id} w={CARD_W} border=round bc="muted..muted"
138 hover="#38bdf8..#c084fc" lift=1 anim=220 ease=in-out
139 align=center pad-x=1>
140 <logo src={format!("{ASSET_DIR}/{}.png", provider.id)}/>
141 <text bold truncate align=center>{provider.name}</text>
142 </box>
143 }
144 </row>
145 </scroll>
146 <row gap=2>
147 <text dim>{"↹/←→/↑↓ pick · ↵ login · wheel scroll · Ctrl-C quit"}</text>
148 <text id={HUD_ID} dim>{"repaint: 0 cells"}</text>
149 </row>
150 </col>
151 };
152 let context = UiContext { elements, ..context };
153 Ui::from_root(root, viewport.width, context)
154}Sourcepub fn with_str(self, prop: Prop, value: &str) -> Self
pub fn with_str(self, prop: Prop, value: &str) -> Self
Sets one image property from a string.
Examples found in repository?
107fn build_ui(viewport: Size, context: UiContext) -> Ui {
108 let ids = PROVIDERS
109 .iter()
110 .enumerate()
111 .map(|(index, provider)| {
112 (format!("{ASSET_DIR}/{}.png", provider.id), u32::try_from(index + 1).unwrap())
113 })
114 .collect::<HashMap<_, _>>();
115 let elements = Elements::builder()
116 .with("logo", move |_: &str, props: Props, _: Vec<Cached>| {
117 let source = props.str_of(Prop::Src).map_or("", |value| value.as_str());
118 let id = ids.get(source).copied().unwrap_or(1);
119 Box::new(
120 Img::new()
121 .with_str(Prop::Src, source)
122 .with(Prop::W, 4_u16)
123 .kitty(id, 2, 4),
124 ) as Box<dyn omp_tui::Component>
125 })
126 .build();
127 let root = dom! {
128 <col gap=1>
129 <row gap=1>
130 <i:log-in/>
131 <text bold fg="accent..info">{"Choose a provider"}</text>
132 <text dim>{format!("{} providers", PROVIDERS.len())}</text>
133 </row>
134 <scroll id={SCROLL_ID} h={scroll_height(viewport)}>
135 <row wrap gap=1 justify=center>
136 for provider in PROVIDERS.iter() {
137 <box focus id={provider.id} w={CARD_W} border=round bc="muted..muted"
138 hover="#38bdf8..#c084fc" lift=1 anim=220 ease=in-out
139 align=center pad-x=1>
140 <logo src={format!("{ASSET_DIR}/{}.png", provider.id)}/>
141 <text bold truncate align=center>{provider.name}</text>
142 </box>
143 }
144 </row>
145 </scroll>
146 <row gap=2>
147 <text dim>{"↹/←→/↑↓ pick · ↵ login · wheel scroll · Ctrl-C quit"}</text>
148 <text id={HUD_ID} dim>{"repaint: 0 cells"}</text>
149 </row>
150 </col>
151 };
152 let context = UiContext { elements, ..context };
153 Ui::from_root(root, viewport.width, context)
154}Sourcepub const fn kitty(self, id: u32, rows: u16, cols: u16) -> Self
pub const fn kitty(self, id: u32, rows: u16, cols: u16) -> Self
Uses a renderer-registered image ID in a fixed cell box on every
pixel-capable graphics tier, overriding the src placeholder path.
Pair with crate::Renderer::register_image. Rebuild the component
with new dimensions after a resize. Dimensions beyond Kitty’s
297-entry coordinate table leave the component on its cell fallback.
Examples found in repository?
107fn build_ui(viewport: Size, context: UiContext) -> Ui {
108 let ids = PROVIDERS
109 .iter()
110 .enumerate()
111 .map(|(index, provider)| {
112 (format!("{ASSET_DIR}/{}.png", provider.id), u32::try_from(index + 1).unwrap())
113 })
114 .collect::<HashMap<_, _>>();
115 let elements = Elements::builder()
116 .with("logo", move |_: &str, props: Props, _: Vec<Cached>| {
117 let source = props.str_of(Prop::Src).map_or("", |value| value.as_str());
118 let id = ids.get(source).copied().unwrap_or(1);
119 Box::new(
120 Img::new()
121 .with_str(Prop::Src, source)
122 .with(Prop::W, 4_u16)
123 .kitty(id, 2, 4),
124 ) as Box<dyn omp_tui::Component>
125 })
126 .build();
127 let root = dom! {
128 <col gap=1>
129 <row gap=1>
130 <i:log-in/>
131 <text bold fg="accent..info">{"Choose a provider"}</text>
132 <text dim>{format!("{} providers", PROVIDERS.len())}</text>
133 </row>
134 <scroll id={SCROLL_ID} h={scroll_height(viewport)}>
135 <row wrap gap=1 justify=center>
136 for provider in PROVIDERS.iter() {
137 <box focus id={provider.id} w={CARD_W} border=round bc="muted..muted"
138 hover="#38bdf8..#c084fc" lift=1 anim=220 ease=in-out
139 align=center pad-x=1>
140 <logo src={format!("{ASSET_DIR}/{}.png", provider.id)}/>
141 <text bold truncate align=center>{provider.name}</text>
142 </box>
143 }
144 </row>
145 </scroll>
146 <row gap=2>
147 <text dim>{"↹/←→/↑↓ pick · ↵ login · wheel scroll · Ctrl-C quit"}</text>
148 <text id={HUD_ID} dim>{"repaint: 0 cells"}</text>
149 </row>
150 </col>
151 };
152 let context = UiContext { elements, ..context };
153 Ui::from_root(root, viewport.width, context)
154}Trait Implementations§
Source§impl Component for Img
impl Component for Img
Source§fn measure(&mut self, ctx: &UiContext) -> (u16, u16)
fn measure(&mut self, ctx: &UiContext) -> (u16, u16)
Source§fn height(&mut self, ctx: &UiContext, width: u16) -> u16
fn height(&mut self, ctx: &UiContext, width: u16) -> u16
Source§fn place(&mut self, ctx: &UiContext, content: Rect)
fn place(&mut self, ctx: &UiContext, content: Rect)
Source§fn paint(&mut self, pc: &mut PaintCtx<'_>, rect: Rect)
fn paint(&mut self, pc: &mut PaintCtx<'_>, rect: Rect)
Source§fn kind(&self) -> &'static str
fn kind(&self) -> &'static str
std::any::type_name. The OMP_TUI_DEBUG
tree dump trims it to the trailing path segment.Source§fn children_mut(&mut self) -> &mut [Cached]
fn children_mut(&mut self) -> &mut [Cached]
Source§fn paints_border(&self) -> bool
fn paints_border(&self) -> bool
Cached should paint this component’s border property as
chrome.Source§fn paints_background(&self) -> bool
fn paints_background(&self) -> bool
Cached should paint this component’s background property
across its rectangle. Components that own a partial background fill opt
out and paint it themselves.Source§fn gradient_bounds(&self, content: Rect) -> Option<Rect>
fn gradient_bounds(&self, content: Rect) -> Option<Rect>
fg=/bg= ramps, given the
painted content rectangle. None projects across the full chrome;
content-sized leaves (crate::components::Pre) return their authored
extent so the ramp completes across the glyphs instead of the
stretched layout width.Source§fn resize_tail(&mut self) -> Option<ResizeTail<'_>>
fn resize_tail(&mut self) -> Option<ResizeTail<'_>>
None — the default — renders this component whole. Read moreSource§fn validation_error(&self) -> Option<String>
fn validation_error(&self) -> Option<String>
required or
match= constraint owned by this component’s internal records;
None when valid. Component-level props are checked by the caller.Source§fn stretch_in_row(&self) -> bool
fn stretch_in_row(&self) -> bool
Source§fn focusable(&self) -> bool
fn focusable(&self) -> bool
focus flag, so any container can opt into
keyboard navigation from markup.Source§fn enter(&mut self, forward: bool)
fn enter(&mut self, forward: bool)
Source§fn mouse(
&mut self,
ec: &mut EventCtx<'_>,
tag: HitTag,
at: (u16, u16),
rect: Rect,
mouse: Mouse,
) -> Flow
fn mouse( &mut self, ec: &mut EventCtx<'_>, tag: HitTag, at: (u16, u16), rect: Rect, mouse: Mouse, ) -> Flow
Source§fn paste(&mut self, ec: &mut EventCtx<'_>, text: &str) -> Flow
fn paste(&mut self, ec: &mut EventCtx<'_>, text: &str) -> Flow
Flow::Consumed repaints,
Flow::Event additionally surfaces a crate::UiEvent, and
Flow::Skip leaves the paste unhandled.Source§fn paste_raw(&mut self, ec: &mut EventCtx<'_>, text: &str) -> Flow
fn paste_raw(&mut self, ec: &mut EventCtx<'_>, text: &str) -> Flow
Component::paste (drop classification,
large-paste collapse). Defaults to Component::paste for
components without such interpretation.Auto Trait Implementations§
impl Freeze for Img
impl RefUnwindSafe for Img
impl Send for Img
impl Sync for Img
impl Unpin for Img
impl UnsafeUnpin for Img
impl UnwindSafe for Img
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> IntoChildren for Twhere
T: IntoComponent,
impl<T> IntoChildren for Twhere
T: IntoComponent,
Source§fn extend_children(self, out: &mut Vec<Cached>)
fn extend_children(self, out: &mut Vec<Cached>)
out.Source§impl<T> IntoComponent for Twhere
T: Component + 'static,
impl<T> IntoComponent for Twhere
T: Component + 'static,
Source§fn into_component(self) -> Box<dyn Component>
fn into_component(self) -> Box<dyn Component>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more