139 lines
4.2 KiB
Rust
139 lines
4.2 KiB
Rust
use sfml::{
|
|
graphics::{Color, Drawable, Font, RectangleShape, Shape, Text, Transformable},
|
|
system::Vector2f,
|
|
};
|
|
|
|
use crate::{button::Button, constants::{button::{FONT_SIZE_BIG, FONT_SIZE_SMALL, RADIUS_BIG, RADIUS_SMALL}, common::WINDOW_SIZE_F, counter::{DEFAULT_BG_COLOR, DEFAULT_OUTLINE_COLOR, DEFAULT_OUTLINE_THICKNESS, FONT_SIZE, HOFFSET_PERC, SIZE, VOFFSET_PERC}}};
|
|
|
|
pub struct Counter<'a> {
|
|
count: u32,
|
|
count_str: Text<'a>,
|
|
background: RectangleShape<'a>,
|
|
dec_button: Button<'a>,
|
|
inc_button: Button<'a>,
|
|
reset_button: Button<'a>,
|
|
}
|
|
|
|
impl<'a> Counter<'a> {
|
|
pub fn new(count: u32, font: &'a Font) -> Self {
|
|
let mut background = RectangleShape::with_size(SIZE);
|
|
background.set_fill_color(DEFAULT_BG_COLOR);
|
|
background.set_outline_color(DEFAULT_OUTLINE_COLOR);
|
|
background.set_outline_thickness(DEFAULT_OUTLINE_THICKNESS);
|
|
background.set_position((WINDOW_SIZE_F.0/2., WINDOW_SIZE_F.1/2.));
|
|
let bounds = background.local_bounds();
|
|
background.set_origin((
|
|
bounds.left + bounds.width / 2.,
|
|
bounds.top + bounds.height / 2.,
|
|
));
|
|
|
|
let mut count_str = Text::new(&count.to_string(), font, FONT_SIZE);
|
|
count_str.set_fill_color(Color::BLACK);
|
|
count_str.set_position((WINDOW_SIZE_F.0/2., WINDOW_SIZE_F.1/2.));
|
|
let bounds = count_str.local_bounds();
|
|
count_str.set_origin((
|
|
bounds.left + bounds.width / 2.,
|
|
bounds.top + bounds.height / 2.,
|
|
));
|
|
|
|
let dec_button = Button::new(
|
|
"-".to_string(),
|
|
font,
|
|
FONT_SIZE_BIG,
|
|
Vector2f::new(
|
|
background.position().x - HOFFSET_PERC*background.size().x,
|
|
background.position().y,
|
|
),
|
|
RADIUS_BIG
|
|
);
|
|
|
|
let inc_button = Button::new(
|
|
"+".to_string(),
|
|
font,
|
|
FONT_SIZE_BIG,
|
|
Vector2f::new(
|
|
background.position().x + HOFFSET_PERC*background.size().x,
|
|
background.position().y,
|
|
),
|
|
RADIUS_BIG
|
|
);
|
|
|
|
let reset_button = Button::new(
|
|
"R".to_string(),
|
|
font,
|
|
FONT_SIZE_SMALL,
|
|
Vector2f::new(
|
|
background.position().x,
|
|
background.position().y + (1. - VOFFSET_PERC)*background.size().y/2.
|
|
),
|
|
RADIUS_SMALL
|
|
);
|
|
|
|
Counter {
|
|
count,
|
|
count_str,
|
|
background,
|
|
dec_button,
|
|
inc_button,
|
|
reset_button,
|
|
}
|
|
}
|
|
|
|
pub fn inc(&mut self) {
|
|
if self.count < u32::MAX {
|
|
self.count += 1;
|
|
}
|
|
self.update();
|
|
}
|
|
|
|
pub fn dec(&mut self) {
|
|
if self.count > 0 {
|
|
self.count -= 1;
|
|
}
|
|
self.update();
|
|
}
|
|
|
|
pub fn reset(&mut self) {
|
|
self.count = 0;
|
|
self.update();
|
|
}
|
|
|
|
fn update(&mut self) {
|
|
self.count_str.set_string(&self.count.to_string());
|
|
let digits = self.count.checked_ilog10().unwrap_or(0);
|
|
if self.count % (10 * if digits == 0 { 1 } else { digits }) == 0 {
|
|
let bounds = self.count_str.local_bounds();
|
|
self.count_str.set_origin((
|
|
bounds.left + bounds.width / 2.,
|
|
bounds.top + bounds.height / 2.,
|
|
));
|
|
}
|
|
}
|
|
|
|
pub fn handle_mouse(&mut self, m_pos: impl Into<Vector2f>) {
|
|
let m_pos = m_pos.into();
|
|
if self.dec_button.contains(m_pos) {
|
|
self.dec();
|
|
}
|
|
if self.inc_button.contains(m_pos) {
|
|
self.inc();
|
|
}
|
|
if self.reset_button.contains(m_pos) {
|
|
self.reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'d> Drawable for Counter<'d> {
|
|
fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
|
|
&'a self,
|
|
target: &mut dyn sfml::graphics::RenderTarget,
|
|
states: &sfml::graphics::RenderStates<'texture, 'shader, 'shader_texture>,
|
|
) {
|
|
self.background.draw(target, states);
|
|
self.count_str.draw(target, states);
|
|
self.dec_button.draw(target, states);
|
|
self.inc_button.draw(target, states);
|
|
self.reset_button.draw(target, states);
|
|
}
|
|
}
|