Skip to content

Commit

Permalink
Image opacity support
Browse files Browse the repository at this point in the history
  • Loading branch information
ecton committed Sep 16, 2024
1 parent 01b764d commit e0df3b0
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 13 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 10 additions & 4 deletions src/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down
16 changes: 14 additions & 2 deletions src/widgets/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {
Expand All @@ -26,6 +28,7 @@ impl Image {
Self {
contents: contents.into_value(),
scaling: Value::default(),
opacity: Value::Constant(ZeroToOne::ONE),
}
}

Expand All @@ -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
Expand Down Expand Up @@ -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);
});
}

Expand Down

0 comments on commit e0df3b0

Please sign in to comment.