Skip to content

Commit

Permalink
Make background color configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
sile committed Mar 22, 2024
1 parent 80d1de2 commit de6a3e2
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Make background color configurable
- Add auto generated color palette block to the color selector window
- Add touch gesture support
- If the `gesture` setting is enabled, the following gestures will become available:
Expand Down
14 changes: 10 additions & 4 deletions src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ impl Models {
}

pub fn to_png(&self) -> Result<Vec<u8>> {
let bg_color = self
.config
.background_color
.unwrap_or(Rgba::new(0, 0, 0, 0));
let frame_count = self.config.animation.enabled_frame_count();
let frames = (0..frame_count)
.map(|frame| {
Expand All @@ -66,10 +70,12 @@ impl Models {
.get_preview_region(&self.config, frame as usize)
.pixels()
.flat_map(|position| {
let color = self
.pixel_canvas
.get_pixel(&self.config, position)
.unwrap_or(Rgba::new(0, 0, 0, 0));
let color =
if let Some(c) = self.pixel_canvas.get_pixel(&self.config, position) {
c.alpha_blend(bg_color)
} else {
bg_color
};
[color.r, color.g, color.b, color.a].into_iter()
})
.collect::<Vec<_>>()
Expand Down
3 changes: 3 additions & 0 deletions src/model/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub struct ConfigModel {

pub silhouette_preview: bool,
pub gesture: bool,
pub background_color: Option<Rgba>,
}

impl Serialize for ConfigModel {
Expand All @@ -50,6 +51,7 @@ impl Serialize for ConfigModel {
self.attrs.serialize(writer).or_fail()?;
self.silhouette_preview.serialize(writer).or_fail()?;
self.gesture.serialize(writer).or_fail()?;
self.background_color.serialize(writer).or_fail()?;
Ok(())
}
}
Expand All @@ -71,6 +73,7 @@ impl Deserialize for ConfigModel {
attrs: Deserialize::deserialize_or_default(reader).or_fail()?,
silhouette_preview: Deserialize::deserialize_or_default(reader).or_fail()?,
gesture: Deserialize::deserialize_or_default(reader).or_fail()?,
background_color: Deserialize::deserialize_or_default(reader).or_fail()?,
})
}
}
Expand Down
37 changes: 32 additions & 5 deletions src/widget/color_selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub struct ColorSelectorWidget {
alpha: BlockWidget<SliderWidget>,
palette: BlockWidget<ColorPaletteWidget>,
replace: BlockWidget<ToggleWidget>,
background: BlockWidget<ToggleWidget>,
}

impl ColorSelectorWidget {
Expand Down Expand Up @@ -63,6 +64,10 @@ impl ColorSelectorWidget {
"REPLACE OLD COLOR PIXELS".parse().expect("unreachable"),
ToggleWidget::default_off(),
),
background: BlockWidget::new(
"BACKGROUND COLOR".parse().expect("unreachable"),
ToggleWidget::default_off(),
),
}
}

Expand Down Expand Up @@ -142,6 +147,7 @@ impl Widget for ColorSelectorWidget {
self.palette.render_if_need(app, canvas);
}
self.replace.render_if_need(app, canvas);
self.background.render_if_need(app, canvas);
}

fn handle_event(&mut self, app: &mut App, event: &mut Event) -> Result<()> {
Expand Down Expand Up @@ -177,6 +183,19 @@ impl Widget for ColorSelectorWidget {
}
}

let old_background_mode = self.background.body().is_on();
self.background.handle_event(app, event).or_fail()?;
if self.background.body().is_on()
&& (old_background_mode == false || old_color != new_color)
{
if new_color.a == 0 {
app.models_mut().config.background_color = None;
} else {
app.models_mut().config.background_color = Some(new_color);
}
app.request_redraw(app.screen_size().to_region());
}

Ok(())
}

Expand All @@ -187,6 +206,7 @@ impl Widget for ColorSelectorWidget {
&mut self.alpha,
&mut self.palette,
&mut self.replace,
&mut self.background,
]
}
}
Expand All @@ -203,7 +223,8 @@ impl FixedSizeWidget for ColorSelectorWidget {
} else {
self.palette.requiring_size(app)
};
let replace = self.alpha.requiring_size(app);
let replace = self.replace.requiring_size(app);
let background = self.background.requiring_size(app);

Size::from_wh(
preview
Expand All @@ -212,7 +233,7 @@ impl FixedSizeWidget for ColorSelectorWidget {
.max(hsv.width)
.max(alpha.width)
.max(palette.width)
.max(replace.width),
.max(replace.width + MARGIN + background.width),
preview.height
+ MARGIN
+ hsv.height
Expand All @@ -223,7 +244,7 @@ impl FixedSizeWidget for ColorSelectorWidget {
+ MARGIN
+ palette.height
+ MARGIN
+ replace.height,
+ replace.height.max(background.height),
)
}

Expand All @@ -250,8 +271,14 @@ impl FixedSizeWidget for ColorSelectorWidget {

offset.y = self.palette.region().end().y + MARGIN as i32;
}
let mut replace_region = Region::new(offset, self.replace.requiring_size(app));
replace_region.size.width = self.region.size.width;
let replace_region = Region::new(offset, self.replace.requiring_size(app));
self.replace.set_region(app, replace_region);

let mut background_region = Region::new(
offset.move_x((MARGIN + replace_region.size.width) as i32),
self.background.requiring_size(app),
);
background_region.size.width += (self.region.end().x - background_region.end().x) as u32;
self.background.set_region(app, background_region);
}
}
7 changes: 5 additions & 2 deletions src/widget/pixel_canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::{
use crate::{
app::App,
canvas_ext::CanvasExt,
color,
color::{self, CANVAS_BACKGROUND},
event::Event,
gesture::{GestureEvent, GestureRecognizer},
io::IoRequest,
Expand Down Expand Up @@ -267,7 +267,10 @@ impl Widget for PixelCanvasWidget {
fn render(&self, app: &App, canvas: &mut Canvas) {
let preview_mode = app.models().preview_mode;

canvas.fill_rectangle(self.region, color::CANVAS_BACKGROUND);
canvas.fill_rectangle(self.region, CANVAS_BACKGROUND);
if let Some(bg) = app.models().config.background_color {
canvas.fill_rectangle(self.region, bg.into());
}
if preview_mode {
if app.models().config.animation.enabled_frame_count() > 1 {
self.render_frame_edges(app, canvas);
Expand Down
7 changes: 5 additions & 2 deletions src/widget/preview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::{FixedSizeWidget, Widget};
use crate::{
app::App,
canvas_ext::CanvasExt,
color,
color::{self, PREVIEW_BACKGROUND},
event::Event,
pixel::{PixelPosition, PixelRegion, PixelSize},
region_ext::RegionExt,
Expand Down Expand Up @@ -172,7 +172,10 @@ impl Widget for PreviewFrameWidget {
}

fn render(&self, app: &App, canvas: &mut Canvas) {
canvas.fill_rectangle(self.region, color::PREVIEW_BACKGROUND);
canvas.fill_rectangle(self.region, PREVIEW_BACKGROUND);
if let Some(bg) = app.models().config.background_color {
canvas.fill_rectangle(self.region, bg.into());
}
self.render_pixels(app, canvas);
}

Expand Down

0 comments on commit de6a3e2

Please sign in to comment.