186 lines
5.5 KiB
Rust
186 lines
5.5 KiB
Rust
|
//! `Colorable` is a property to simply fill an area with a color
|
||
|
|
||
|
use crate::prelude::*;
|
||
|
use anyhow::Result;
|
||
|
|
||
|
use cgmath::{vec4, Vector4};
|
||
|
|
||
|
use std::sync::atomic::{AtomicI32, Ordering::SeqCst};
|
||
|
use std::sync::{Arc, RwLock};
|
||
|
|
||
|
/// `Colorable` gives the ability to fill an area with a color
|
||
|
pub struct Colorable {
|
||
|
framable: Arc<Framable>,
|
||
|
|
||
|
descriptor_set: RwLock<Arc<DescriptorSet>>,
|
||
|
buffer: Arc<Buffer<Vector4<f32>>>,
|
||
|
|
||
|
color: RwLock<Color>,
|
||
|
|
||
|
ui_layer: AtomicI32,
|
||
|
|
||
|
left_factor: RwLock<f32>,
|
||
|
right_factor: RwLock<f32>,
|
||
|
bottom_factor: RwLock<f32>,
|
||
|
top_factor: RwLock<f32>,
|
||
|
}
|
||
|
|
||
|
impl Colorable {
|
||
|
/// Factory method for `Colorable`, returns `Arc<Colorable>`.
|
||
|
pub fn new(framable: Arc<Framable>, color: Color) -> Result<Arc<Self>> {
|
||
|
let set = framable.gui_handler().color_descriptor(color)?;
|
||
|
|
||
|
let buffer = Buffer::builder()
|
||
|
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
|
||
|
.set_memory_usage(MemoryUsage::CpuOnly)
|
||
|
.set_size(6)
|
||
|
.build(framable.gui_handler().device().clone())?;
|
||
|
|
||
|
let colorable = Arc::new(Colorable {
|
||
|
framable,
|
||
|
|
||
|
descriptor_set: RwLock::new(set),
|
||
|
buffer,
|
||
|
|
||
|
color: RwLock::new(color),
|
||
|
|
||
|
ui_layer: AtomicI32::new(0),
|
||
|
|
||
|
left_factor: RwLock::new(0.0),
|
||
|
right_factor: RwLock::new(1.0),
|
||
|
bottom_factor: RwLock::new(1.0),
|
||
|
top_factor: RwLock::new(0.0),
|
||
|
});
|
||
|
|
||
|
let colorable_clone = colorable.clone();
|
||
|
let weak_colorable = Arc::downgrade(&colorable);
|
||
|
|
||
|
colorable.framable.add_callback(
|
||
|
weak_colorable,
|
||
|
Box::new(move || colorable_clone.update_frame()),
|
||
|
);
|
||
|
|
||
|
Ok(colorable)
|
||
|
}
|
||
|
|
||
|
/// Add method
|
||
|
///
|
||
|
/// # Arguments
|
||
|
///
|
||
|
/// * `colorable` is a `&Arc<Colorable>` instance that is going to be added
|
||
|
pub fn add(self: &Arc<Self>) -> Result<()> {
|
||
|
self.framable
|
||
|
.gui_handler()
|
||
|
.add_colorable(self.ui_layer.load(SeqCst), self.clone())
|
||
|
}
|
||
|
|
||
|
/// Delete method, has to be explicitly called, otherwise it will remain in memory.
|
||
|
///
|
||
|
/// # Arguments
|
||
|
///
|
||
|
/// * `colorable` is a `&Arc<Colorable>` instance that is going to be deleted
|
||
|
pub fn delete(self: &Arc<Self>) -> Result<()> {
|
||
|
self.framable
|
||
|
.gui_handler()
|
||
|
.delete_colorable(self.ui_layer.load(SeqCst), self)
|
||
|
}
|
||
|
|
||
|
pub fn clear_callback(self: &Arc<Self>) {
|
||
|
let weak_colorable = Arc::downgrade(self);
|
||
|
self.framable.remove_callback(weak_colorable);
|
||
|
}
|
||
|
|
||
|
pub fn set_ui_layer(&self, ui_layer: i32) {
|
||
|
self.ui_layer.store(ui_layer, SeqCst);
|
||
|
}
|
||
|
|
||
|
/// Changes text color
|
||
|
///
|
||
|
/// # Arguments
|
||
|
///
|
||
|
/// * `color` defines the color
|
||
|
pub fn set_color(&self, color: Color) -> Result<()> {
|
||
|
let set = self.framable.gui_handler().color_descriptor(color)?;
|
||
|
|
||
|
*self.color.write().unwrap() = color;
|
||
|
*self.descriptor_set.write().unwrap() = set;
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
pub fn color(&self) -> Color {
|
||
|
*self.color.read().unwrap()
|
||
|
}
|
||
|
|
||
|
/// Returns the internal vulkan buffer
|
||
|
pub fn buffer(&self) -> &Arc<Buffer<Vector4<f32>>> {
|
||
|
&self.buffer
|
||
|
}
|
||
|
|
||
|
/// Returns the internal vulkan descriptor set
|
||
|
pub fn descriptor_set(&self) -> Arc<DescriptorSet> {
|
||
|
self.descriptor_set.read().unwrap().clone()
|
||
|
}
|
||
|
|
||
|
pub fn set_left_factor(&self, factor: f32) {
|
||
|
*self.left_factor.write().unwrap() = factor;
|
||
|
}
|
||
|
|
||
|
pub fn set_right_factor(&self, factor: f32) {
|
||
|
*self.right_factor.write().unwrap() = factor;
|
||
|
}
|
||
|
|
||
|
pub fn set_top_factor(&self, factor: f32) {
|
||
|
*self.top_factor.write().unwrap() = factor;
|
||
|
}
|
||
|
|
||
|
pub fn set_bottom_factor(&self, factor: f32) {
|
||
|
*self.bottom_factor.write().unwrap() = factor;
|
||
|
}
|
||
|
|
||
|
/// Update frame method if the original frame is invalidated
|
||
|
pub fn update_frame(&self) -> Result<()> {
|
||
|
let mut frame = self.buffer.map_complete()?;
|
||
|
|
||
|
let x_start = self.framable.left() as f32;
|
||
|
let y_start = self.framable.top() as f32;
|
||
|
|
||
|
let width = (self.framable.right() - self.framable.left()) as f32;
|
||
|
let height = (self.framable.bottom() - self.framable.top()) as f32;
|
||
|
|
||
|
let left = x_start + width * *self.left_factor.read().unwrap();
|
||
|
let right = x_start + width * *self.right_factor.read().unwrap();
|
||
|
let top = y_start + height * *self.top_factor.read().unwrap();
|
||
|
let bottom = y_start + height * *self.bottom_factor.read().unwrap();
|
||
|
|
||
|
frame[0] = self.framable.ortho() * vec4(left, bottom, 0.0, 1.0);
|
||
|
frame[1] = self.framable.ortho() * vec4(right, bottom, 0.0, 1.0);
|
||
|
frame[2] = self.framable.ortho() * vec4(right, top, 0.0, 1.0);
|
||
|
frame[3] = self.framable.ortho() * vec4(right, top, 0.0, 1.0);
|
||
|
frame[4] = self.framable.ortho() * vec4(left, top, 0.0, 1.0);
|
||
|
frame[5] = self.framable.ortho() * vec4(left, bottom, 0.0, 1.0);
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
pub(crate) fn vertex_input_state() -> (
|
||
|
Vec<VkVertexInputBindingDescription>,
|
||
|
Vec<VkVertexInputAttributeDescription>,
|
||
|
) {
|
||
|
let input_bindings = vec![VkVertexInputBindingDescription {
|
||
|
binding: 0,
|
||
|
stride: std::mem::size_of::<Vector4<f32>>() as u32,
|
||
|
inputRate: VK_VERTEX_INPUT_RATE_VERTEX,
|
||
|
}];
|
||
|
|
||
|
let input_attributes = vec![VkVertexInputAttributeDescription {
|
||
|
location: 0,
|
||
|
binding: 0,
|
||
|
format: VK_FORMAT_R32G32B32A32_SFLOAT,
|
||
|
offset: 0,
|
||
|
}];
|
||
|
|
||
|
(input_bindings, input_attributes)
|
||
|
}
|
||
|
}
|