mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
ability to specify custom shaders for widgets
- renderer does not support it yet (should support soon)
This commit is contained in:
@@ -34,6 +34,7 @@ use crate::{
|
||||
};
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use fyrox_core::math::round_to_step;
|
||||
use fyrox_resource::untyped::UntypedResource;
|
||||
use fyrox_texture::TextureResource;
|
||||
use std::ops::Range;
|
||||
|
||||
@@ -131,6 +132,7 @@ pub struct Command {
|
||||
pub brush: Brush,
|
||||
pub texture: CommandTexture,
|
||||
pub triangles: Range<usize>,
|
||||
pub shader: Option<UntypedResource>,
|
||||
pub opacity: f32,
|
||||
/// A set of triangles that defines clipping region.
|
||||
pub clipping_geometry: Option<ClippingGeometry>,
|
||||
@@ -784,6 +786,7 @@ pub struct DrawingContext {
|
||||
command_buffer: Vec<Command>,
|
||||
pub transform_stack: TransformStack,
|
||||
opacity_stack: Vec<f32>,
|
||||
shader_stack: Vec<UntypedResource>,
|
||||
triangles_to_commit: usize,
|
||||
pub style: StyleResource,
|
||||
/// Amount of time (in seconds) that passed from creation of the engine. Keep in mind, that
|
||||
@@ -835,6 +838,7 @@ impl DrawingContext {
|
||||
transform_stack: Default::default(),
|
||||
style,
|
||||
elapsed_time: 0.0,
|
||||
shader_stack: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -844,6 +848,7 @@ impl DrawingContext {
|
||||
self.triangle_buffer.clear();
|
||||
self.command_buffer.clear();
|
||||
self.opacity_stack.clear();
|
||||
self.shader_stack.clear();
|
||||
self.opacity_stack.push(1.0);
|
||||
self.triangles_to_commit = 0;
|
||||
}
|
||||
@@ -871,6 +876,14 @@ impl DrawingContext {
|
||||
self.opacity_stack.pop().unwrap();
|
||||
}
|
||||
|
||||
pub fn push_shader(&mut self, shader: UntypedResource) {
|
||||
self.shader_stack.push(shader)
|
||||
}
|
||||
|
||||
pub fn pop_shader(&mut self) {
|
||||
self.shader_stack.pop().unwrap();
|
||||
}
|
||||
|
||||
pub fn triangle_points(
|
||||
&self,
|
||||
triangle: &TriangleDefinition,
|
||||
@@ -925,12 +938,14 @@ impl DrawingContext {
|
||||
let bounds = self.bounds_of(triangles.clone());
|
||||
|
||||
let opacity = *self.opacity_stack.last().unwrap();
|
||||
let shader = self.shader_stack.last().cloned();
|
||||
self.command_buffer.push(Command {
|
||||
clip_bounds,
|
||||
bounds,
|
||||
brush,
|
||||
texture,
|
||||
triangles,
|
||||
shader,
|
||||
opacity,
|
||||
clipping_geometry,
|
||||
});
|
||||
|
||||
@@ -976,6 +976,10 @@ fn draw_node(
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(shader) = node.shader.as_ref() {
|
||||
drawing_context.push_shader(shader.clone());
|
||||
}
|
||||
|
||||
let pushed = if !is_node_enabled(nodes, node_handle) {
|
||||
drawing_context.push_opacity(0.4);
|
||||
true
|
||||
@@ -1018,6 +1022,10 @@ fn draw_node(
|
||||
|
||||
drawing_context.transform_stack.pop();
|
||||
|
||||
if node.shader.as_ref().is_some() {
|
||||
drawing_context.pop_shader();
|
||||
}
|
||||
|
||||
if pushed {
|
||||
drawing_context.pop_opacity();
|
||||
}
|
||||
|
||||
+18
-15
@@ -23,8 +23,6 @@
|
||||
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use crate::style::resource::StyleResource;
|
||||
use crate::style::StyledProperty;
|
||||
use crate::{
|
||||
brush::Brush,
|
||||
core::{
|
||||
@@ -39,13 +37,15 @@ use crate::{
|
||||
core::{parking_lot::Mutex, variable::InheritableVariable},
|
||||
define_constructor,
|
||||
message::{CursorIcon, Force, KeyCode, MessageDirection, UiMessage},
|
||||
style::resource::StyleResourceExt,
|
||||
style::Style,
|
||||
style::{
|
||||
resource::{StyleResource, StyleResourceExt},
|
||||
Style, StyledProperty,
|
||||
},
|
||||
BuildContext, HorizontalAlignment, LayoutEvent, MouseButton, MouseState, RcUiNodeHandle,
|
||||
Thickness, UiNode, UserInterface, VerticalAlignment,
|
||||
};
|
||||
use fyrox_graph::BaseSceneGraph;
|
||||
use fyrox_resource::Resource;
|
||||
use fyrox_resource::{untyped::UntypedResource, Resource};
|
||||
use std::{
|
||||
any::Any,
|
||||
cell::{Cell, RefCell},
|
||||
@@ -749,6 +749,7 @@ impl WidgetMessage {
|
||||
/// for layout information, basic visual appearance, visibility options, parent-child information. It does almost nothing
|
||||
/// on its own, instead, the user interface modifies its state accordingly.
|
||||
#[derive(Default, Debug, Clone, Reflect, Visit)]
|
||||
#[visit(optional)]
|
||||
pub struct Widget {
|
||||
/// Self handle of the widget. It is valid **only**, if the widget is added to the user interface, in other
|
||||
/// cases it will most likely be [`Handle::NONE`].
|
||||
@@ -836,12 +837,10 @@ pub struct Widget {
|
||||
/// Optional opacity of the widget. It should be in `[0.0..1.0]` range, where 0.0 - fully transparent, 1.0 - fully opaque.
|
||||
pub opacity: InheritableVariable<Option<f32>>,
|
||||
/// An optional ref counted handle to a tooltip used by the widget.
|
||||
#[visit(optional)]
|
||||
pub tooltip: Option<RcUiNodeHandle>,
|
||||
/// Maximum available time to show the tooltip after the cursor was moved away from the widget.
|
||||
pub tooltip_time: f32,
|
||||
/// An optional ref counted handle to a context menu used by the widget.
|
||||
#[visit(optional)]
|
||||
pub context_menu: Option<RcUiNodeHandle>,
|
||||
/// A flag, that defines whether the widget should be clipped by the parent bounds or not.
|
||||
pub clip_to_bounds: InheritableVariable<bool>,
|
||||
@@ -866,23 +865,18 @@ pub struct Widget {
|
||||
pub handle_os_events: bool,
|
||||
/// Defines the order in which this widget will get keyboard focus when Tab key is pressed.
|
||||
/// If set to [`None`], Tab key won't do anything on such widget. Default is [`None`].
|
||||
#[visit(optional)]
|
||||
pub tab_index: InheritableVariable<Option<usize>>,
|
||||
/// A flag, that defines whether the Tab key navigation is enabled or disabled for this widget.
|
||||
#[visit(optional)]
|
||||
pub tab_stop: InheritableVariable<bool>,
|
||||
/// A flag, that defines whether the widget will be update or not. Basically, it defines whether [crate::Control::update]
|
||||
/// is called or not.
|
||||
#[visit(optional)]
|
||||
pub need_update: bool,
|
||||
/// Enables (`false`) or disables (`true`) layout rounding.
|
||||
#[visit(optional)]
|
||||
pub ignore_layout_rounding: bool,
|
||||
/// A flag, that indicates that the widget accepts user input. It could be used to determine, if
|
||||
/// a user can interact with the widget using keyboard. It is also used for automatic assignment
|
||||
/// of the tab index. Keep in mind, that this flag is only a marker and does not do anything else
|
||||
/// on its own. Default value is `false`.
|
||||
#[visit(optional)]
|
||||
pub accepts_input: bool,
|
||||
/// Internal sender for layout events.
|
||||
#[reflect(hidden)]
|
||||
@@ -893,16 +887,15 @@ pub struct Widget {
|
||||
/// A flag, that indicates whether this widget is a root widget of a hierarchy of widgets
|
||||
/// instantiated from a resource.
|
||||
#[reflect(hidden)]
|
||||
#[visit(optional)]
|
||||
pub is_resource_instance_root: bool,
|
||||
/// A resource from which this widget was instantiated from, can work in pair with `original`
|
||||
/// handle to get a corresponding widget from resource.
|
||||
#[reflect(read_only)]
|
||||
#[visit(optional)]
|
||||
pub resource: Option<Resource<UserInterface>>,
|
||||
/// A shader, that should be used when rendering the widget.
|
||||
pub shader: InheritableVariable<Option<UntypedResource>>,
|
||||
/// Handle to a widget in a user interface resource from which this node was instantiated from.
|
||||
#[reflect(hidden)]
|
||||
#[visit(optional)]
|
||||
pub original_handle_in_resource: Handle<UiNode>,
|
||||
//
|
||||
// Layout. Interior mutability is a must here because layout performed in a series of recursive calls.
|
||||
@@ -1901,6 +1894,8 @@ pub struct WidgetBuilder {
|
||||
pub tab_stop: bool,
|
||||
/// A flag, that indicates that the widget accepts user input.
|
||||
pub accepts_input: bool,
|
||||
/// A shader that will be used for rendering.
|
||||
pub shader: Option<UntypedResource>,
|
||||
}
|
||||
|
||||
impl Default for WidgetBuilder {
|
||||
@@ -1950,6 +1945,7 @@ impl WidgetBuilder {
|
||||
tab_index: None,
|
||||
tab_stop: false,
|
||||
accepts_input: false,
|
||||
shader: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2212,6 +2208,12 @@ impl WidgetBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a shader which will be used for rendering of this widget.
|
||||
pub fn with_shader(mut self, shader: UntypedResource) -> Self {
|
||||
self.shader = Some(shader);
|
||||
self
|
||||
}
|
||||
|
||||
/// Finishes building of the base widget.
|
||||
pub fn build(self, ctx: &BuildContext) -> Widget {
|
||||
Widget {
|
||||
@@ -2280,6 +2282,7 @@ impl WidgetBuilder {
|
||||
id: self.id,
|
||||
is_resource_instance_root: false,
|
||||
resource: None,
|
||||
shader: self.shader.into(),
|
||||
original_handle_in_resource: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user