Add Context::set_debug_on_hover and egui::trace!(ui)
This commit is contained in:
parent
8623909d82
commit
3b807e1ad6
13 changed files with 117 additions and 41 deletions
|
@ -17,6 +17,7 @@ NOTE: [`eframe`](eframe/CHANGELOG.md), [`egui_web`](egui_web/CHANGELOG.md) and [
|
||||||
* Add support for [cint](https://crates.io/crates/cint) under `cint` feature.
|
* Add support for [cint](https://crates.io/crates/cint) under `cint` feature.
|
||||||
* Add features `extra_asserts` and `extra_debug_asserts` to enable additional checks.
|
* Add features `extra_asserts` and `extra_debug_asserts` to enable additional checks.
|
||||||
* `TextEdit` now supports edits on a generic buffer using `TextBuffer`.
|
* `TextEdit` now supports edits on a generic buffer using `TextBuffer`.
|
||||||
|
* Add `Context::set_debug_on_hover` and `egui::trace!(ui)`
|
||||||
|
|
||||||
### Changed 🔧
|
### Changed 🔧
|
||||||
* Plot: Changed `Curve` to `Line`.
|
* Plot: Changed `Curve` to `Line`.
|
||||||
|
|
|
@ -726,6 +726,20 @@ impl Context {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Wether or not to debug widget layout on hover.
|
||||||
|
pub fn debug_on_hover(&self) -> bool {
|
||||||
|
self.memory().options.style.debug.debug_on_hover
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turn on/off wether or not to debug widget layout on hover.
|
||||||
|
pub fn set_debug_on_hover(&self, debug_on_hover: bool) {
|
||||||
|
let mut style = (*self.memory().options.style).clone();
|
||||||
|
style.debug.debug_on_hover = debug_on_hover;
|
||||||
|
self.set_style(style);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ## Animation
|
/// ## Animation
|
||||||
|
@ -780,12 +794,14 @@ impl Context {
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
let mut tessellation_options = self.memory().options.tessellation_options;
|
let mut tessellation_options = self.memory().options.tessellation_options;
|
||||||
tessellation_options.ui(ui);
|
tessellation_options.ui(ui);
|
||||||
|
ui.vertical_centered(|ui| reset_button(ui, &mut tessellation_options));
|
||||||
self.memory().options.tessellation_options = tessellation_options;
|
self.memory().options.tessellation_options = tessellation_options;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inspection_ui(&self, ui: &mut Ui) {
|
pub fn inspection_ui(&self, ui: &mut Ui) {
|
||||||
use crate::containers::*;
|
use crate::containers::*;
|
||||||
|
crate::trace!(ui);
|
||||||
|
|
||||||
ui.label(format!("Is using pointer: {}", self.is_using_pointer()))
|
ui.label(format!("Is using pointer: {}", self.is_using_pointer()))
|
||||||
.on_hover_text(
|
.on_hover_text(
|
||||||
|
|
|
@ -731,14 +731,13 @@ impl Layout {
|
||||||
/// ## Debug stuff
|
/// ## Debug stuff
|
||||||
impl Layout {
|
impl Layout {
|
||||||
/// Shows where the next widget is going to be placed
|
/// Shows where the next widget is going to be placed
|
||||||
pub(crate) fn debug_paint_cursor(
|
pub(crate) fn paint_text_at_cursor(
|
||||||
&self,
|
&self,
|
||||||
|
painter: &crate::Painter,
|
||||||
region: &Region,
|
region: &Region,
|
||||||
stroke: epaint::Stroke,
|
stroke: epaint::Stroke,
|
||||||
painter: &crate::Painter,
|
text: impl ToString,
|
||||||
) {
|
) {
|
||||||
use epaint::*;
|
|
||||||
|
|
||||||
let cursor = region.cursor;
|
let cursor = region.cursor;
|
||||||
let next_pos = self.next_widget_position(region);
|
let next_pos = self.next_widget_position(region);
|
||||||
|
|
||||||
|
@ -769,12 +768,6 @@ impl Layout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
painter.text(
|
painter.debug_text(next_pos, align, stroke.color, text);
|
||||||
next_pos,
|
|
||||||
align,
|
|
||||||
"cursor",
|
|
||||||
TextStyle::Monospace,
|
|
||||||
Color32::WHITE,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -416,6 +416,31 @@ macro_rules! github_link_file {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Show debug info on hover when [`Context::set_debug_on_hover`] has been turned on.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # let ui = &mut egui::Ui::__test();
|
||||||
|
/// // Turn on tracing of widgets
|
||||||
|
/// ui.ctx().set_debug_on_hover(true);
|
||||||
|
///
|
||||||
|
/// /// Show [`std::file`], [`std::line`] and argument on hover
|
||||||
|
/// egui::trace!(ui, "MyWindow");
|
||||||
|
///
|
||||||
|
/// /// Show [`std::file`] and [`std::line`] on hover
|
||||||
|
/// egui::trace!(ui);
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! trace {
|
||||||
|
($ui:expr) => {{
|
||||||
|
$ui.trace_location(format!("{}:{}", file!(), line!()))
|
||||||
|
}};
|
||||||
|
($ui:expr, $label:expr) => {{
|
||||||
|
$ui.trace_location(format!("{} - {}:{}", $label, file!(), line!()))
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// An assert that is only active when `egui` is compiled with the `egui_assert` feature
|
/// An assert that is only active when `egui` is compiled with the `egui_assert` feature
|
||||||
/// or with the `debug_egui_assert` feature in debug builds.
|
/// or with the `debug_egui_assert` feature in debug builds.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
|
|
@ -83,6 +83,7 @@ pub struct Options {
|
||||||
/// The default style for new `Ui`:s.
|
/// The default style for new `Ui`:s.
|
||||||
#[cfg_attr(feature = "persistence", serde(skip))]
|
#[cfg_attr(feature = "persistence", serde(skip))]
|
||||||
pub(crate) style: std::sync::Arc<Style>,
|
pub(crate) style: std::sync::Arc<Style>,
|
||||||
|
|
||||||
/// Controls the tessellator.
|
/// Controls the tessellator.
|
||||||
pub(crate) tessellation_options: epaint::TessellationOptions,
|
pub(crate) tessellation_options: epaint::TessellationOptions,
|
||||||
|
|
||||||
|
|
|
@ -187,20 +187,31 @@ impl Painter {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error(&self, pos: Pos2, text: impl std::fmt::Display) -> Rect {
|
pub fn error(&self, pos: Pos2, text: impl std::fmt::Display) -> Rect {
|
||||||
let galley = self.fonts().layout_multiline(
|
self.debug_text(pos, Align2::LEFT_TOP, Color32::RED, format!("🔥 {}", text))
|
||||||
TextStyle::Monospace,
|
}
|
||||||
format!("🔥 {}", text),
|
|
||||||
f32::INFINITY,
|
/// text with a background
|
||||||
);
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
let rect = Rect::from_min_size(pos, galley.size);
|
pub fn debug_text(
|
||||||
|
&self,
|
||||||
|
pos: Pos2,
|
||||||
|
anchor: Align2,
|
||||||
|
color: Color32,
|
||||||
|
text: impl ToString,
|
||||||
|
) -> Rect {
|
||||||
|
let galley = self
|
||||||
|
.fonts()
|
||||||
|
.layout_no_wrap(TextStyle::Monospace, text.to_string());
|
||||||
|
let rect = anchor.anchor_rect(Rect::from_min_size(pos, galley.size));
|
||||||
let frame_rect = rect.expand(2.0);
|
let frame_rect = rect.expand(2.0);
|
||||||
self.add(Shape::Rect {
|
self.add(Shape::Rect {
|
||||||
rect: frame_rect,
|
rect: frame_rect,
|
||||||
corner_radius: 0.0,
|
corner_radius: 0.0,
|
||||||
fill: Color32::from_black_alpha(240),
|
fill: Color32::from_black_alpha(240),
|
||||||
stroke: Stroke::new(1.0, Color32::RED),
|
// stroke: Stroke::new(1.0, color),
|
||||||
|
stroke: Default::default(),
|
||||||
});
|
});
|
||||||
self.galley(rect.min, galley, Color32::RED);
|
self.galley(rect.min, galley, color);
|
||||||
frame_rect
|
frame_rect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,15 +248,17 @@ impl Placer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Placer {
|
impl Placer {
|
||||||
pub(crate) fn debug_paint_cursor(&self, painter: &crate::Painter) {
|
pub(crate) fn debug_paint_cursor(&self, painter: &crate::Painter, text: impl ToString) {
|
||||||
let color = Color32::GREEN.linear_multiply(0.5);
|
let stroke = Stroke::new(1.0, Color32::DEBUG_COLOR);
|
||||||
let stroke = Stroke::new(2.0, color);
|
|
||||||
|
|
||||||
if let Some(grid) = &self.grid {
|
if let Some(grid) = &self.grid {
|
||||||
painter.rect_stroke(grid.next_cell(self.cursor(), Vec2::splat(0.0)), 1.0, stroke)
|
let rect = grid.next_cell(self.cursor(), Vec2::splat(0.0));
|
||||||
|
painter.rect_stroke(rect, 1.0, stroke);
|
||||||
|
let align = Align2::CENTER_CENTER;
|
||||||
|
painter.debug_text(align.pos_in_rect(&rect), align, stroke.color, text);
|
||||||
} else {
|
} else {
|
||||||
self.layout
|
self.layout
|
||||||
.debug_paint_cursor(&self.region, stroke, painter)
|
.paint_text_at_cursor(painter, &self.region, stroke, text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -313,7 +313,7 @@ impl WidgetVisuals {
|
||||||
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub struct DebugOptions {
|
pub struct DebugOptions {
|
||||||
/// However over widgets to see their rectangles
|
/// However over widgets to see their rectangles
|
||||||
pub show_widgets: bool,
|
pub debug_on_hover: bool,
|
||||||
/// Show which widgets make their parent wider
|
/// Show which widgets make their parent wider
|
||||||
pub show_expand_width: bool,
|
pub show_expand_width: bool,
|
||||||
/// Show which widgets make their parent higher
|
/// Show which widgets make their parent higher
|
||||||
|
@ -548,7 +548,7 @@ impl Style {
|
||||||
ui.collapsing("📏 Spacing", |ui| spacing.ui(ui));
|
ui.collapsing("📏 Spacing", |ui| spacing.ui(ui));
|
||||||
ui.collapsing("☝ Interaction", |ui| interaction.ui(ui));
|
ui.collapsing("☝ Interaction", |ui| interaction.ui(ui));
|
||||||
ui.collapsing("🎨 Visuals", |ui| visuals.ui(ui));
|
ui.collapsing("🎨 Visuals", |ui| visuals.ui(ui));
|
||||||
ui.collapsing("⁉ Debug", |ui| debug.ui(ui));
|
ui.collapsing("🐛 Debug", |ui| debug.ui(ui));
|
||||||
|
|
||||||
ui.vertical_centered(|ui| reset_button(ui, self));
|
ui.vertical_centered(|ui| reset_button(ui, self));
|
||||||
}
|
}
|
||||||
|
@ -746,13 +746,13 @@ impl Visuals {
|
||||||
impl DebugOptions {
|
impl DebugOptions {
|
||||||
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
||||||
let Self {
|
let Self {
|
||||||
show_widgets: debug_widgets,
|
debug_on_hover,
|
||||||
show_expand_width: debug_expand_width,
|
show_expand_width: debug_expand_width,
|
||||||
show_expand_height: debug_expand_height,
|
show_expand_height: debug_expand_height,
|
||||||
show_resize: debug_resize,
|
show_resize: debug_resize,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
ui.checkbox(debug_widgets, "Show widget bounds on hover");
|
ui.checkbox(debug_on_hover, "Show debug info on hover");
|
||||||
ui.checkbox(
|
ui.checkbox(
|
||||||
debug_expand_width,
|
debug_expand_width,
|
||||||
"Show which widgets make their parent wider",
|
"Show which widgets make their parent wider",
|
||||||
|
|
|
@ -601,10 +601,10 @@ impl Ui {
|
||||||
|
|
||||||
let rect = self.allocate_space_impl(desired_size);
|
let rect = self.allocate_space_impl(desired_size);
|
||||||
|
|
||||||
if self.style().debug.show_widgets && self.rect_contains_pointer(rect) {
|
if self.style().debug.debug_on_hover && self.rect_contains_pointer(rect) {
|
||||||
let painter = self.ctx().debug_painter();
|
let painter = self.ctx().debug_painter();
|
||||||
painter.rect_stroke(rect, 4.0, (1.0, Color32::LIGHT_BLUE));
|
painter.rect_stroke(rect, 4.0, (1.0, Color32::LIGHT_BLUE));
|
||||||
self.placer.debug_paint_cursor(&painter);
|
self.placer.debug_paint_cursor(&painter, "next");
|
||||||
}
|
}
|
||||||
|
|
||||||
let debug_expand_width = self.style().debug.show_expand_width;
|
let debug_expand_width = self.style().debug.show_expand_width;
|
||||||
|
@ -666,10 +666,10 @@ impl Ui {
|
||||||
let item_spacing = self.spacing().item_spacing;
|
let item_spacing = self.spacing().item_spacing;
|
||||||
self.placer.advance_after_rects(rect, rect, item_spacing);
|
self.placer.advance_after_rects(rect, rect, item_spacing);
|
||||||
|
|
||||||
if self.style().debug.show_widgets && self.rect_contains_pointer(rect) {
|
if self.style().debug.debug_on_hover && self.rect_contains_pointer(rect) {
|
||||||
let painter = self.ctx().debug_painter();
|
let painter = self.ctx().debug_painter();
|
||||||
painter.rect_stroke(rect, 4.0, (1.0, Color32::LIGHT_BLUE));
|
painter.rect_stroke(rect, 4.0, (1.0, Color32::LIGHT_BLUE));
|
||||||
self.placer.debug_paint_cursor(&painter);
|
self.placer.debug_paint_cursor(&painter, "next");
|
||||||
}
|
}
|
||||||
|
|
||||||
let id = Id::new(self.next_auto_id_source);
|
let id = Id::new(self.next_auto_id_source);
|
||||||
|
@ -735,11 +735,11 @@ impl Ui {
|
||||||
self.placer
|
self.placer
|
||||||
.advance_after_rects(final_child_rect, final_child_rect, item_spacing);
|
.advance_after_rects(final_child_rect, final_child_rect, item_spacing);
|
||||||
|
|
||||||
if self.style().debug.show_widgets && self.rect_contains_pointer(final_child_rect) {
|
if self.style().debug.debug_on_hover && self.rect_contains_pointer(final_child_rect) {
|
||||||
let painter = self.ctx().debug_painter();
|
let painter = self.ctx().debug_painter();
|
||||||
painter.rect_stroke(frame_rect, 4.0, (1.0, Color32::LIGHT_BLUE));
|
painter.rect_stroke(frame_rect, 4.0, (1.0, Color32::LIGHT_BLUE));
|
||||||
painter.rect_stroke(final_child_rect, 4.0, (1.0, Color32::LIGHT_BLUE));
|
painter.rect_stroke(final_child_rect, 4.0, (1.0, Color32::LIGHT_BLUE));
|
||||||
self.placer.debug_paint_cursor(&painter);
|
self.placer.debug_paint_cursor(&painter, "next");
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = self.interact(final_child_rect, child_ui.id, Sense::hover());
|
let response = self.interact(final_child_rect, child_ui.id, Sense::hover());
|
||||||
|
@ -1523,10 +1523,10 @@ impl Ui {
|
||||||
let item_spacing = self.spacing().item_spacing;
|
let item_spacing = self.spacing().item_spacing;
|
||||||
self.placer.advance_after_rects(rect, rect, item_spacing);
|
self.placer.advance_after_rects(rect, rect, item_spacing);
|
||||||
|
|
||||||
if self.style().debug.show_widgets && self.rect_contains_pointer(rect) {
|
if self.style().debug.debug_on_hover && self.rect_contains_pointer(rect) {
|
||||||
let painter = self.ctx().debug_painter();
|
let painter = self.ctx().debug_painter();
|
||||||
painter.rect_stroke(rect, 4.0, (1.0, Color32::LIGHT_BLUE));
|
painter.rect_stroke(rect, 4.0, (1.0, Color32::LIGHT_BLUE));
|
||||||
self.placer.debug_paint_cursor(&painter);
|
self.placer.debug_paint_cursor(&painter, "next");
|
||||||
}
|
}
|
||||||
|
|
||||||
InnerResponse::new(inner, self.interact(rect, child_ui.id, Sense::hover()))
|
InnerResponse::new(inner, self.interact(rect, child_ui.id, Sense::hover()))
|
||||||
|
@ -1628,6 +1628,16 @@ impl Ui {
|
||||||
impl Ui {
|
impl Ui {
|
||||||
/// Shows where the next widget is going to be placed
|
/// Shows where the next widget is going to be placed
|
||||||
pub fn debug_paint_cursor(&self) {
|
pub fn debug_paint_cursor(&self) {
|
||||||
self.placer.debug_paint_cursor(&self.painter);
|
self.placer.debug_paint_cursor(&self.painter, "next");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shows the given text where the next widget is to be placed
|
||||||
|
/// if when [`Context::set_debug_on_hover`] has been turned on and the mouse is hovering the Ui.
|
||||||
|
pub fn trace_location(&self, text: impl ToString) {
|
||||||
|
let rect = self.max_rect_finite();
|
||||||
|
if self.style().debug.debug_on_hover && self.rect_contains_pointer(rect) {
|
||||||
|
self.placer
|
||||||
|
.debug_paint_cursor(&self.ctx().debug_painter(), text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,6 +156,7 @@ impl DemoWindows {
|
||||||
.min_width(150.0)
|
.min_width(150.0)
|
||||||
.default_width(190.0)
|
.default_width(190.0)
|
||||||
.show(ctx, |ui| {
|
.show(ctx, |ui| {
|
||||||
|
egui::trace!(ui);
|
||||||
ui.vertical_centered(|ui| {
|
ui.vertical_centered(|ui| {
|
||||||
ui.heading("✒ egui demos");
|
ui.heading("✒ egui demos");
|
||||||
});
|
});
|
||||||
|
@ -296,6 +297,7 @@ impl EguiWindows {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_menu_bar(ui: &mut Ui) {
|
fn show_menu_bar(ui: &mut Ui) {
|
||||||
|
trace!(ui);
|
||||||
use egui::*;
|
use egui::*;
|
||||||
|
|
||||||
menu::bar(ui, |ui| {
|
menu::bar(ui, |ui| {
|
||||||
|
|
|
@ -75,6 +75,7 @@ impl epi::App for WrapApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
egui::TopBottomPanel::top("wrap_app_top_bar").show(ctx, |ui| {
|
egui::TopBottomPanel::top("wrap_app_top_bar").show(ctx, |ui| {
|
||||||
|
egui::trace!(ui);
|
||||||
self.bar_contents(ui, frame);
|
self.bar_contents(ui, frame);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -262,6 +263,7 @@ impl BackendPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut epi::Frame<'_>) {
|
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut epi::Frame<'_>) {
|
||||||
|
egui::trace!(ui);
|
||||||
ui.vertical_centered(|ui| {
|
ui.vertical_centered(|ui| {
|
||||||
ui.heading("💻 Backend");
|
ui.heading("💻 Backend");
|
||||||
});
|
});
|
||||||
|
@ -327,9 +329,20 @@ impl BackendPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut screen_reader = ui.ctx().memory().options.screen_reader;
|
{
|
||||||
ui.checkbox(&mut screen_reader, "Screen reader").on_hover_text("Experimental feature: checking this will turn on the screen reader on supported platforms");
|
let mut debug_on_hover = ui.ctx().debug_on_hover();
|
||||||
ui.ctx().memory().options.screen_reader = screen_reader;
|
ui.checkbox(&mut debug_on_hover, "🐛 Debug on hover")
|
||||||
|
.on_hover_text("Show structure of the ui when you hover with the mouse");
|
||||||
|
ui.ctx().set_debug_on_hover(debug_on_hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.separator();
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut screen_reader = ui.ctx().memory().options.screen_reader;
|
||||||
|
ui.checkbox(&mut screen_reader, "Screen reader").on_hover_text("Experimental feature: checking this will turn on the screen reader on supported platforms");
|
||||||
|
ui.ctx().memory().options.screen_reader = screen_reader;
|
||||||
|
}
|
||||||
|
|
||||||
ui.collapsing("Output events", |ui| {
|
ui.collapsing("Output events", |ui| {
|
||||||
ui.set_max_width(450.0);
|
ui.set_max_width(450.0);
|
||||||
|
|
|
@ -49,6 +49,8 @@ impl Color32 {
|
||||||
pub const LIGHT_BLUE: Color32 = Color32::from_rgb(140, 160, 255);
|
pub const LIGHT_BLUE: Color32 = Color32::from_rgb(140, 160, 255);
|
||||||
pub const GOLD: Color32 = Color32::from_rgb(255, 215, 0);
|
pub const GOLD: Color32 = Color32::from_rgb(255, 215, 0);
|
||||||
|
|
||||||
|
pub const DEBUG_COLOR: Color32 = Color32::from_rgba_premultiplied(0, 200, 0, 128);
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn from_rgb(r: u8, g: u8, b: u8) -> Self {
|
pub const fn from_rgb(r: u8, g: u8, b: u8) -> Self {
|
||||||
Self([r, g, b, 255])
|
Self([r, g, b, 255])
|
||||||
|
|
|
@ -229,7 +229,7 @@ pub enum PathType {
|
||||||
use self::PathType::{Closed, Open};
|
use self::PathType::{Closed, Open};
|
||||||
|
|
||||||
/// Tessellation quality options
|
/// Tessellation quality options
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
||||||
#[cfg_attr(feature = "persistence", serde(default))]
|
#[cfg_attr(feature = "persistence", serde(default))]
|
||||||
pub struct TessellationOptions {
|
pub struct TessellationOptions {
|
||||||
|
|
Loading…
Reference in a new issue