poc window decorations
This commit is contained in:
@@ -10,8 +10,8 @@ use crate::{
|
|||||||
globals::Globals,
|
globals::Globals,
|
||||||
layout::Widget,
|
layout::Widget,
|
||||||
renderer_vk::text::{
|
renderer_vk::text::{
|
||||||
TextShadow,
|
|
||||||
custom_glyph::{CustomGlyph, CustomGlyphData},
|
custom_glyph::{CustomGlyph, CustomGlyphData},
|
||||||
|
TextShadow,
|
||||||
},
|
},
|
||||||
stack::{self, ScissorBoundary, ScissorStack, TransformStack},
|
stack::{self, ScissorBoundary, ScissorStack, TransformStack},
|
||||||
widget::{self, ScrollbarInfo, WidgetState},
|
widget::{self, ScrollbarInfo, WidgetState},
|
||||||
@@ -147,6 +147,11 @@ impl Color {
|
|||||||
let a = (self.a.clamp(0.0, 1.0) * 255.0).round() as u8;
|
let a = (self.a.clamp(0.0, 1.0) * 255.0).round() as u8;
|
||||||
format!("#{r:02X}{g:02X}{b:02X}{a:02X}")
|
format!("#{r:02X}{g:02X}{b:02X}{a:02X}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn as_arr(&self) -> [f32; 4] {
|
||||||
|
[self.r, self.b, self.g, self.a]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Color {
|
impl Default for Color {
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ use vulkano::{
|
|||||||
view::ImageView,
|
view::ImageView,
|
||||||
},
|
},
|
||||||
pipeline::{
|
pipeline::{
|
||||||
Pipeline, PipelineBindPoint,
|
|
||||||
graphics::{self, vertex_input::Vertex, viewport::Viewport},
|
graphics::{self, vertex_input::Vertex, viewport::Viewport},
|
||||||
|
Pipeline, PipelineBindPoint,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{WGfx, pipeline::WGfxPipeline};
|
use super::{pipeline::WGfxPipeline, WGfx};
|
||||||
|
|
||||||
pub struct WGfxPass<V> {
|
pub struct WGfxPass<V> {
|
||||||
pub command_buffer: Arc<SecondaryAutoCommandBuffer>,
|
pub command_buffer: Arc<SecondaryAutoCommandBuffer>,
|
||||||
@@ -34,6 +34,7 @@ where
|
|||||||
pub(super) fn new(
|
pub(super) fn new(
|
||||||
pipeline: &Arc<WGfxPipeline<V>>,
|
pipeline: &Arc<WGfxPipeline<V>>,
|
||||||
dimensions: [f32; 2],
|
dimensions: [f32; 2],
|
||||||
|
offset: [f32; 2],
|
||||||
vertex_buffer: Subbuffer<[V]>,
|
vertex_buffer: Subbuffer<[V]>,
|
||||||
vertices: Range<u32>,
|
vertices: Range<u32>,
|
||||||
instances: Range<u32>,
|
instances: Range<u32>,
|
||||||
@@ -41,7 +42,7 @@ where
|
|||||||
vk_scissor: &graphics::viewport::Scissor,
|
vk_scissor: &graphics::viewport::Scissor,
|
||||||
) -> anyhow::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
let viewport = Viewport {
|
let viewport = Viewport {
|
||||||
offset: [0.0, 0.0],
|
offset,
|
||||||
extent: dimensions,
|
extent: dimensions,
|
||||||
depth_range: 0.0..=1.0,
|
depth_range: 0.0..=1.0,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
use std::{marker::PhantomData, ops::Range, sync::Arc};
|
use std::{marker::PhantomData, ops::Range, sync::Arc};
|
||||||
|
|
||||||
use smallvec::{SmallVec, smallvec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
buffer::{
|
buffer::{
|
||||||
BufferContents, BufferUsage, Subbuffer,
|
|
||||||
allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo},
|
allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo},
|
||||||
|
BufferContents, BufferUsage, Subbuffer,
|
||||||
},
|
},
|
||||||
descriptor_set::{
|
descriptor_set::{
|
||||||
DescriptorSet, WriteDescriptorSet,
|
|
||||||
layout::{DescriptorBindingFlags, DescriptorSetLayoutCreateFlags},
|
layout::{DescriptorBindingFlags, DescriptorSetLayoutCreateFlags},
|
||||||
|
DescriptorSet, WriteDescriptorSet,
|
||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{
|
image::{
|
||||||
@@ -17,9 +17,8 @@ use vulkano::{
|
|||||||
},
|
},
|
||||||
memory::allocator::MemoryTypeFilter,
|
memory::allocator::MemoryTypeFilter,
|
||||||
pipeline::{
|
pipeline::{
|
||||||
DynamicState, GraphicsPipeline, Pipeline, PipelineLayout,
|
|
||||||
graphics::{
|
graphics::{
|
||||||
self, GraphicsPipelineCreateInfo,
|
self,
|
||||||
color_blend::{AttachmentBlend, ColorBlendAttachmentState, ColorBlendState},
|
color_blend::{AttachmentBlend, ColorBlendAttachmentState, ColorBlendState},
|
||||||
input_assembly::{InputAssemblyState, PrimitiveTopology},
|
input_assembly::{InputAssemblyState, PrimitiveTopology},
|
||||||
multisample::MultisampleState,
|
multisample::MultisampleState,
|
||||||
@@ -27,13 +26,15 @@ use vulkano::{
|
|||||||
subpass::PipelineRenderingCreateInfo,
|
subpass::PipelineRenderingCreateInfo,
|
||||||
vertex_input::{Vertex, VertexDefinition, VertexInputState},
|
vertex_input::{Vertex, VertexDefinition, VertexInputState},
|
||||||
viewport::ViewportState,
|
viewport::ViewportState,
|
||||||
|
GraphicsPipelineCreateInfo,
|
||||||
},
|
},
|
||||||
layout::PipelineDescriptorSetLayoutCreateInfo,
|
layout::PipelineDescriptorSetLayoutCreateInfo,
|
||||||
|
DynamicState, GraphicsPipeline, Pipeline, PipelineLayout,
|
||||||
},
|
},
|
||||||
shader::{EntryPoint, ShaderModule},
|
shader::{EntryPoint, ShaderModule},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{WGfx, pass::WGfxPass};
|
use super::{pass::WGfxPass, WGfx};
|
||||||
|
|
||||||
pub struct WGfxPipeline<V> {
|
pub struct WGfxPipeline<V> {
|
||||||
pub graphics: Arc<WGfx>,
|
pub graphics: Arc<WGfx>,
|
||||||
@@ -266,6 +267,7 @@ where
|
|||||||
pub fn create_pass(
|
pub fn create_pass(
|
||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
dimensions: [f32; 2],
|
dimensions: [f32; 2],
|
||||||
|
offset: [f32; 2],
|
||||||
vertex_buffer: Subbuffer<[V]>,
|
vertex_buffer: Subbuffer<[V]>,
|
||||||
vertices: Range<u32>,
|
vertices: Range<u32>,
|
||||||
instances: Range<u32>,
|
instances: Range<u32>,
|
||||||
@@ -275,6 +277,7 @@ where
|
|||||||
WGfxPass::new(
|
WGfxPass::new(
|
||||||
&self.clone(),
|
&self.clone(),
|
||||||
dimensions,
|
dimensions,
|
||||||
|
offset,
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
vertices,
|
vertices,
|
||||||
instances,
|
instances,
|
||||||
|
|||||||
@@ -200,6 +200,7 @@ impl ImageRenderer {
|
|||||||
|
|
||||||
let pass = self.pipeline.inner.create_pass(
|
let pass = self.pipeline.inner.create_pass(
|
||||||
[res[0] as _, res[1] as _],
|
[res[0] as _, res[1] as _],
|
||||||
|
[0.0, 0.0],
|
||||||
vert_buffer.clone(),
|
vert_buffer.clone(),
|
||||||
0..4,
|
0..4,
|
||||||
0..1,
|
0..1,
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ use vulkano::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
drawing::{Boundary, Rectangle},
|
drawing::{Boundary, Rectangle},
|
||||||
gfx::{
|
gfx::{
|
||||||
BLEND_ALPHA, WGfx,
|
|
||||||
cmd::GfxCommandBuffer,
|
cmd::GfxCommandBuffer,
|
||||||
pass::WGfxPass,
|
pass::WGfxPass,
|
||||||
pipeline::{WGfxPipeline, WPipelineCreateInfo},
|
pipeline::{WGfxPipeline, WPipelineCreateInfo},
|
||||||
|
WGfx, BLEND_ALPHA,
|
||||||
},
|
},
|
||||||
renderer_vk::model_buffer::ModelBuffer,
|
renderer_vk::model_buffer::ModelBuffer,
|
||||||
};
|
};
|
||||||
@@ -151,6 +151,7 @@ impl RectRenderer {
|
|||||||
let set1 = self.model_buffer.get_rect_descriptor(&self.pipeline);
|
let set1 = self.model_buffer.get_rect_descriptor(&self.pipeline);
|
||||||
let pass = self.pipeline.color_rect.create_pass(
|
let pass = self.pipeline.color_rect.create_pass(
|
||||||
[res[0] as _, res[1] as _],
|
[res[0] as _, res[1] as _],
|
||||||
|
[0.0, 0.0],
|
||||||
self.vert_buffer.clone(),
|
self.vert_buffer.clone(),
|
||||||
0..4,
|
0..4,
|
||||||
0..self.rect_vertices.len() as _,
|
0..self.rect_vertices.len() as _,
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
ContentType, FontSystem, GlyphDetails, GpuCacheStatus, SwashCache, TextArea,
|
|
||||||
custom_glyph::{CustomGlyphCacheKey, RasterizeCustomGlyphRequest, RasterizedCustomGlyph},
|
custom_glyph::{CustomGlyphCacheKey, RasterizeCustomGlyphRequest, RasterizedCustomGlyph},
|
||||||
text_atlas::{GlyphVertex, TextAtlas, TextPipeline},
|
text_atlas::{GlyphVertex, TextAtlas, TextPipeline},
|
||||||
|
ContentType, FontSystem, GlyphDetails, GpuCacheStatus, SwashCache, TextArea,
|
||||||
};
|
};
|
||||||
use cosmic_text::{Color, SubpixelBin, SwashContent};
|
use cosmic_text::{Color, SubpixelBin, SwashContent};
|
||||||
use etagere::size2;
|
use etagere::size2;
|
||||||
@@ -272,6 +272,7 @@ impl TextRenderer {
|
|||||||
|
|
||||||
let pass = self.pipeline.inner.create_pass(
|
let pass = self.pipeline.inner.create_pass(
|
||||||
[res[0] as _, res[1] as _],
|
[res[0] as _, res[1] as _],
|
||||||
|
[0.0, 0.0],
|
||||||
self.vertex_buffer.clone(),
|
self.vertex_buffer.clone(),
|
||||||
0..4,
|
0..4,
|
||||||
0..self.glyph_vertices.len() as u32,
|
0..self.glyph_vertices.len() as u32,
|
||||||
|
|||||||
23
wlx-overlay-s/src/assets/gui/decor.xml
Normal file
23
wlx-overlay-s/src/assets/gui/decor.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<layout>
|
||||||
|
<elements>
|
||||||
|
<rectangle
|
||||||
|
width="100%" height="100%"
|
||||||
|
margin="4" box_sizing="border_box"
|
||||||
|
border_color="~color_faded" border="2"
|
||||||
|
round="50%" color="~color_faded"
|
||||||
|
justify_content="space_between">
|
||||||
|
|
||||||
|
<label id="label_title" color="~color_text" size="18" text="Test" weight="bold" />
|
||||||
|
|
||||||
|
|
||||||
|
<Button macro="button_style" tooltip="WATCH.EDIT_MODE" _press="" border_color="~color_faded_translucent" color="~color_faded_50" color2="~color_faded_10">
|
||||||
|
<sprite width="24" height="24" src="watch/edit.svg" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button macro="button_style" tooltip="DECOR.CLOSE_WINDOW" _long_release="" border_color="~color_danger_translucent" color="~color_danger_50" color2="~color_danger_10">
|
||||||
|
<sprite width="24" height="24" src="edit/close.svg" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
</rectangle>
|
||||||
|
</elements>
|
||||||
|
</layout>
|
||||||
@@ -75,6 +75,7 @@ impl LinePool {
|
|||||||
|
|
||||||
let pass = self.pipeline.create_pass(
|
let pass = self.pipeline.create_pass(
|
||||||
[1.0, 1.0],
|
[1.0, 1.0],
|
||||||
|
[0.0, 0.0],
|
||||||
app.gfx_extras.quad_verts.clone(),
|
app.gfx_extras.quad_verts.clone(),
|
||||||
0..4,
|
0..4,
|
||||||
0..1,
|
0..1,
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ impl Skybox {
|
|||||||
let set1 = pipeline.uniform_buffer_upload(1, vec![1f32])?;
|
let set1 = pipeline.uniform_buffer_upload(1, vec![1f32])?;
|
||||||
let pass = pipeline.create_pass(
|
let pass = pipeline.create_pass(
|
||||||
tgt.extent_f32(),
|
tgt.extent_f32(),
|
||||||
|
[0.0, 0.0],
|
||||||
app.gfx_extras.quad_verts.clone(),
|
app.gfx_extras.quad_verts.clone(),
|
||||||
0..4,
|
0..4,
|
||||||
0..1,
|
0..1,
|
||||||
@@ -161,6 +162,7 @@ impl Skybox {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let pass = pipeline.create_pass(
|
let pass = pipeline.create_pass(
|
||||||
tgt.extent_f32(),
|
tgt.extent_f32(),
|
||||||
|
[0.0, 0.0],
|
||||||
app.gfx_extras.quad_verts.clone(),
|
app.gfx_extras.quad_verts.clone(),
|
||||||
0..4,
|
0..4,
|
||||||
0..1,
|
0..1,
|
||||||
|
|||||||
@@ -192,12 +192,20 @@ impl OverlayBackend for ScreenBackend {
|
|||||||
.meta
|
.meta
|
||||||
.is_some_and(|old| old.extent[..2] != meta.extent[..2])
|
.is_some_and(|old| old.extent[..2] != meta.extent[..2])
|
||||||
{
|
{
|
||||||
pipeline.set_extent(app, [meta.extent[0] as _, meta.extent[1] as _])?;
|
pipeline.set_extent(
|
||||||
|
app,
|
||||||
|
[meta.extent[0] as _, meta.extent[1] as _],
|
||||||
|
[0., 0.],
|
||||||
|
)?;
|
||||||
self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr()));
|
self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let pipeline =
|
let pipeline = ScreenPipeline::new(
|
||||||
ScreenPipeline::new(&meta, app, self.stereo.unwrap_or(StereoMode::None))?;
|
&meta,
|
||||||
|
app,
|
||||||
|
self.stereo.unwrap_or(StereoMode::None),
|
||||||
|
[0., 0.],
|
||||||
|
)?;
|
||||||
meta.extent[2] = pipeline.get_depth();
|
meta.extent[2] = pipeline.get_depth();
|
||||||
self.pipeline = Some(pipeline);
|
self.pipeline = Some(pipeline);
|
||||||
self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr()));
|
self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr()));
|
||||||
|
|||||||
@@ -46,11 +46,17 @@ pub struct ScreenPipeline {
|
|||||||
pipeline: Arc<WGfxPipeline<Vert2Uv>>,
|
pipeline: Arc<WGfxPipeline<Vert2Uv>>,
|
||||||
buf_alpha: Subbuffer<[f32]>,
|
buf_alpha: Subbuffer<[f32]>,
|
||||||
extentf: [f32; 2],
|
extentf: [f32; 2],
|
||||||
|
offsetf: [f32; 2],
|
||||||
stereo: StereoMode,
|
stereo: StereoMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScreenPipeline {
|
impl ScreenPipeline {
|
||||||
pub fn new(meta: &FrameMeta, app: &mut AppState, stereo: StereoMode) -> anyhow::Result<Self> {
|
pub fn new(
|
||||||
|
meta: &FrameMeta,
|
||||||
|
app: &mut AppState,
|
||||||
|
stereo: StereoMode,
|
||||||
|
offsetf: [f32; 2],
|
||||||
|
) -> anyhow::Result<Self> {
|
||||||
let extentf = [meta.extent[0] as f32, meta.extent[1] as f32];
|
let extentf = [meta.extent[0] as f32, meta.extent[1] as f32];
|
||||||
|
|
||||||
let pipeline = app.gfx.create_pipeline(
|
let pipeline = app.gfx.create_pipeline(
|
||||||
@@ -70,11 +76,19 @@ impl ScreenPipeline {
|
|||||||
app,
|
app,
|
||||||
pipeline.clone(),
|
pipeline.clone(),
|
||||||
extentf,
|
extentf,
|
||||||
|
offsetf,
|
||||||
buf_alpha.clone()
|
buf_alpha.clone()
|
||||||
)?],
|
)?],
|
||||||
mouse: Self::create_mouse_pass(app, pipeline.clone(), extentf, buf_alpha.clone())?,
|
mouse: Self::create_mouse_pass(
|
||||||
|
app,
|
||||||
|
pipeline.clone(),
|
||||||
|
extentf,
|
||||||
|
offsetf,
|
||||||
|
buf_alpha.clone(),
|
||||||
|
)?,
|
||||||
pipeline,
|
pipeline,
|
||||||
extentf,
|
extentf,
|
||||||
|
offsetf,
|
||||||
buf_alpha,
|
buf_alpha,
|
||||||
stereo,
|
stereo,
|
||||||
};
|
};
|
||||||
@@ -94,6 +108,7 @@ impl ScreenPipeline {
|
|||||||
app,
|
app,
|
||||||
self.pipeline.clone(),
|
self.pipeline.clone(),
|
||||||
self.extentf,
|
self.extentf,
|
||||||
|
self.offsetf,
|
||||||
self.buf_alpha.clone(),
|
self.buf_alpha.clone(),
|
||||||
)?);
|
)?);
|
||||||
}
|
}
|
||||||
@@ -113,15 +128,34 @@ impl ScreenPipeline {
|
|||||||
self.pass.len() as _
|
self.pass.len() as _
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_extent(&mut self, app: &mut AppState, extentf: [f32; 2]) -> anyhow::Result<()> {
|
pub fn set_extent(
|
||||||
|
&mut self,
|
||||||
|
app: &mut AppState,
|
||||||
|
extentf: [f32; 2],
|
||||||
|
offsetf: [f32; 2],
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
self.extentf = extentf;
|
||||||
|
self.offsetf = offsetf;
|
||||||
|
|
||||||
for (eye, pass) in self.pass.iter_mut().enumerate() {
|
for (eye, pass) in self.pass.iter_mut().enumerate() {
|
||||||
*pass = Self::create_pass(app, self.pipeline.clone(), extentf, self.buf_alpha.clone())?;
|
*pass = Self::create_pass(
|
||||||
|
app,
|
||||||
|
self.pipeline.clone(),
|
||||||
|
extentf,
|
||||||
|
offsetf,
|
||||||
|
self.buf_alpha.clone(),
|
||||||
|
)?;
|
||||||
let verts = stereo_mode_to_verts(self.stereo, eye);
|
let verts = stereo_mode_to_verts(self.stereo, eye);
|
||||||
pass.buf_vert.write()?.copy_from_slice(&verts);
|
pass.buf_vert.write()?.copy_from_slice(&verts);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.mouse =
|
self.mouse = Self::create_mouse_pass(
|
||||||
Self::create_mouse_pass(app, self.pipeline.clone(), extentf, self.buf_alpha.clone())?;
|
app,
|
||||||
|
self.pipeline.clone(),
|
||||||
|
extentf,
|
||||||
|
offsetf,
|
||||||
|
self.buf_alpha.clone(),
|
||||||
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +163,7 @@ impl ScreenPipeline {
|
|||||||
app: &mut AppState,
|
app: &mut AppState,
|
||||||
pipeline: Arc<WGfxPipeline<Vert2Uv>>,
|
pipeline: Arc<WGfxPipeline<Vert2Uv>>,
|
||||||
extentf: [f32; 2],
|
extentf: [f32; 2],
|
||||||
|
offsetf: [f32; 2],
|
||||||
buf_alpha: Subbuffer<[f32]>,
|
buf_alpha: Subbuffer<[f32]>,
|
||||||
) -> anyhow::Result<BufPass> {
|
) -> anyhow::Result<BufPass> {
|
||||||
let set0 = pipeline.uniform_sampler(
|
let set0 = pipeline.uniform_sampler(
|
||||||
@@ -143,6 +178,7 @@ impl ScreenPipeline {
|
|||||||
|
|
||||||
let pass = pipeline.create_pass(
|
let pass = pipeline.create_pass(
|
||||||
extentf,
|
extentf,
|
||||||
|
offsetf,
|
||||||
buf_vert.clone(),
|
buf_vert.clone(),
|
||||||
0..4,
|
0..4,
|
||||||
0..1,
|
0..1,
|
||||||
@@ -157,6 +193,7 @@ impl ScreenPipeline {
|
|||||||
app: &mut AppState,
|
app: &mut AppState,
|
||||||
pipeline: Arc<WGfxPipeline<Vert2Uv>>,
|
pipeline: Arc<WGfxPipeline<Vert2Uv>>,
|
||||||
extentf: [f32; 2],
|
extentf: [f32; 2],
|
||||||
|
offsetf: [f32; 2],
|
||||||
buf_alpha: Subbuffer<[f32]>,
|
buf_alpha: Subbuffer<[f32]>,
|
||||||
) -> anyhow::Result<BufPass> {
|
) -> anyhow::Result<BufPass> {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
@@ -184,6 +221,7 @@ impl ScreenPipeline {
|
|||||||
let set1 = pipeline.buffer(1, buf_alpha)?;
|
let set1 = pipeline.buffer(1, buf_alpha)?;
|
||||||
let pass = pipeline.create_pass(
|
let pass = pipeline.create_pass(
|
||||||
extentf,
|
extentf,
|
||||||
|
offsetf,
|
||||||
buf_vert.clone(),
|
buf_vert.clone(),
|
||||||
0..4,
|
0..4,
|
||||||
0..1,
|
0..1,
|
||||||
|
|||||||
@@ -7,7 +7,15 @@ use std::sync::Arc;
|
|||||||
use vulkano::{
|
use vulkano::{
|
||||||
buffer::BufferUsage, image::view::ImageView, pipeline::graphics::color_blend::AttachmentBlend,
|
buffer::BufferUsage, image::view::ImageView, pipeline::graphics::color_blend::AttachmentBlend,
|
||||||
};
|
};
|
||||||
use wgui::gfx::pipeline::{WGfxPipeline, WPipelineCreateInfo};
|
use wgui::{
|
||||||
|
gfx::{
|
||||||
|
cmd::WGfxClearMode,
|
||||||
|
pipeline::{WGfxPipeline, WPipelineCreateInfo},
|
||||||
|
},
|
||||||
|
i18n::Translation,
|
||||||
|
parser::Fetchable,
|
||||||
|
widget::label::WidgetLabel,
|
||||||
|
};
|
||||||
use wlx_capture::frame::MouseMeta;
|
use wlx_capture::frame::MouseMeta;
|
||||||
use wlx_common::{
|
use wlx_common::{
|
||||||
overlays::{BackendAttrib, BackendAttribValue, StereoMode},
|
overlays::{BackendAttrib, BackendAttribValue, StereoMode},
|
||||||
@@ -21,6 +29,7 @@ use crate::{
|
|||||||
wayvr::{self, SurfaceBufWithImage},
|
wayvr::{self, SurfaceBufWithImage},
|
||||||
},
|
},
|
||||||
graphics::{ExtentExt, Vert2Uv, upload_quad_vertices},
|
graphics::{ExtentExt, Vert2Uv, upload_quad_vertices},
|
||||||
|
gui::panel::{GuiPanel, NewGuiPanelParams},
|
||||||
overlays::screen::capture::ScreenPipeline,
|
overlays::screen::capture::ScreenPipeline,
|
||||||
state::{self, AppState},
|
state::{self, AppState},
|
||||||
subsystem::{hid::WheelDelta, input::KeyboardFocus},
|
subsystem::{hid::WheelDelta, input::KeyboardFocus},
|
||||||
@@ -33,9 +42,12 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const BORDER_SIZE: u32 = 5;
|
||||||
|
const BAR_SIZE: u32 = 24;
|
||||||
|
|
||||||
pub fn create_wl_window_overlay(
|
pub fn create_wl_window_overlay(
|
||||||
name: Arc<str>,
|
name: Arc<str>,
|
||||||
app: &AppState,
|
app: &mut AppState,
|
||||||
window: wayvr::window::WindowHandle,
|
window: wayvr::window::WindowHandle,
|
||||||
) -> anyhow::Result<OverlayWindowConfig> {
|
) -> anyhow::Result<OverlayWindowConfig> {
|
||||||
Ok(OverlayWindowConfig {
|
Ok(OverlayWindowConfig {
|
||||||
@@ -71,12 +83,14 @@ pub struct WvrWindowBackend {
|
|||||||
mouse: Option<MouseMeta>,
|
mouse: Option<MouseMeta>,
|
||||||
stereo: Option<StereoMode>,
|
stereo: Option<StereoMode>,
|
||||||
cur_image: Option<Arc<ImageView>>,
|
cur_image: Option<Arc<ImageView>>,
|
||||||
|
panel: GuiPanel<()>,
|
||||||
|
mouse_transform: Affine2,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WvrWindowBackend {
|
impl WvrWindowBackend {
|
||||||
fn new(
|
fn new(
|
||||||
name: Arc<str>,
|
name: Arc<str>,
|
||||||
app: &AppState,
|
app: &mut AppState,
|
||||||
window: wayvr::window::WindowHandle,
|
window: wayvr::window::WindowHandle,
|
||||||
) -> anyhow::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
let popups_pipeline = app.gfx.create_pipeline(
|
let popups_pipeline = app.gfx.create_pipeline(
|
||||||
@@ -85,6 +99,28 @@ impl WvrWindowBackend {
|
|||||||
WPipelineCreateInfo::new(app.gfx.surface_format).use_blend(AttachmentBlend::default()),
|
WPipelineCreateInfo::new(app.gfx.surface_format).use_blend(AttachmentBlend::default()),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let mut panel = GuiPanel::new_from_template(
|
||||||
|
app,
|
||||||
|
"gui/decor.xml",
|
||||||
|
(),
|
||||||
|
NewGuiPanelParams {
|
||||||
|
resize_to_parent: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut title = panel
|
||||||
|
.parser_state
|
||||||
|
.fetch_widget_as::<WidgetLabel>(&panel.layout.state, "label_title")?;
|
||||||
|
title.set_text_simple(
|
||||||
|
&mut app.wgui_globals.get(),
|
||||||
|
Translation::from_raw_text(&*name),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
panel.update_layout()?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
name,
|
name,
|
||||||
pipeline: None,
|
pipeline: None,
|
||||||
@@ -101,25 +137,29 @@ impl WvrWindowBackend {
|
|||||||
None
|
None
|
||||||
},
|
},
|
||||||
cur_image: None,
|
cur_image: None,
|
||||||
|
panel,
|
||||||
|
mouse_transform: Affine2::ZERO,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OverlayBackend for WvrWindowBackend {
|
impl OverlayBackend for WvrWindowBackend {
|
||||||
fn init(&mut self, _app: &mut state::AppState) -> anyhow::Result<()> {
|
fn init(&mut self, app: &mut state::AppState) -> anyhow::Result<()> {
|
||||||
Ok(())
|
self.panel.init(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pause(&mut self, _app: &mut state::AppState) -> anyhow::Result<()> {
|
fn pause(&mut self, app: &mut state::AppState) -> anyhow::Result<()> {
|
||||||
Ok(())
|
self.panel.pause(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resume(&mut self, _app: &mut state::AppState) -> anyhow::Result<()> {
|
fn resume(&mut self, app: &mut state::AppState) -> anyhow::Result<()> {
|
||||||
self.just_resumed = true;
|
self.just_resumed = true;
|
||||||
Ok(())
|
self.panel.resume(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_render(&mut self, app: &mut AppState) -> anyhow::Result<ShouldRender> {
|
fn should_render(&mut self, app: &mut AppState) -> anyhow::Result<ShouldRender> {
|
||||||
|
let should_render_panel = self.panel.should_render(app)?;
|
||||||
|
|
||||||
let Some(toplevel) = app
|
let Some(toplevel) = app
|
||||||
.wvr_server
|
.wvr_server
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -162,22 +202,37 @@ impl OverlayBackend for WvrWindowBackend {
|
|||||||
let mut meta = FrameMeta {
|
let mut meta = FrameMeta {
|
||||||
extent: surf.image.image().extent(),
|
extent: surf.image.image().extent(),
|
||||||
format: surf.image.format(),
|
format: surf.image.format(),
|
||||||
|
clear: WGfxClearMode::Clear([0.0, 0.0, 0.0, 0.0]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(pipeline) = self.pipeline.as_mut() {
|
if let Some(pipeline) = self.pipeline.as_mut() {
|
||||||
|
let inner_extent = meta.extent;
|
||||||
|
|
||||||
|
meta.extent[0] += BORDER_SIZE * 2;
|
||||||
|
meta.extent[1] += BORDER_SIZE * 2 + BAR_SIZE;
|
||||||
meta.extent[2] = pipeline.get_depth();
|
meta.extent[2] = pipeline.get_depth();
|
||||||
if self
|
if self
|
||||||
.meta
|
.meta
|
||||||
.is_some_and(|old| old.extent[..2] != meta.extent[..2])
|
.is_some_and(|old| old.extent[..2] != meta.extent[..2])
|
||||||
{
|
{
|
||||||
pipeline.set_extent(app, [meta.extent[0] as _, meta.extent[1] as _])?;
|
pipeline.set_extent(
|
||||||
|
app,
|
||||||
|
[inner_extent[0] as _, inner_extent[1] as _],
|
||||||
|
[BORDER_SIZE as _, (BAR_SIZE + BORDER_SIZE) as _],
|
||||||
|
)?;
|
||||||
self.interaction_transform =
|
self.interaction_transform =
|
||||||
Some(ui_transform(meta.extent.extent_u32arr()));
|
Some(ui_transform(meta.extent.extent_u32arr()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let pipeline =
|
let pipeline = ScreenPipeline::new(
|
||||||
ScreenPipeline::new(&meta, app, self.stereo.unwrap_or(StereoMode::None))?;
|
&meta,
|
||||||
|
app,
|
||||||
|
self.stereo.unwrap_or(StereoMode::None),
|
||||||
|
[BORDER_SIZE as _, (BAR_SIZE + BORDER_SIZE) as _],
|
||||||
|
)?;
|
||||||
|
meta.extent[0] += BORDER_SIZE * 2;
|
||||||
|
meta.extent[1] += BORDER_SIZE * 2 + BAR_SIZE;
|
||||||
meta.extent[2] = pipeline.get_depth();
|
meta.extent[2] = pipeline.get_depth();
|
||||||
self.pipeline = Some(pipeline);
|
self.pipeline = Some(pipeline);
|
||||||
self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr()));
|
self.interaction_transform = Some(ui_transform(meta.extent.extent_u32arr()));
|
||||||
@@ -215,7 +270,7 @@ impl OverlayBackend for WvrWindowBackend {
|
|||||||
} else if dirty {
|
} else if dirty {
|
||||||
Ok(ShouldRender::Should)
|
Ok(ShouldRender::Should)
|
||||||
} else {
|
} else {
|
||||||
Ok(ShouldRender::Can)
|
Ok(should_render_panel)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log::trace!("{}: no buffer for wl_surface", self.name);
|
log::trace!("{}: no buffer for wl_surface", self.name);
|
||||||
@@ -229,6 +284,8 @@ impl OverlayBackend for WvrWindowBackend {
|
|||||||
app: &mut state::AppState,
|
app: &mut state::AppState,
|
||||||
rdr: &mut RenderResources,
|
rdr: &mut RenderResources,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
self.panel.render(app, rdr)?;
|
||||||
|
|
||||||
let image = self.cur_image.as_ref().unwrap().clone();
|
let image = self.cur_image.as_ref().unwrap().clone();
|
||||||
|
|
||||||
self.pipeline
|
self.pipeline
|
||||||
@@ -264,6 +321,7 @@ impl OverlayBackend for WvrWindowBackend {
|
|||||||
|
|
||||||
let pass = self.popups_pipeline.create_pass(
|
let pass = self.popups_pipeline.create_pass(
|
||||||
extentf,
|
extentf,
|
||||||
|
[BORDER_SIZE as _, (BAR_SIZE + BORDER_SIZE) as _],
|
||||||
buf_vert,
|
buf_vert,
|
||||||
0..4,
|
0..4,
|
||||||
0..1,
|
0..1,
|
||||||
@@ -308,8 +366,8 @@ impl OverlayBackend for WvrWindowBackend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_left(&mut self, _app: &mut state::AppState, _pointer: usize) {
|
fn on_left(&mut self, app: &mut state::AppState, pointer: usize) {
|
||||||
// Ignore event
|
self.panel.on_left(app, pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_pointer(&mut self, app: &mut state::AppState, hit: &input::PointerHit, pressed: bool) {
|
fn on_pointer(&mut self, app: &mut state::AppState, hit: &input::PointerHit, pressed: bool) {
|
||||||
|
|||||||
Reference in New Issue
Block a user