mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 06:40:06 -04:00
hierarchy & example
This commit is contained in:
@@ -4315,6 +4315,14 @@ dependencies = [
|
|||||||
"float-cmp",
|
"float-cmp",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "styling_engine"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"eframe",
|
||||||
|
"env_logger",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.6.1"
|
version = "2.6.1"
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
//!
|
//!
|
||||||
//! Add your [`crate::Window`]:s after any top-level panels.
|
//! Add your [`crate::Window`]:s after any top-level panels.
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use emath::{GuiRounding as _, Pos2};
|
use emath::{GuiRounding as _, Pos2};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -1027,10 +1029,12 @@ impl CentralPanel {
|
|||||||
.max_rect(panel_rect)
|
.max_rect(panel_rect)
|
||||||
.layout(Layout::top_down(Align::Min)),
|
.layout(Layout::top_down(Align::Min)),
|
||||||
);
|
);
|
||||||
|
let style_stack = ui.style_stack_mut().clone();
|
||||||
panel_ui.set_clip_rect(panel_rect); // If we overflow, don't do so visibly (#4475)
|
panel_ui.set_clip_rect(panel_rect); // If we overflow, don't do so visibly (#4475)
|
||||||
|
|
||||||
let frame = frame.unwrap_or_else(|| Frame::central_panel(ui.style()));
|
let frame = frame.unwrap_or_else(|| Frame::central_panel(ui.style()));
|
||||||
let response = frame.show(&mut panel_ui, |ui| {
|
let response = frame.show(&mut panel_ui, |ui| {
|
||||||
|
ui.style_stack_mut().parent = Some(Arc::new(style_stack));
|
||||||
ui.expand_to_include_rect(ui.max_rect()); // Expand frame to include it all
|
ui.expand_to_include_rect(ui.max_rect()); // Expand frame to include it all
|
||||||
add_contents(ui)
|
add_contents(ui)
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use emath::GuiRounding as _;
|
|||||||
use epaint::mutex::RwLock;
|
use epaint::mutex::RwLock;
|
||||||
|
|
||||||
use crate::containers::menu;
|
use crate::containers::menu;
|
||||||
use crate::widget_style::{HasModifiers, StyleModifiers};
|
use crate::widget_style::{HasModifiers, StyleModifiers, StyleStack};
|
||||||
use crate::{containers::*, ecolor::*, layout::*, placer::Placer, widgets::*, *};
|
use crate::{containers::*, ecolor::*, layout::*, placer::Placer, widgets::*, *};
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -91,8 +91,8 @@ pub struct Ui {
|
|||||||
/// end of a [`Ui::scope`].
|
/// end of a [`Ui::scope`].
|
||||||
min_rect_already_remembered: bool,
|
min_rect_already_remembered: bool,
|
||||||
|
|
||||||
/// Modifiers for style purpose
|
/// test
|
||||||
modifiers: StyleModifiers,
|
style_stack: Arc<StyleStack>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allow using [`Ui`] like a [`Context`].
|
/// Allow using [`Ui`] like a [`Context`].
|
||||||
@@ -117,7 +117,7 @@ impl Ui {
|
|||||||
let UiBuilder {
|
let UiBuilder {
|
||||||
id_salt,
|
id_salt,
|
||||||
global_scope: _,
|
global_scope: _,
|
||||||
ui_stack_info,
|
mut ui_stack_info,
|
||||||
layer_id,
|
layer_id,
|
||||||
max_rect,
|
max_rect,
|
||||||
layout,
|
layout,
|
||||||
@@ -143,6 +143,9 @@ impl Ui {
|
|||||||
let style = style.unwrap_or_else(|| ctx.global_style());
|
let style = style.unwrap_or_else(|| ctx.global_style());
|
||||||
let sense = sense.unwrap_or_else(Sense::hover);
|
let sense = sense.unwrap_or_else(Sense::hover);
|
||||||
|
|
||||||
|
// Temporary use of user tags as proof of concept
|
||||||
|
ui_stack_info = ui_stack_info.with_tag("root");
|
||||||
|
|
||||||
let placer = Placer::new(max_rect, layout);
|
let placer = Placer::new(max_rect, layout);
|
||||||
let ui_stack = UiStack {
|
let ui_stack = UiStack {
|
||||||
id,
|
id,
|
||||||
@@ -152,6 +155,12 @@ impl Ui {
|
|||||||
min_rect: placer.min_rect(),
|
min_rect: placer.min_rect(),
|
||||||
max_rect: placer.max_rect(),
|
max_rect: placer.max_rect(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let style_stack = StyleStack {
|
||||||
|
modifiers: StyleModifiers::default(),
|
||||||
|
parent: None,
|
||||||
|
};
|
||||||
|
|
||||||
let mut ui = Ui {
|
let mut ui = Ui {
|
||||||
id,
|
id,
|
||||||
unique_id: id,
|
unique_id: id,
|
||||||
@@ -165,7 +174,7 @@ impl Ui {
|
|||||||
stack: Arc::new(ui_stack),
|
stack: Arc::new(ui_stack),
|
||||||
sense,
|
sense,
|
||||||
min_rect_already_remembered: false,
|
min_rect_already_remembered: false,
|
||||||
modifiers: StyleModifiers::default(),
|
style_stack: Arc::new(style_stack),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(accessibility_parent) = accessibility_parent {
|
if let Some(accessibility_parent) = accessibility_parent {
|
||||||
@@ -315,6 +324,12 @@ impl Ui {
|
|||||||
min_rect: placer.min_rect(),
|
min_rect: placer.min_rect(),
|
||||||
max_rect: placer.max_rect(),
|
max_rect: placer.max_rect(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let style_stack = StyleStack {
|
||||||
|
modifiers: StyleModifiers::default(),
|
||||||
|
parent: Some(Arc::clone(&self.style_stack)),
|
||||||
|
};
|
||||||
|
|
||||||
let mut child_ui = Ui {
|
let mut child_ui = Ui {
|
||||||
id: stable_id,
|
id: stable_id,
|
||||||
unique_id,
|
unique_id,
|
||||||
@@ -328,7 +343,7 @@ impl Ui {
|
|||||||
stack: Arc::new(ui_stack),
|
stack: Arc::new(ui_stack),
|
||||||
sense,
|
sense,
|
||||||
min_rect_already_remembered: false,
|
min_rect_already_remembered: false,
|
||||||
modifiers: StyleModifiers::default(),
|
style_stack: Arc::new(style_stack),
|
||||||
};
|
};
|
||||||
|
|
||||||
if disabled {
|
if disabled {
|
||||||
@@ -3153,11 +3168,34 @@ impl Drop for Ui {
|
|||||||
|
|
||||||
impl HasModifiers for Ui {
|
impl HasModifiers for Ui {
|
||||||
fn modifiers(&self) -> &StyleModifiers {
|
fn modifiers(&self) -> &StyleModifiers {
|
||||||
&self.modifiers
|
&self.style_stack.modifiers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modifiers_mut(&mut self) -> &mut StyleModifiers {
|
fn modifiers_mut(&mut self) -> &mut StyleModifiers {
|
||||||
&mut self.modifiers
|
&mut self.style_stack_mut().modifiers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ui {
|
||||||
|
/// borrow internal [`StyleStack`].
|
||||||
|
/// Allow the access to the modifiers of the ui's ancestors
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```
|
||||||
|
/// # egui::__run_test_ui(|ui| {
|
||||||
|
/// // Check if the parent has the "test" modifier
|
||||||
|
/// ui.style_stack().parent.is_some_and(|parent| parent.modifiers.has("test"));
|
||||||
|
///
|
||||||
|
/// // Same but shorter
|
||||||
|
/// ui.style_stack().parent_has("test");
|
||||||
|
/// # });
|
||||||
|
/// ```
|
||||||
|
pub fn style_stack(&self) -> &StyleStack {
|
||||||
|
&self.style_stack
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn style_stack_mut(&mut self) -> &mut StyleStack {
|
||||||
|
Arc::make_mut(&mut self.style_stack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ impl UiTags {
|
|||||||
/// Note: since [`UiStack`] contains a reference to its parent, it is both a stack, and a node within
|
/// Note: since [`UiStack`] contains a reference to its parent, it is both a stack, and a node within
|
||||||
/// that stack. Most of its methods are about the specific node, but some methods walk up the
|
/// that stack. Most of its methods are about the specific node, but some methods walk up the
|
||||||
/// hierarchy to provide information about the entire stack.
|
/// hierarchy to provide information about the entire stack.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct UiStack {
|
pub struct UiStack {
|
||||||
// stuff that `Ui::child_ui` can deal with directly
|
// stuff that `Ui::child_ui` can deal with directly
|
||||||
pub id: Id,
|
pub id: Id,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::{iter::FusedIterator, sync::Arc};
|
||||||
|
|
||||||
use emath::Vec2;
|
use emath::Vec2;
|
||||||
use epaint::{Color32, FontId, Shadow, Stroke, text::TextWrapMode};
|
use epaint::{Color32, FontId, Shadow, Stroke, text::TextWrapMode};
|
||||||
|
|
||||||
@@ -203,7 +205,7 @@ impl Style {
|
|||||||
pub type WidgetStyleModifier = String;
|
pub type WidgetStyleModifier = String;
|
||||||
|
|
||||||
/// For now we use Vec for the modifiers but later we could use `SmallVev` for performance
|
/// For now we use Vec for the modifiers but later we could use `SmallVev` for performance
|
||||||
#[derive(Default)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct StyleModifiers {
|
pub struct StyleModifiers {
|
||||||
modifiers: Vec<WidgetStyleModifier>,
|
modifiers: Vec<WidgetStyleModifier>,
|
||||||
theme: Option<Theme>,
|
theme: Option<Theme>,
|
||||||
@@ -213,15 +215,15 @@ pub struct StyleModifiers {
|
|||||||
impl StyleModifiers {
|
impl StyleModifiers {
|
||||||
/// Add multiples modifiers in one method and return the list for method chaining
|
/// Add multiples modifiers in one method and return the list for method chaining
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_modifiers(mut self, classes: &[WidgetStyleModifier]) -> Self {
|
pub fn with_modifiers(mut self, modifiers: &[WidgetStyleModifier]) -> Self {
|
||||||
self.modifiers.append(&mut classes.to_vec());
|
self.modifiers.append(&mut modifiers.to_vec());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a single modifier and return the list for method chaining
|
/// Add a single modifier and return the list for method chaining
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_modifier(mut self, class: impl Into<WidgetStyleModifier>) -> Self {
|
pub fn with_modifier(mut self, modifier: impl Into<WidgetStyleModifier>) -> Self {
|
||||||
self.modifiers.push(class.into());
|
self.modifiers.push(modifier.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,6 +254,10 @@ impl StyleModifiers {
|
|||||||
pub fn with_state(&mut self, state: WidgetState) {
|
pub fn with_state(&mut self, state: WidgetState) {
|
||||||
self.state = state;
|
self.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn list(&self) -> Vec<WidgetStyleModifier> {
|
||||||
|
self.modifiers.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Any widgets supporting [`StyleModifiers`] must implement this trait
|
/// Any widgets supporting [`StyleModifiers`] must implement this trait
|
||||||
@@ -260,11 +266,6 @@ pub trait HasModifiers {
|
|||||||
|
|
||||||
fn modifiers_mut(&mut self) -> &mut StyleModifiers;
|
fn modifiers_mut(&mut self) -> &mut StyleModifiers;
|
||||||
|
|
||||||
fn add_class(&mut self, modifier: impl Into<WidgetStyleModifier>) -> &Self {
|
|
||||||
self.modifiers_mut().add_if(modifier.into(), true);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_modifier(mut self, modifier: impl Into<WidgetStyleModifier>) -> Self
|
fn with_modifier(mut self, modifier: impl Into<WidgetStyleModifier>) -> Self
|
||||||
where
|
where
|
||||||
@@ -283,6 +284,28 @@ pub trait HasModifiers {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add_modifier(&mut self, modifier: impl Into<WidgetStyleModifier>) -> &mut Self
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
self.modifiers_mut().add_if(modifier.into(), true);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add_modifier_if(
|
||||||
|
&mut self,
|
||||||
|
modifier: impl Into<WidgetStyleModifier>,
|
||||||
|
condition: bool,
|
||||||
|
) -> &mut Self
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
self.modifiers_mut().add_if(modifier.into(), condition);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn theme(mut self, theme: Theme) -> Self
|
fn theme(mut self, theme: Theme) -> Self
|
||||||
where
|
where
|
||||||
@@ -315,3 +338,62 @@ macro_rules! add_modifiers {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct StyleStack {
|
||||||
|
pub modifiers: StyleModifiers,
|
||||||
|
pub parent: Option<Arc<Self>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// these methods act on the entire stack
|
||||||
|
impl StyleStack {
|
||||||
|
/// Return an iterator that walks the stack from this node to the root.
|
||||||
|
#[expect(clippy::iter_without_into_iter)]
|
||||||
|
pub fn iter(&self) -> StyleStackIterator<'_> {
|
||||||
|
StyleStackIterator { next: Some(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if any of the ancestor has the modifiers
|
||||||
|
pub fn ancestors_have(&self, modifier: impl Into<WidgetStyleModifier>) -> bool {
|
||||||
|
let modifier = modifier.into();
|
||||||
|
self.iter()
|
||||||
|
.any(|parent| parent.modifiers.has(modifier.clone()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if the direct parent has the modifiers
|
||||||
|
pub fn parent_has(&self, modifier: impl Into<WidgetStyleModifier>) -> bool {
|
||||||
|
if let Some(parent) = &self.parent {
|
||||||
|
parent.modifiers.has(modifier)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parent_modifiers(&self) -> Option<&StyleModifiers> {
|
||||||
|
self.parent.as_ref().map(|parent| &parent.modifiers)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ancestors_modifiers(&self) -> Vec<&StyleModifiers> {
|
||||||
|
self.iter().map(|f| &f.modifiers).collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Iterator that walks up a stack of `StackFrame`s.
|
||||||
|
///
|
||||||
|
/// See [`StyleStack::iter`].
|
||||||
|
pub struct StyleStackIterator<'a> {
|
||||||
|
next: Option<&'a StyleStack>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for StyleStackIterator<'a> {
|
||||||
|
type Item = &'a StyleStack;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let current = self.next;
|
||||||
|
self.next = current.and_then(|style| style.parent.as_deref());
|
||||||
|
current
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FusedIterator for StyleStackIterator<'_> {}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ pub struct Checkbox<'a> {
|
|||||||
checked: &'a mut bool,
|
checked: &'a mut bool,
|
||||||
atoms: Atoms<'a>,
|
atoms: Atoms<'a>,
|
||||||
indeterminate: bool,
|
indeterminate: bool,
|
||||||
modifier: StyleModifiers,
|
modifiers: StyleModifiers,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Checkbox<'a> {
|
impl<'a> Checkbox<'a> {
|
||||||
@@ -33,7 +33,7 @@ impl<'a> Checkbox<'a> {
|
|||||||
checked,
|
checked,
|
||||||
atoms: atoms.into_atoms(),
|
atoms: atoms.into_atoms(),
|
||||||
indeterminate: false,
|
indeterminate: false,
|
||||||
modifier: StyleModifiers::default(),
|
modifiers: StyleModifiers::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ impl Widget for Checkbox<'_> {
|
|||||||
checked,
|
checked,
|
||||||
mut atoms,
|
mut atoms,
|
||||||
indeterminate,
|
indeterminate,
|
||||||
mut modifier,
|
modifiers: mut modifier,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
// Get the widget style by reading the response from the previous pass
|
// Get the widget style by reading the response from the previous pass
|
||||||
@@ -161,10 +161,10 @@ impl Widget for Checkbox<'_> {
|
|||||||
|
|
||||||
impl HasModifiers for Checkbox<'_> {
|
impl HasModifiers for Checkbox<'_> {
|
||||||
fn modifiers(&self) -> &crate::widget_style::StyleModifiers {
|
fn modifiers(&self) -> &crate::widget_style::StyleModifiers {
|
||||||
&self.modifier
|
&self.modifiers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modifiers_mut(&mut self) -> &mut crate::widget_style::StyleModifiers {
|
fn modifiers_mut(&mut self) -> &mut crate::widget_style::StyleModifiers {
|
||||||
&mut self.modifier
|
&mut self.modifiers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub struct Separator {
|
|||||||
spacing: Option<f32>,
|
spacing: Option<f32>,
|
||||||
grow: f32,
|
grow: f32,
|
||||||
is_horizontal_line: Option<bool>,
|
is_horizontal_line: Option<bool>,
|
||||||
modifier: StyleModifiers,
|
modifiers: StyleModifiers,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Separator {
|
impl Default for Separator {
|
||||||
@@ -28,7 +28,7 @@ impl Default for Separator {
|
|||||||
spacing: None,
|
spacing: None,
|
||||||
grow: 0.0,
|
grow: 0.0,
|
||||||
is_horizontal_line: None,
|
is_horizontal_line: None,
|
||||||
modifier: StyleModifiers::default(),
|
modifiers: StyleModifiers::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,7 +96,7 @@ impl Widget for Separator {
|
|||||||
spacing,
|
spacing,
|
||||||
grow,
|
grow,
|
||||||
is_horizontal_line,
|
is_horizontal_line,
|
||||||
mut modifier,
|
modifiers: mut modifier,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
// Get the widget style by reading the response from the previous pass
|
// Get the widget style by reading the response from the previous pass
|
||||||
@@ -152,10 +152,10 @@ impl Widget for Separator {
|
|||||||
|
|
||||||
impl HasModifiers for Separator {
|
impl HasModifiers for Separator {
|
||||||
fn modifiers(&self) -> &crate::widget_style::StyleModifiers {
|
fn modifiers(&self) -> &crate::widget_style::StyleModifiers {
|
||||||
&self.modifier
|
&self.modifiers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modifiers_mut(&mut self) -> &mut crate::widget_style::StyleModifiers {
|
fn modifiers_mut(&mut self) -> &mut crate::widget_style::StyleModifiers {
|
||||||
&mut self.modifier
|
&mut self.modifiers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
examples/styling_engine/Cargo.toml
Normal file
19
examples/styling_engine/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[package]
|
||||||
|
name = "styling_engine"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Emil Ernerfeldt <emil.ernerfeldt@gmail.com>"]
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
edition = "2024"
|
||||||
|
rust-version = "1.92"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
eframe = { workspace = true, features = [
|
||||||
|
"default",
|
||||||
|
"__screenshot", # __screenshot is so we can dump a screenshot using EFRAME_SCREENSHOT_TO
|
||||||
|
] }
|
||||||
|
env_logger = { workspace = true, features = ["auto-color", "humantime"] }
|
||||||
7
examples/styling_engine/README.md
Normal file
7
examples/styling_engine/README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Example showing how the style engine work.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo run -p styling_engine
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
3
examples/styling_engine/screenshot.png
Normal file
3
examples/styling_engine/screenshot.png
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:7cde6a351fbcf5a5d3b5474353c627a9c93801563880b7ff41dfa025da3c6d37
|
||||||
|
size 8587
|
||||||
44
examples/styling_engine/src/main.rs
Normal file
44
examples/styling_engine/src/main.rs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
|
||||||
|
#![expect(rustdoc::missing_crate_level_docs)] // it's an example
|
||||||
|
|
||||||
|
use eframe::egui::{self, Button, Frame, Grid, Margin, Panel, widget_style::HasModifiers as _};
|
||||||
|
|
||||||
|
fn main() -> eframe::Result {
|
||||||
|
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`).
|
||||||
|
|
||||||
|
let options = eframe::NativeOptions {
|
||||||
|
viewport: egui::ViewportBuilder::default().with_inner_size([600.0, 400.0]),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut style_code = "// future style code live editor".to_owned();
|
||||||
|
|
||||||
|
eframe::run_ui_native("My egui App", options, move |ui, _frame| {
|
||||||
|
// Add a modifier to this ui
|
||||||
|
ui.add_modifier("body");
|
||||||
|
ui.label("body");
|
||||||
|
egui::CentralPanel::default().show_inside(ui, |ui| {
|
||||||
|
// Add a modifier to this ui
|
||||||
|
ui.add_modifier("central panel");
|
||||||
|
ui.label("central panel");
|
||||||
|
|
||||||
|
Panel::left("style_code").show_inside(ui, |ui| {
|
||||||
|
ui.add_modifier("style code editor");
|
||||||
|
ui.label("style code editor");
|
||||||
|
|
||||||
|
ui.text_edit_multiline(&mut style_code);
|
||||||
|
});
|
||||||
|
|
||||||
|
Grid::new("grid").show(ui, |ui| {
|
||||||
|
ui.add_modifier("grid");
|
||||||
|
|
||||||
|
Frame::new().inner_margin(Margin::same(10)).show(ui, |ui| {
|
||||||
|
ui.add_modifier("frame1");
|
||||||
|
|
||||||
|
ui.add(Button::new("button1").with_modifier("button1"));
|
||||||
|
ui.add(Button::new("button2").with_modifier("button2"));
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user