Image opacity support

This commit is contained in:
Jonathan Johnson 2024-09-16 14:15:49 -07:00
parent 01b764de0b
commit e0df3b0017
No known key found for this signature in database
GPG key ID: A66D6A34D6620579
4 changed files with 34 additions and 13 deletions

View file

@ -45,6 +45,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
resize event.
- `PlatformWindow::outer_size` is a new function that returns the window's
current outer size.
- `Graphics::draw_texture` and `Graphics::draw_textured_shape` now both accept
an opactiy parameter controlling how opaque the texture should be rendered at.
### Changed
@ -161,6 +163,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
initialized.
- `Window::on_file_drop` is a new callback that is invoked when file drop events
occur for the window.
- `Image::opacity` allows rendering the image with a given opacity.
[139]: https://github.com/khonsulabs/cushy/issues/139

14
Cargo.lock generated
View file

@ -117,9 +117,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.88"
version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356"
checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
[[package]]
name = "appit"
@ -418,9 +418,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.1.18"
version = "1.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476"
checksum = "2d74707dde2ba56f86ae90effb3b43ddd369504387e718014de010cec7959800"
dependencies = [
"jobserver",
"libc",
@ -1311,7 +1311,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]]
name = "kludgine"
version = "0.11.0"
source = "git+https://github.com/khonsulabs/kludgine#eccacdaffe4a60d1887a201a68656f0058a12088"
source = "git+https://github.com/khonsulabs/kludgine#186a350402da7068aea248801477376611b5f12a"
dependencies = [
"ahash",
"alot",
@ -1963,9 +1963,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.20.0"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ea5043e58958ee56f3e15a90aee535795cd7dfd319846288d93c5b57d85cbe"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "orbclient"

View file

@ -170,14 +170,18 @@ impl<'clip, 'gfx, 'pass> Graphics<'clip, 'gfx, 'pass> {
}
/// Draws `texture` at `destination`, scaling as necessary.
pub fn draw_texture<Unit>(&mut self, texture: &impl TextureSource, destination: Rect<Unit>)
where
pub fn draw_texture<Unit>(
&mut self,
texture: &impl TextureSource,
destination: Rect<Unit>,
opacity: ZeroToOne,
) where
Unit: figures::ScreenUnit + ShaderScalable,
i32: From<<Unit as IntoSigned>::Signed>,
{
let translate = Point::<Unit>::from_px(self.translation(), self.scale());
self.renderer
.draw_texture(texture, destination + translate, *self.opacity);
.draw_texture(texture, destination + translate, *(self.opacity * opacity));
}
/// Draws a shape that was created with texture coordinates, applying the
@ -186,16 +190,18 @@ impl<'clip, 'gfx, 'pass> Graphics<'clip, 'gfx, 'pass> {
&mut self,
shape: impl Into<Drawable<&'shape Shape, Unit>>,
texture: &impl TextureSource,
opacity: ZeroToOne,
) where
Unit: Zero + ShaderScalable + figures::ScreenUnit + Copy,
i32: From<<Unit as IntoSigned>::Signed>,
Shape: ShapeSource<Unit, true> + 'shape,
{
let mut shape = shape.into();
let effective_opacity = self.opacity * opacity;
shape.opacity = Some(
shape
.opacity
.map_or(*self.opacity, |opacity| opacity * *self.opacity),
.map_or(*effective_opacity, |opacity| opacity * *effective_opacity),
);
shape.translation += Point::<Unit>::from_px(self.translation(), self.scale());
self.renderer.draw_textured_shape(shape, texture);

View file

@ -5,7 +5,7 @@ use figures::{FloatConversion, IntoSigned, IntoUnsigned, Point, Rect, Size, Zero
use kludgine::{AnyTexture, CollectedTexture, LazyTexture, SharedTexture, Texture, TextureRegion};
use crate::animation::ZeroToOne;
use crate::context::LayoutContext;
use crate::context::{LayoutContext, Trackable};
use crate::value::{IntoValue, Source, Value};
use crate::widget::Widget;
use crate::ConstraintLimit;
@ -17,6 +17,8 @@ pub struct Image {
pub contents: Value<AnyTexture>,
/// The scaling strategy to apply.
pub scaling: Value<ImageScaling>,
/// The opacity to render the image with.
pub opacity: Value<ZeroToOne>,
}
impl Image {
@ -26,6 +28,7 @@ impl Image {
Self {
contents: contents.into_value(),
scaling: Value::default(),
opacity: Value::Constant(ZeroToOne::ONE),
}
}
@ -36,6 +39,13 @@ impl Image {
self
}
/// Applies `opacity` when drawing the image, returns self.
#[must_use]
pub fn opacity(mut self, opacity: impl IntoValue<ZeroToOne>) -> Self {
self.opacity = opacity.into_value();
self
}
/// Applies the aspect-fit scaling strategy and returns self.
///
/// The aspect-fit scaling strategy scales the image to be the largest size
@ -145,9 +155,11 @@ impl Image {
impl Widget for Image {
fn redraw(&mut self, context: &mut crate::context::GraphicsContext<'_, '_, '_, '_>) {
self.contents.invalidate_when_changed(context);
let opacity = self.opacity.get_tracking_redraw(context);
self.contents.map(|texture| {
let rect = self.calculate_image_rect(texture, context.gfx.size(), context);
context.gfx.draw_texture(texture, rect);
context.gfx.draw_texture(texture, rect, opacity);
});
}