mirror of https://github.com/wayvr-org/wayvr.git
wgui: `ComponentBarGraph`, `WidgetCustomDraw`
This commit is contained in:
parent
0f6f344c97
commit
d5148e2107
|
|
@ -910,6 +910,17 @@ dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chacha20"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures 0.3.0",
|
||||||
|
"rand_core 0.10.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.42"
|
version = "0.4.42"
|
||||||
|
|
@ -1231,6 +1242,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
|
@ -1417,6 +1437,7 @@ dependencies = [
|
||||||
"hyper",
|
"hyper",
|
||||||
"keyvalues-parser",
|
"keyvalues-parser",
|
||||||
"log",
|
"log",
|
||||||
|
"rand 0.10.0",
|
||||||
"rust-embed",
|
"rust-embed",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|
@ -2106,6 +2127,20 @@ dependencies = [
|
||||||
"wasip2",
|
"wasip2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"r-efi",
|
||||||
|
"rand_core 0.10.0",
|
||||||
|
"wasip2",
|
||||||
|
"wasip3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gif"
|
name = "gif"
|
||||||
version = "0.14.1"
|
version = "0.14.1"
|
||||||
|
|
@ -2440,6 +2475,12 @@ dependencies = [
|
||||||
"zerovec",
|
"zerovec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "id-arena"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ident_case"
|
name = "ident_case"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
|
@ -2575,6 +2616,8 @@ checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown 0.16.1",
|
"hashbrown 0.16.1",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2795,6 +2838,18 @@ version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazycell"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leb128fmt"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lebe"
|
name = "lebe"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
|
|
@ -4330,6 +4385,17 @@ dependencies = [
|
||||||
"rand_core 0.9.3",
|
"rand_core 0.9.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8"
|
||||||
|
dependencies = [
|
||||||
|
"chacha20",
|
||||||
|
"getrandom 0.4.1",
|
||||||
|
"rand_core 0.10.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_chacha"
|
name = "rand_chacha"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
|
@ -4387,6 +4453,12 @@ dependencies = [
|
||||||
"getrandom 0.3.4",
|
"getrandom 0.3.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_hc"
|
name = "rand_hc"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
@ -4604,6 +4676,12 @@ dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ringbuffer"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57b0b88a509053cbfd535726dcaaceee631313cef981266119527a1d110f6d2b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rodio"
|
name = "rodio"
|
||||||
version = "0.21.1"
|
version = "0.21.1"
|
||||||
|
|
@ -4983,7 +5061,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures 0.2.17",
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -5925,6 +6003,12 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unsafe-libyaml"
|
name = "unsafe-libyaml"
|
||||||
version = "0.2.11"
|
version = "0.2.11"
|
||||||
|
|
@ -6126,7 +6210,16 @@ version = "1.0.1+wasi-0.2.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
|
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wit-bindgen",
|
"wit-bindgen 0.46.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasip3"
|
||||||
|
version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
|
||||||
|
dependencies = [
|
||||||
|
"wit-bindgen 0.51.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -6187,6 +6280,40 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-encoder"
|
||||||
|
version = "0.244.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
|
||||||
|
dependencies = [
|
||||||
|
"leb128fmt",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-metadata"
|
||||||
|
version = "0.244.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"indexmap 2.12.1",
|
||||||
|
"wasm-encoder",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasmparser"
|
||||||
|
version = "0.244.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.10.0",
|
||||||
|
"hashbrown 0.15.5",
|
||||||
|
"indexmap 2.12.1",
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-backend"
|
name = "wayland-backend"
|
||||||
version = "0.3.12"
|
version = "0.3.12"
|
||||||
|
|
@ -6472,6 +6599,7 @@ dependencies = [
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"regex",
|
"regex",
|
||||||
"resvg",
|
"resvg",
|
||||||
|
"ringbuffer",
|
||||||
"roxmltree 0.21.1",
|
"roxmltree 0.21.1",
|
||||||
"rust-embed",
|
"rust-embed",
|
||||||
"rustc-hash 2.1.1",
|
"rustc-hash 2.1.1",
|
||||||
|
|
@ -6995,6 +7123,94 @@ version = "0.46.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
|
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen"
|
||||||
|
version = "0.51.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
|
||||||
|
dependencies = [
|
||||||
|
"wit-bindgen-rust-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-core"
|
||||||
|
version = "0.51.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"heck 0.5.0",
|
||||||
|
"wit-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-rust"
|
||||||
|
version = "0.51.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"heck 0.5.0",
|
||||||
|
"indexmap 2.12.1",
|
||||||
|
"prettyplease",
|
||||||
|
"syn 2.0.113",
|
||||||
|
"wasm-metadata",
|
||||||
|
"wit-bindgen-core",
|
||||||
|
"wit-component",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-rust-macro"
|
||||||
|
version = "0.51.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.113",
|
||||||
|
"wit-bindgen-core",
|
||||||
|
"wit-bindgen-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-component"
|
||||||
|
version = "0.244.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bitflags 2.10.0",
|
||||||
|
"indexmap 2.12.1",
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"wasm-encoder",
|
||||||
|
"wasm-metadata",
|
||||||
|
"wasmparser",
|
||||||
|
"wit-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-parser"
|
||||||
|
version = "0.244.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"id-arena",
|
||||||
|
"indexmap 2.12.1",
|
||||||
|
"log",
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"unicode-xid",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wlx-capture"
|
name = "wlx-capture"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ hyper = { version = "1.8.1", features = ["client", "http1", "http2"] }
|
||||||
http-body-util = "0.1.3"
|
http-body-util = "0.1.3"
|
||||||
async-native-tls = "0.5.0"
|
async-native-tls = "0.5.0"
|
||||||
smol-hyper = "0.1.1"
|
smol-hyper = "0.1.1"
|
||||||
|
rand = "0.10.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["monado"]
|
default = ["monado"]
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,10 @@
|
||||||
|
|
||||||
<elements>
|
<elements>
|
||||||
<rectangle macro="group_box">
|
<rectangle macro="group_box">
|
||||||
<GroupBoxTitle src_builtin="dashboard/not_a_bug.svg" text="Debug timings (TODO)" />
|
<GroupBoxTitle src_builtin="dashboard/not_a_bug.svg" text="Debug timings" />
|
||||||
|
|
||||||
|
<BarGraph id="graph_first" width="200" height="100" unit="%" limit_min="0" limit_max="50" capacity="100" />
|
||||||
|
<BarGraph id="graph_second" width="300" height="200" unit="ms" capacity="50" />
|
||||||
</rectangle>
|
</rectangle>
|
||||||
</elements>
|
</elements>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
@ -2,7 +2,13 @@ use std::{collections::HashMap, marker::PhantomData, rc::Rc};
|
||||||
|
|
||||||
use wgui::{
|
use wgui::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
components::{checkbox::ComponentCheckbox, slider::ComponentSlider, tabs::ComponentTabs},
|
components::{
|
||||||
|
bar_graph::{ComponentBarGraph, ValueCell},
|
||||||
|
checkbox::ComponentCheckbox,
|
||||||
|
slider::ComponentSlider,
|
||||||
|
tabs::ComponentTabs,
|
||||||
|
},
|
||||||
|
drawing,
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
layout::{Layout, WidgetID},
|
layout::{Layout, WidgetID},
|
||||||
parser::{self, Fetchable, ParseDocumentParams, ParserState},
|
parser::{self, Fetchable, ParseDocumentParams, ParserState},
|
||||||
|
|
@ -56,6 +62,9 @@ struct SubtabGeneralSettings {
|
||||||
struct SubtabDebugTimings {
|
struct SubtabDebugTimings {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
state: ParserState,
|
state: ParserState,
|
||||||
|
|
||||||
|
graph_first: Rc<ComponentBarGraph>,
|
||||||
|
graph_second: Rc<ComponentBarGraph>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
|
@ -121,11 +130,20 @@ impl<T> Tab<T> for TabMonado<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// every few seconds
|
match &mut self.subtab {
|
||||||
if let Subtab::ProcessList(_) = &self.subtab
|
Subtab::Empty => {}
|
||||||
&& self.ticks.is_multiple_of(500)
|
Subtab::GeneralSettings(_) => {}
|
||||||
{
|
Subtab::ProcessList(_) => {
|
||||||
self.tasks.push(Task::ProcessListRefresh);
|
// every few seconds
|
||||||
|
if let Subtab::ProcessList(_) = &self.subtab
|
||||||
|
&& self.ticks.is_multiple_of(500)
|
||||||
|
{
|
||||||
|
self.tasks.push(Task::ProcessListRefresh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Subtab::DebugTimings(timings) => {
|
||||||
|
timings.update(&mut frontend.layout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ticks += 1;
|
self.ticks += 1;
|
||||||
|
|
@ -214,7 +232,28 @@ impl SubtabDebugTimings {
|
||||||
parent_id,
|
parent_id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(Self { state })
|
let graph_first = state.fetch_component_as::<ComponentBarGraph>("graph_first")?;
|
||||||
|
let graph_second = state.fetch_component_as::<ComponentBarGraph>("graph_second")?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
state,
|
||||||
|
graph_first,
|
||||||
|
graph_second,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, layout: &mut Layout) {
|
||||||
|
self.graph_first.push_value(ValueCell {
|
||||||
|
value: rand::random_range(0.0..50.0),
|
||||||
|
color: drawing::Color::new(rand::random_range(0.0..1.0), rand::random_range(0.0..1.0), 0.0, 1.0),
|
||||||
|
});
|
||||||
|
|
||||||
|
self.graph_second.push_value(ValueCell {
|
||||||
|
value: rand::random_range(0.0..30.0),
|
||||||
|
color: drawing::Color::new(0.0, rand::random_range(0.0..1.0), rand::random_range(0.0..1.0), 1.0),
|
||||||
|
});
|
||||||
|
|
||||||
|
layout.mark_redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,10 @@ pub struct MonadoState {
|
||||||
|
|
||||||
impl MonadoState {
|
impl MonadoState {
|
||||||
pub fn new() -> anyhow::Result<Self> {
|
pub fn new() -> anyhow::Result<Self> {
|
||||||
let mut ipc = libmonado::Monado::auto_connect().map_err(|s| anyhow::anyhow!("{s}"))?;
|
let ipc = libmonado::Monado::auto_connect().map_err(|s| anyhow::anyhow!("{s}"))?;
|
||||||
|
let mut res = Self { ipc, metrics: None };
|
||||||
let metrics = monado_metrics::metrics_fd::MonadoMetricsFd::new(&mut ipc)?;
|
res.set_metrics_enabled(true)?;
|
||||||
|
Ok(res)
|
||||||
Ok(Self {
|
|
||||||
ipc,
|
|
||||||
metrics: Some(metrics),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self) {
|
||||||
|
|
@ -22,4 +18,16 @@ impl MonadoState {
|
||||||
metrics.update();
|
metrics.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_metrics_enabled(&mut self, enabled: bool) -> anyhow::Result<()> {
|
||||||
|
if enabled && self.metrics.is_none() {
|
||||||
|
self.metrics = Some(monado_metrics::metrics_fd::MonadoMetricsFd::new(
|
||||||
|
&mut self.ipc,
|
||||||
|
)?);
|
||||||
|
} else {
|
||||||
|
self.metrics = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use std::{
|
use std::{
|
||||||
|
collections::VecDeque,
|
||||||
io::Read,
|
io::Read,
|
||||||
os::{fd::AsFd, unix::net::UnixStream},
|
os::{fd::AsFd, unix::net::UnixStream},
|
||||||
};
|
};
|
||||||
|
|
@ -8,6 +9,8 @@ use crate::subsystem::monado_metrics::proto;
|
||||||
pub struct MonadoMetricsFd {
|
pub struct MonadoMetricsFd {
|
||||||
stream_reader: UnixStream,
|
stream_reader: UnixStream,
|
||||||
stream_writer: UnixStream,
|
stream_writer: UnixStream,
|
||||||
|
|
||||||
|
records: VecDeque<proto::Record>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MonadoMetricsFd {
|
impl MonadoMetricsFd {
|
||||||
|
|
@ -21,11 +24,18 @@ impl MonadoMetricsFd {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
stream_reader,
|
stream_reader,
|
||||||
stream_writer,
|
stream_writer,
|
||||||
|
records: VecDeque::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_message(&self, record: proto::Record) {
|
fn parse_message(&mut self, record: proto::Record) {
|
||||||
log::debug!("metrics message: {record:?}");
|
log::debug!("metrics message: {record:?}");
|
||||||
|
|
||||||
|
if self.records.len() < 500 {
|
||||||
|
self.records.push_back(record);
|
||||||
|
} else {
|
||||||
|
log::warn!("record queue full, discarding");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// called every frame
|
// called every frame
|
||||||
|
|
|
||||||
|
|
@ -35,3 +35,4 @@ vulkano.workspace = true
|
||||||
vulkano-shaders.workspace = true
|
vulkano-shaders.workspace = true
|
||||||
rust-embed.workspace = true
|
rust-embed.workspace = true
|
||||||
flate2 = "1.1.5"
|
flate2 = "1.1.5"
|
||||||
|
ringbuffer = "0.16.0"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
## [Built-in components](#components)
|
## [Built-in components](#components)
|
||||||
|
|
||||||
[Button](#button-component), [Slider](#slider-component), [CheckBox](#checkbox-component), [Tabs](#tabs-component) ([Tab](#tab-component)), [EditBox](#editbox-component)
|
[Button](#button-component), [Slider](#slider-component), [CheckBox](#checkbox-component), [Tabs](#tabs-component) ([Tab](#tab-component)), [EditBox](#editbox-component), [BarGraph](#bargraph-component)
|
||||||
|
|
||||||
## [Examples](#examples)
|
## [Examples](#examples)
|
||||||
|
|
||||||
|
|
@ -448,6 +448,30 @@ _Image path (see [sprite](#sprite-widget)) for src descriptions_
|
||||||
|
|
||||||
_Initial text content_
|
_Initial text content_
|
||||||
|
|
||||||
|
## BarGraph component
|
||||||
|
|
||||||
|
### `<BarGraph>`
|
||||||
|
|
||||||
|
### A bar graph widget
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
`limit_min`: **float**
|
||||||
|
|
||||||
|
_Minimum limit value_
|
||||||
|
|
||||||
|
`limit_max`: **float**
|
||||||
|
|
||||||
|
_Maximum limit value_
|
||||||
|
|
||||||
|
`unit`: **string** (default: "")
|
||||||
|
|
||||||
|
_Unit type, for example "%" or "ms"_
|
||||||
|
|
||||||
|
`capacity`: **int** (default: 50)
|
||||||
|
|
||||||
|
_Value count_
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Examples
|
# Examples
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,241 @@
|
||||||
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
|
use glam::Vec2;
|
||||||
|
use ringbuffer::{AllocRingBuffer, RingBuffer};
|
||||||
|
use taffy::{
|
||||||
|
FlexDirection, JustifyContent,
|
||||||
|
prelude::{auto, length, percent},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
components::{Component, ComponentBase, ComponentTrait, RefreshData},
|
||||||
|
drawing::{self, GradientMode, PrimitiveExtent, RenderPrimitive},
|
||||||
|
event::CallbackDataCommon,
|
||||||
|
i18n::Translation,
|
||||||
|
layout::{WidgetID, WidgetPair},
|
||||||
|
renderer_vk::text::{FontWeight, HorizontalAlign, TextStyle},
|
||||||
|
widget::{
|
||||||
|
ConstructEssentials,
|
||||||
|
custom_draw::{WidgetCustomDraw, WidgetCustomDrawParams},
|
||||||
|
div::WidgetDiv,
|
||||||
|
label::{WidgetLabel, WidgetLabelParams},
|
||||||
|
rectangle::{WidgetRectangle, WidgetRectangleParams},
|
||||||
|
util::WLength,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Params {
|
||||||
|
pub style: taffy::Style,
|
||||||
|
pub limits: (f32, f32),
|
||||||
|
pub unit: String,
|
||||||
|
pub capacity: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ValueCell {
|
||||||
|
pub value: f32,
|
||||||
|
pub color: drawing::Color,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
limits: (f32, f32), /* min - max */
|
||||||
|
values: AllocRingBuffer<ValueCell>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::struct_field_names)]
|
||||||
|
struct Data {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
id_root: WidgetID,
|
||||||
|
|
||||||
|
id_label_val_min: WidgetID,
|
||||||
|
id_label_val_max: WidgetID,
|
||||||
|
|
||||||
|
unit: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ComponentBarGraph {
|
||||||
|
base: ComponentBase,
|
||||||
|
data: Rc<Data>,
|
||||||
|
state: Rc<RefCell<State>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ComponentTrait for ComponentBarGraph {
|
||||||
|
fn base(&self) -> &ComponentBase {
|
||||||
|
&self.base
|
||||||
|
}
|
||||||
|
|
||||||
|
fn base_mut(&mut self) -> &mut ComponentBase {
|
||||||
|
&mut self.base
|
||||||
|
}
|
||||||
|
|
||||||
|
fn refresh(&self, data: &mut RefreshData) {
|
||||||
|
let state = self.state.borrow();
|
||||||
|
self.update_limits_text(&state, data.common);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ComponentBarGraph {
|
||||||
|
fn update_limits_text(&self, state: &State, c: &mut CallbackDataCommon) -> Option<()> {
|
||||||
|
let mut label_val_min = c.state.widgets.get_as::<WidgetLabel>(self.data.id_label_val_min)?;
|
||||||
|
let mut label_val_max = c.state.widgets.get_as::<WidgetLabel>(self.data.id_label_val_max)?;
|
||||||
|
|
||||||
|
label_val_min.set_text(
|
||||||
|
c,
|
||||||
|
Translation::from_raw_text_string(format!("{}{}", state.limits.0, self.data.unit)),
|
||||||
|
);
|
||||||
|
label_val_max.set_text(
|
||||||
|
c,
|
||||||
|
Translation::from_raw_text_string(format!("{}{}", state.limits.1, self.data.unit)),
|
||||||
|
);
|
||||||
|
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_limits(&self, c: &mut CallbackDataCommon, limits: (f32, f32)) {
|
||||||
|
let mut state = self.state.borrow_mut();
|
||||||
|
state.limits = limits;
|
||||||
|
self.update_limits_text(&state, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_value(&self, cell: ValueCell) {
|
||||||
|
let mut state = self.state.borrow_mut();
|
||||||
|
state.values.enqueue(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn construct(
|
||||||
|
ess: &mut ConstructEssentials,
|
||||||
|
mut params: Params,
|
||||||
|
) -> anyhow::Result<(WidgetPair, Rc<ComponentBarGraph>)> {
|
||||||
|
let globals = ess.layout.state.globals.clone();
|
||||||
|
|
||||||
|
params.style.flex_direction = FlexDirection::Row;
|
||||||
|
params.style.gap = length(4.0);
|
||||||
|
|
||||||
|
// override style
|
||||||
|
let (root, _) = ess.layout.add_child(ess.parent, WidgetDiv::create(), params.style)?;
|
||||||
|
|
||||||
|
let (vertical_texts, _) = ess.layout.add_child(
|
||||||
|
root.id,
|
||||||
|
WidgetDiv::create(),
|
||||||
|
taffy::Style {
|
||||||
|
justify_content: Some(JustifyContent::SpaceBetween),
|
||||||
|
flex_direction: FlexDirection::Column,
|
||||||
|
size: taffy::Size {
|
||||||
|
width: auto(),
|
||||||
|
height: percent(1.0),
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let (rect, _) = ess.layout.add_child(
|
||||||
|
root.id,
|
||||||
|
WidgetRectangle::create(WidgetRectangleParams {
|
||||||
|
border: 2.0,
|
||||||
|
border_color: drawing::Color::new(1.0, 1.0, 1.0, 0.5),
|
||||||
|
round: WLength::Units(3.0),
|
||||||
|
gradient: GradientMode::Vertical,
|
||||||
|
color: drawing::Color::new(0.0, 0.0, 0.0, 0.6),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
taffy::Style {
|
||||||
|
position: taffy::Position::Relative,
|
||||||
|
size: taffy::Size {
|
||||||
|
width: percent(1.0),
|
||||||
|
height: percent(1.0),
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let state = Rc::new(RefCell::new(State {
|
||||||
|
limits: params.limits,
|
||||||
|
values: AllocRingBuffer::new(params.capacity.clamp(1, 1000) as usize),
|
||||||
|
}));
|
||||||
|
|
||||||
|
let (_, _) = ess.layout.add_child(
|
||||||
|
rect.id,
|
||||||
|
WidgetCustomDraw::create(WidgetCustomDrawParams {
|
||||||
|
func: {
|
||||||
|
let state = state.clone();
|
||||||
|
Box::new(move |info| {
|
||||||
|
let state = state.borrow();
|
||||||
|
let (limit_min, limit_max) = state.limits;
|
||||||
|
|
||||||
|
let box_width = info.boundary.width();
|
||||||
|
let box_height = info.boundary.height();
|
||||||
|
|
||||||
|
let bar_width = box_width / state.values.len() as f32;
|
||||||
|
|
||||||
|
for (idx, cell) in state.values.iter().enumerate() {
|
||||||
|
let norm_value = ((cell.value - limit_min) / (limit_max - limit_min)).clamp(0.0, 1.0);
|
||||||
|
let bar_height = norm_value * box_height;
|
||||||
|
let bar_x = bar_width * idx as f32;
|
||||||
|
let bar_y = box_height - bar_height;
|
||||||
|
|
||||||
|
info.primitives.push(RenderPrimitive::Rectangle(
|
||||||
|
PrimitiveExtent {
|
||||||
|
boundary: drawing::Boundary {
|
||||||
|
pos: Vec2::new(bar_x, bar_y),
|
||||||
|
size: Vec2::new(bar_width, bar_height),
|
||||||
|
},
|
||||||
|
transform: info.transform.transform,
|
||||||
|
},
|
||||||
|
drawing::Rectangle {
|
||||||
|
color: cell.color,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
taffy::Style {
|
||||||
|
size: taffy::Size {
|
||||||
|
width: percent(1.0),
|
||||||
|
height: percent(1.0),
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let label_params = WidgetLabelParams {
|
||||||
|
style: TextStyle {
|
||||||
|
align: Some(HorizontalAlign::Right),
|
||||||
|
weight: Some(FontWeight::Bold),
|
||||||
|
size: Some(11.0),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let (label_val_max, _) = ess.layout.add_child(
|
||||||
|
vertical_texts.id,
|
||||||
|
WidgetLabel::create(&mut globals.get(), label_params.clone()),
|
||||||
|
Default::default(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let (label_val_min, _) = ess.layout.add_child(
|
||||||
|
vertical_texts.id,
|
||||||
|
WidgetLabel::create(&mut globals.get(), label_params),
|
||||||
|
Default::default(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let data = Rc::new(Data {
|
||||||
|
id_root: root.id,
|
||||||
|
id_label_val_min: label_val_min.id,
|
||||||
|
id_label_val_max: label_val_max.id,
|
||||||
|
unit: params.unit,
|
||||||
|
});
|
||||||
|
|
||||||
|
let base = ComponentBase {
|
||||||
|
id: root.id,
|
||||||
|
lhandles: Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let bar_graph = Rc::new(ComponentBarGraph { base, data, state });
|
||||||
|
|
||||||
|
ess.layout.defer_component_refresh(Component(bar_graph.clone()));
|
||||||
|
Ok((root, bar_graph))
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ use crate::{
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub mod bar_graph;
|
||||||
pub mod button;
|
pub mod button;
|
||||||
pub mod checkbox;
|
pub mod checkbox;
|
||||||
pub mod editbox;
|
pub mod editbox;
|
||||||
|
|
|
||||||
|
|
@ -225,11 +225,13 @@ pub struct ImagePrimitive {
|
||||||
pub round_units: u8,
|
pub round_units: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct PrimitiveExtent {
|
pub struct PrimitiveExtent {
|
||||||
pub(super) boundary: Boundary,
|
pub(super) boundary: Boundary,
|
||||||
pub(super) transform: Mat4,
|
pub(super) transform: Mat4,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub enum RenderPrimitive {
|
pub enum RenderPrimitive {
|
||||||
NewPass,
|
NewPass,
|
||||||
Rectangle(PrimitiveExtent, Rectangle),
|
Rectangle(PrimitiveExtent, Rectangle),
|
||||||
|
|
|
||||||
|
|
@ -883,6 +883,7 @@ impl Layout {
|
||||||
widget::WidgetType::Label => drawing::Color::new(0.4, 1.0, 0.0, 1.0),
|
widget::WidgetType::Label => drawing::Color::new(0.4, 1.0, 0.0, 1.0),
|
||||||
widget::WidgetType::Sprite => drawing::Color::new(0.0, 0.8, 1.0, 1.0),
|
widget::WidgetType::Sprite => drawing::Color::new(0.0, 0.8, 1.0, 1.0),
|
||||||
widget::WidgetType::Rectangle => drawing::Color::new(1.0, 0.5, 0.2, 1.0),
|
widget::WidgetType::Rectangle => drawing::Color::new(1.0, 0.5, 0.2, 1.0),
|
||||||
|
widget::WidgetType::CustomDraw => drawing::Color::new(1.0, 1.0, 1.0, 1.0),
|
||||||
};
|
};
|
||||||
|
|
||||||
let line = format!(
|
let line = format!(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
use crate::{
|
||||||
|
components::{Component, bar_graph},
|
||||||
|
layout::WidgetID,
|
||||||
|
parser::{AttribPair, ParserContext, process_component, style::parse_style},
|
||||||
|
widget::ConstructEssentials,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn parse_component_bar_graph(
|
||||||
|
ctx: &mut ParserContext,
|
||||||
|
parent_id: WidgetID,
|
||||||
|
attribs: &[AttribPair],
|
||||||
|
tag_name: &str,
|
||||||
|
) -> anyhow::Result<WidgetID> {
|
||||||
|
let style = parse_style(ctx, attribs, tag_name);
|
||||||
|
let mut limit_min = 0.0;
|
||||||
|
let mut capacity = 50;
|
||||||
|
let mut limit_max = 100.0;
|
||||||
|
let mut unit = String::new();
|
||||||
|
|
||||||
|
for pair in attribs {
|
||||||
|
let (key, value) = (pair.attrib.as_ref(), pair.value.as_ref());
|
||||||
|
#[allow(clippy::single_match)]
|
||||||
|
match key {
|
||||||
|
"capacity" => {
|
||||||
|
ctx.parse_check_i32(tag_name, key, value, &mut capacity);
|
||||||
|
}
|
||||||
|
"limit_min" => {
|
||||||
|
ctx.parse_check_f32(tag_name, key, value, &mut limit_min);
|
||||||
|
}
|
||||||
|
"limit_max" => {
|
||||||
|
ctx.parse_check_f32(tag_name, key, value, &mut limit_max);
|
||||||
|
}
|
||||||
|
"unit" => {
|
||||||
|
unit = value.to_string();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let (widget, component) = bar_graph::construct(
|
||||||
|
&mut ConstructEssentials {
|
||||||
|
layout: ctx.layout,
|
||||||
|
parent: parent_id,
|
||||||
|
},
|
||||||
|
bar_graph::Params {
|
||||||
|
style,
|
||||||
|
limits: (limit_min, limit_max),
|
||||||
|
unit,
|
||||||
|
capacity: capacity.try_into().unwrap_or(50),
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
process_component(ctx, Component(component), widget.id, attribs);
|
||||||
|
|
||||||
|
Ok(widget.id)
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
mod component_bar_graph;
|
||||||
mod component_button;
|
mod component_button;
|
||||||
mod component_checkbox;
|
mod component_checkbox;
|
||||||
mod component_editbox;
|
mod component_editbox;
|
||||||
|
|
@ -21,6 +22,7 @@ use crate::{
|
||||||
layout::{Layout, LayoutParams, LayoutState, Widget, WidgetID, WidgetMap, WidgetPair},
|
layout::{Layout, LayoutParams, LayoutState, Widget, WidgetID, WidgetMap, WidgetPair},
|
||||||
log::LogErr,
|
log::LogErr,
|
||||||
parser::{
|
parser::{
|
||||||
|
component_bar_graph::parse_component_bar_graph,
|
||||||
component_button::parse_component_button,
|
component_button::parse_component_button,
|
||||||
component_checkbox::{CheckboxKind, parse_component_checkbox},
|
component_checkbox::{CheckboxKind, parse_component_checkbox},
|
||||||
component_editbox::parse_component_editbox,
|
component_editbox::parse_component_editbox,
|
||||||
|
|
@ -1056,6 +1058,7 @@ fn parse_child<'a>(
|
||||||
)?);
|
)?);
|
||||||
}
|
}
|
||||||
"EditBox" => new_widget_id = Some(parse_component_editbox(ctx, parent_id, &attribs, tag_name)?),
|
"EditBox" => new_widget_id = Some(parse_component_editbox(ctx, parent_id, &attribs, tag_name)?),
|
||||||
|
"BarGraph" => new_widget_id = Some(parse_component_bar_graph(ctx, parent_id, &attribs, tag_name)?),
|
||||||
"Tabs" => {
|
"Tabs" => {
|
||||||
new_widget_id = Some(parse_component_tabs(ctx, child_node, parent_id, &attribs, tag_name)?);
|
new_widget_id = Some(parse_component_tabs(ctx, child_node, parent_id, &attribs, tag_name)?);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ impl InnerAtlas {
|
||||||
// Grow each dimension by a factor of 2. The growth factor was chosen to match the growth
|
// Grow each dimension by a factor of 2. The growth factor was chosen to match the growth
|
||||||
// factor of `Vec`.`
|
// factor of `Vec`.`
|
||||||
let new_size = (self.size * GROWTH_FACTOR).min(self.max_texture_dimension_2d);
|
let new_size = (self.size * GROWTH_FACTOR).min(self.max_texture_dimension_2d);
|
||||||
log::info!("Grow {:?} atlas {} → {new_size}", self.kind, self.size);
|
log::debug!("Grow {:?} atlas {} → {new_size}", self.kind, self.size);
|
||||||
|
|
||||||
self.packer.grow(size2(new_size as i32, new_size as i32));
|
self.packer.grow(size2(new_size as i32, new_size as i32));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
use slotmap::Key;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
drawing::{self},
|
||||||
|
layout::WidgetID,
|
||||||
|
stack,
|
||||||
|
widget::WidgetStateFlags,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{WidgetObj, WidgetState};
|
||||||
|
|
||||||
|
pub struct CustomDrawArgs<'a> {
|
||||||
|
pub boundary: &'a drawing::Boundary,
|
||||||
|
pub transform: &'a stack::Transform,
|
||||||
|
pub primitives: &'a mut Vec<drawing::RenderPrimitive>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WidgetCustomDrawParams {
|
||||||
|
pub func: Box<dyn Fn(CustomDrawArgs)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: bring up a better name for this
|
||||||
|
pub struct WidgetCustomDraw {
|
||||||
|
pub params: WidgetCustomDrawParams,
|
||||||
|
id: WidgetID,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WidgetCustomDraw {
|
||||||
|
pub fn create(params: WidgetCustomDrawParams) -> WidgetState {
|
||||||
|
WidgetState::new(
|
||||||
|
WidgetStateFlags::default(),
|
||||||
|
Box::new(Self {
|
||||||
|
params,
|
||||||
|
id: WidgetID::null(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WidgetObj for WidgetCustomDraw {
|
||||||
|
fn draw(&mut self, state: &mut super::DrawState, _params: &super::DrawParams) {
|
||||||
|
let boundary = drawing::Boundary::construct_relative(state.transform_stack);
|
||||||
|
(*self.params.func)(CustomDrawArgs {
|
||||||
|
primitives: state.primitives,
|
||||||
|
boundary: &boundary,
|
||||||
|
transform: state.transform_stack.get(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_id(&self) -> WidgetID {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_id(&mut self, id: WidgetID) {
|
||||||
|
self.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_type(&self) -> super::WidgetType {
|
||||||
|
super::WidgetType::Rectangle
|
||||||
|
}
|
||||||
|
|
||||||
|
fn debug_print(&self) -> String {
|
||||||
|
String::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,7 @@ use crate::{
|
||||||
|
|
||||||
use super::{WidgetObj, WidgetState};
|
use super::{WidgetObj, WidgetState};
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct WidgetLabelParams {
|
pub struct WidgetLabelParams {
|
||||||
pub content: Translation,
|
pub content: Translation,
|
||||||
pub style: TextStyle,
|
pub style: TextStyle,
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ use crate::{
|
||||||
stack::{ScissorStack, TransformStack},
|
stack::{ScissorStack, TransformStack},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub mod custom_draw;
|
||||||
pub mod div;
|
pub mod div;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
pub mod label;
|
pub mod label;
|
||||||
|
|
@ -152,6 +153,7 @@ pub enum WidgetType {
|
||||||
Label,
|
Label,
|
||||||
Sprite,
|
Sprite,
|
||||||
Rectangle,
|
Rectangle,
|
||||||
|
CustomDraw,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WidgetType {
|
impl WidgetType {
|
||||||
|
|
@ -161,6 +163,7 @@ impl WidgetType {
|
||||||
WidgetType::Label => "label",
|
WidgetType::Label => "label",
|
||||||
WidgetType::Sprite => "sprite",
|
WidgetType::Sprite => "sprite",
|
||||||
WidgetType::Rectangle => "rectangle",
|
WidgetType::Rectangle => "rectangle",
|
||||||
|
WidgetType::CustomDraw => "custom_draw",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue