Update to imgui-rs 0.11.0.
Remove a lot of code 'temporarily' while we do some restructuring.
This commit is contained in:
parent
cdd3888446
commit
e6a6f67b4d
13 changed files with 13520 additions and 4963 deletions
275
Cargo.lock
generated
Normal file
275
Cargo.lock
generated
Normal file
|
@ -0,0 +1,275 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chlorine"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75476fe966a8af7c0ceae2a3e514afa87d4451741fcdfab8bfaa07ad301842ec"
|
||||
|
||||
[[package]]
|
||||
name = "imgui"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "122d677d0efcd64ca15f12907beaf46b26bbd2cdc855ee5b227f29cf50f75bb5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"imgui-sys",
|
||||
"mint",
|
||||
"parking_lot 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imgui-sys"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d785272a57cb8058a53a1e6f376f48e2ec4f40fbc6a9bb197dabf7b6b59c03bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"chlorine",
|
||||
"mint",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "implot"
|
||||
version = "0.11.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"imgui",
|
||||
"implot-sys",
|
||||
"parking_lot 0.11.2",
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "implot-sys"
|
||||
version = "0.11.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"imgui-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.148"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mint"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e53debba6bda7a793e5f99b8dacf19e626084f525f7829104ba9898f367d85ff"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||
dependencies = [
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core 0.8.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core 0.9.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall 0.2.16",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall 0.3.5",
|
||||
"smallvec",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "implot"
|
||||
version = "0.6.0"
|
||||
version = "0.11.0"
|
||||
edition = "2018"
|
||||
authors = ["Sandro Merkli", "implot-rs contributors"]
|
||||
description = "Rust bindings to https://github.com/epezent/implot"
|
||||
|
@ -11,8 +11,8 @@ categories = ["gui", "api-bindings"]
|
|||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
implot-sys = { version = "0.6.0", path = "implot-sys" }
|
||||
imgui = { version = "0.8.0" }
|
||||
implot-sys = { version = "0.11.0", path = "implot-sys" }
|
||||
imgui = { version = "0.11.0", features = ["docking"] }
|
||||
bitflags = "1.0"
|
||||
parking_lot = "0.11"
|
||||
rustversion = "1.0.4"
|
||||
|
|
380
implot-sys-bindgen/Cargo.lock
generated
Normal file
380
implot-sys-bindgen/Cargo.lock
generated
Normal file
|
@ -0,0 +1,380 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd4865004a46a0aafb2a0a5eb19d3c9fc46ee5f063a6cfc605c69ac9ecf5263d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"clap",
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"peeking_take_while",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chlorine"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75476fe966a8af7c0ceae2a3e514afa87d4451741fcdfab8bfaa07ad301842ec"
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "imgui-sys"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d785272a57cb8058a53a1e6f376f48e2ec4f40fbc6a9bb197dabf7b6b59c03bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"chlorine",
|
||||
"mint",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "implot-sys-bindgen"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"imgui-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.148"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
|
||||
|
||||
[[package]]
|
||||
name = "mint"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e53debba6bda7a793e5f99b8dacf19e626084f525f7829104ba9898f367d85ff"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "5.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "3.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
@ -6,4 +6,4 @@ edition = "2018"
|
|||
|
||||
[dependencies]
|
||||
bindgen = "0.57"
|
||||
imgui-sys = { version = "0.8.0" }
|
||||
imgui-sys = { version = "0.11.0", features = ["docking"] }
|
||||
|
|
|
@ -17,6 +17,8 @@ fn main() {
|
|||
env::var_os("DEP_IMGUI_THIRD_PARTY").expect("DEP_IMGUI_THIRD_PARTY not defined"),
|
||||
);
|
||||
|
||||
println!("{}", cimgui_include_path.display());
|
||||
|
||||
let bindings = Builder::default()
|
||||
.header(
|
||||
cimgui_include_path
|
||||
|
@ -34,21 +36,40 @@ fn main() {
|
|||
)
|
||||
.parse_callbacks(Box::new(CargoCallbacks))
|
||||
.clang_arg("-DCIMGUI_DEFINE_ENUMS_AND_STRUCTS=1")
|
||||
.clang_arg(format!("-I{}", cimgui_include_path.display()))
|
||||
// Reuse the imgui types that implot requires from imgui_sys so we don't define
|
||||
// our own new types.
|
||||
.raw_line("pub use imgui_sys::{ImVec2, ImVec4, ImGuiCond, ImTextureID};")
|
||||
.raw_line("pub use imgui_sys::{ImGuiContext, ImGuiKeyModFlags, ImDrawList};")
|
||||
.raw_line("pub use imgui_sys::{ImVec2, ImVector_ImU32, ImVec4, ImGuiCond, ImTextureID};")
|
||||
.raw_line("pub use imgui_sys::{ImGuiTextBuffer, ImGuiStorage, ImWchar, ImGuiTextRange};")
|
||||
.raw_line("pub use imgui_sys::{ImGuiStoragePair, ImDrawCmd, *};")
|
||||
.raw_line("pub use imgui_sys::{ImGuiContext, ImGuiKey, ImDrawList};")
|
||||
.raw_line("pub use imgui_sys::{ImGuiMouseButton, ImGuiDragDropFlags};")
|
||||
.raw_line("use libc::time_t;")
|
||||
.whitelist_recursively(false)
|
||||
.whitelist_function("ImPlot.*")
|
||||
.whitelist_type("ImPlot.*")
|
||||
// We do want to create bindings for the scalar typedefs
|
||||
.whitelist_type("Im[U|S][0-9]{1,2}")
|
||||
.whitelist_type("ImAxis")
|
||||
.whitelist_var("ImAxis_")
|
||||
.whitelist_type("ImPool_.+")
|
||||
.whitelist_type("ImVector_.+")
|
||||
.whitelist_type("tm")
|
||||
// Remove some functions that would take a variable-argument list
|
||||
.blacklist_function("ImPlot_AnnotateVVec4")
|
||||
.blacklist_function("ImPlot_AnnotateVStr")
|
||||
.blacklist_function("ImPlot_AnnotateClampedVVec4")
|
||||
.blacklist_function("ImPlot_AnnotateClampedVStr")
|
||||
.blacklist_type("ImVector_ImU32")
|
||||
.blacklist_function("ImPlot_MkGmtTime")
|
||||
.blacklist_function("ImPlot_GetGmtTime")
|
||||
.blacklist_function("ImPlot_MkLocTime")
|
||||
.blacklist_function("ImPlot_GetLocTime")
|
||||
.blacklist_function("ImPlot_AnnotationV")
|
||||
.blacklist_function("ImPlot_TagXV")
|
||||
.blacklist_function("ImPlot_TagYV")
|
||||
.blacklist_function("ImPlotAnnotationCollection_AppendV")
|
||||
.blacklist_function("ImPlotTagCollection_AppendV")
|
||||
.generate()
|
||||
.expect("Unable to generate bindings");
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "implot-sys"
|
||||
version = "0.6.0"
|
||||
version = "0.11.0"
|
||||
edition = "2018"
|
||||
authors = ["Sandro Merkli", "implot-rs contributors"]
|
||||
description = "Raw FFI bindings to implot"
|
||||
|
@ -12,7 +12,8 @@ build = "build.rs"
|
|||
links = "implot"
|
||||
|
||||
[dependencies]
|
||||
imgui-sys = "0.8.0"
|
||||
imgui-sys = { version = "0.11.0", features = ["docking"] }
|
||||
libc = "0.2.148"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
|
|
11093
implot-sys/src/bindings.rs
generated
11093
implot-sys/src/bindings.rs
generated
File diff suppressed because it is too large
Load diff
2
implot-sys/third-party/cimplot
vendored
2
implot-sys/third-party/cimplot
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 374317a84121a01868aa5274dbcf1c5a5df96e8c
|
||||
Subproject commit 82d498a5bf0d945b1db21c80ba3ce69350930022
|
182
src/lib.rs
182
src/lib.rs
|
@ -16,16 +16,18 @@
|
|||
//! the C++ name - some doc aliases are defined to increase the chances of that working. If this
|
||||
//! does not yield any results, you can also try cloning the source and doing a full-text search to
|
||||
//! see if the feature is used somewhere internally the code.
|
||||
use implot_sys as sys;
|
||||
pub use implot_sys as sys;
|
||||
|
||||
// TODO(4bb4) facade-wrap these?
|
||||
pub use self::{context::*, plot::*, plot_elements::*};
|
||||
use std::os::raw::c_char;
|
||||
pub use sys::{ImPlotLimits, ImPlotPoint, ImPlotRange, ImVec2, ImVec4};
|
||||
pub use sys::{ImAxis, ImPlotPoint, ImPlotRange, ImPlotRect, ImVec2, ImVec4};
|
||||
|
||||
mod context;
|
||||
pub mod lines;
|
||||
mod plot;
|
||||
mod plot_elements;
|
||||
pub mod rect;
|
||||
|
||||
// The bindings for some reason don't contain this - it has to match the IMPLOT_AUTO from
|
||||
// the original C++ header for things to work properly.
|
||||
|
@ -41,23 +43,6 @@ const NUMBER_OF_Y_AXES: usize = 3;
|
|||
// Implementation note: This enum is converted straight to an usize index in a few places
|
||||
// so we can store data about individual axes in arrays, so this pretty much should stay
|
||||
// just a mapping of words to numbers.
|
||||
#[rustversion::attr(since(1.48), doc(alias = "ImPlotYAxis"))]
|
||||
#[derive(Clone)]
|
||||
#[repr(u32)]
|
||||
pub enum YAxisChoice {
|
||||
First = sys::ImPlotYAxis__ImPlotYAxis_1,
|
||||
Second = sys::ImPlotYAxis__ImPlotYAxis_2,
|
||||
Third = sys::ImPlotYAxis__ImPlotYAxis_3,
|
||||
}
|
||||
|
||||
/// Turn an Option<YAxisChoice> into an i32. Picks IMPLOT_AUTO for None.
|
||||
#[rustversion::attr(since(1.48), doc(alias = "IMPLOT_AUTO"))]
|
||||
fn y_axis_choice_option_to_i32(y_axis_choice: Option<YAxisChoice>) -> i32 {
|
||||
match y_axis_choice {
|
||||
Some(choice) => choice as i32,
|
||||
None => IMPLOT_AUTO,
|
||||
}
|
||||
}
|
||||
|
||||
/// A temporary reference for building plots. This does not really do anything on its own at
|
||||
/// this point, but it is used to enforce that a context is created and active for other features,
|
||||
|
@ -130,27 +115,12 @@ pub enum PlotColorElement {
|
|||
/// Color of text appearing inside of plots (defaults to ImGuiCol_Text)
|
||||
InlayText = sys::ImPlotCol__ImPlotCol_InlayText,
|
||||
/// X-axis label and tick lables color (defaults to ImGuiCol_Text)
|
||||
XAxis = sys::ImPlotCol__ImPlotCol_XAxis,
|
||||
AxisBg = sys::ImPlotCol__ImPlotCol_AxisBg,
|
||||
/// X-axis grid color (defaults to 25% ImPlotCol_XAxis)
|
||||
XAxisGrid = sys::ImPlotCol__ImPlotCol_XAxisGrid,
|
||||
/// Y-axis label and tick labels color (defaults to ImGuiCol_Text)
|
||||
YAxis = sys::ImPlotCol__ImPlotCol_YAxis,
|
||||
/// Y-axis grid color (defaults to 25% ImPlotCol_YAxis)
|
||||
YAxisGrid = sys::ImPlotCol__ImPlotCol_YAxisGrid,
|
||||
/// 2nd y-axis label and tick labels color (defaults to ImGuiCol_Text)
|
||||
YAxis2 = sys::ImPlotCol__ImPlotCol_YAxis2,
|
||||
/// 2nd y-axis grid/label color (defaults to 25% ImPlotCol_YAxis2)
|
||||
YAxisGrid2 = sys::ImPlotCol__ImPlotCol_YAxisGrid2,
|
||||
/// 3rd y-axis label and tick labels color (defaults to ImGuiCol_Text)
|
||||
YAxis3 = sys::ImPlotCol__ImPlotCol_YAxis3,
|
||||
/// 3rd y-axis grid/label color (defaults to 25% ImPlotCol_YAxis3)
|
||||
YAxisGrid3 = sys::ImPlotCol__ImPlotCol_YAxisGrid3,
|
||||
/// Box-selection color (defaults to yellow)
|
||||
AxisBgHovered = sys::ImPlotCol__ImPlotCol_AxisBgHovered,
|
||||
AxisBgActive = sys::ImPlotCol__ImPlotCol_AxisBgActive,
|
||||
Selection = sys::ImPlotCol__ImPlotCol_Selection,
|
||||
/// crosshairs color (defaults to ImPlotCol_PlotBorder)
|
||||
Crosshairs = sys::ImPlotCol__ImPlotCol_Crosshairs,
|
||||
/// Box-query color (defaults to green)
|
||||
Query = sys::ImPlotCol__ImPlotCol_Query,
|
||||
}
|
||||
|
||||
/// Colormap choice. Documentation copied from implot.h for convenience.
|
||||
|
@ -158,8 +128,6 @@ pub enum PlotColorElement {
|
|||
#[repr(u32)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum Colormap {
|
||||
/// ImPlot default colormap (n=10). Called "Standard" here because Default is reserved.
|
||||
Standard = sys::ImPlotColormap__ImPlotColormap_Default,
|
||||
/// a.k.a. seaborn deep (n=10)
|
||||
Deep = sys::ImPlotColormap__ImPlotColormap_Deep,
|
||||
/// a.k.a. matplotlib "Set1" (n=9)
|
||||
|
@ -269,35 +237,6 @@ pub enum PlotLocation {
|
|||
SouthEast = sys::ImPlotLocation__ImPlotLocation_SouthEast,
|
||||
}
|
||||
|
||||
#[rustversion::attr(since(1.48), doc(alias = "ImPlotOrientation"))]
|
||||
/// Used to orient items on a plot (e.g. legends, labels, etc.)
|
||||
#[repr(u32)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum PlotOrientation {
|
||||
Horizontal = sys::ImPlotOrientation__ImPlotOrientation_Horizontal,
|
||||
Vertical = sys::ImPlotOrientation__ImPlotOrientation_Vertical,
|
||||
}
|
||||
|
||||
/// Switch to one of the built-in preset colormaps. If samples is greater than 1, the map will be
|
||||
/// linearly resampled.
|
||||
#[rustversion::attr(since(1.48), doc(alias = "SetColormap"))]
|
||||
pub fn set_colormap_from_preset(preset: Colormap, samples: u32) {
|
||||
unsafe {
|
||||
// "as" casts saturate as of Rust 1.45. This is safe here, and at least the enum
|
||||
// values are not expected to go outside the range of an i32 anyway, so there is no
|
||||
// risk of changed values.
|
||||
sys::ImPlot_SetColormapPlotColormap(preset as i32, samples as i32);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set a custom colormap in the form of a vector of colors.
|
||||
#[rustversion::attr(since(1.48), doc(alias = "SetColormap"))]
|
||||
pub fn set_colormap_from_vec(colors: Vec<ImVec4>) {
|
||||
unsafe {
|
||||
sys::ImPlot_SetColormapVec4Ptr(colors.as_ptr(), colors.len() as i32);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Push/pop utils -------------------------------------------------------------------------
|
||||
// Currently not in a struct yet. imgui-rs has some smarts about dealing with stacks, in particular
|
||||
// leak detection, which I'd like to replicate here at some point.
|
||||
|
@ -319,7 +258,7 @@ pub fn push_style_color(
|
|||
alpha: f32,
|
||||
) -> StyleColorToken {
|
||||
unsafe {
|
||||
sys::ImPlot_PushStyleColorVec4(
|
||||
sys::ImPlot_PushStyleColor_Vec4(
|
||||
*element as sys::ImPlotCol,
|
||||
sys::ImVec4 {
|
||||
x: red,
|
||||
|
@ -362,7 +301,7 @@ impl StyleColorToken {
|
|||
#[rustversion::attr(since(1.48), doc(alias = "PushStyleVar"))]
|
||||
pub fn push_style_var_f32(element: &StyleVar, value: f32) -> StyleVarToken {
|
||||
unsafe {
|
||||
sys::ImPlot_PushStyleVarFloat(*element as sys::ImPlotStyleVar, value);
|
||||
sys::ImPlot_PushStyleVar_Float(*element as sys::ImPlotStyleVar, value);
|
||||
}
|
||||
StyleVarToken { was_popped: false }
|
||||
}
|
||||
|
@ -378,7 +317,7 @@ pub fn push_style_var_f32(element: &StyleVar, value: f32) -> StyleVarToken {
|
|||
#[rustversion::attr(since(1.48), doc(alias = "PushStyleVar"))]
|
||||
pub fn push_style_var_i32(element: &StyleVar, value: i32) -> StyleVarToken {
|
||||
unsafe {
|
||||
sys::ImPlot_PushStyleVarInt(*element as sys::ImPlotStyleVar, value);
|
||||
sys::ImPlot_PushStyleVar_Int(*element as sys::ImPlotStyleVar, value);
|
||||
}
|
||||
StyleVarToken { was_popped: false }
|
||||
}
|
||||
|
@ -387,7 +326,7 @@ pub fn push_style_var_i32(element: &StyleVar, value: i32) -> StyleVarToken {
|
|||
/// the variable from the stack again.
|
||||
pub fn push_style_var_imvec2(element: &StyleVar, value: ImVec2) -> StyleVarToken {
|
||||
unsafe {
|
||||
sys::ImPlot_PushStyleVarVec2(*element as sys::ImPlotStyleVar, value);
|
||||
sys::ImPlot_PushStyleVar_Vec2(*element as sys::ImPlotStyleVar, value);
|
||||
}
|
||||
StyleVarToken { was_popped: false }
|
||||
}
|
||||
|
@ -419,21 +358,14 @@ pub fn is_plot_hovered() -> bool {
|
|||
unsafe { sys::ImPlot_IsPlotHovered() }
|
||||
}
|
||||
|
||||
/// Returns true if the current or most recent plot is queried
|
||||
#[rustversion::attr(since(1.48), doc(alias = "IsPlotQueried"))]
|
||||
pub fn is_plot_queried() -> bool {
|
||||
unsafe { sys::ImPlot_IsPlotQueried() }
|
||||
}
|
||||
|
||||
/// Returns the mouse position in x,y coordinates of the current or most recent plot,
|
||||
/// for the specified choice of Y axis. If `None` is the Y axis choice, that means the
|
||||
/// most recently selected Y axis is chosen.
|
||||
#[rustversion::attr(since(1.48), doc(alias = "GetPlotMousePos"))]
|
||||
pub fn get_plot_mouse_position(y_axis_choice: Option<YAxisChoice>) -> ImPlotPoint {
|
||||
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||
pub fn get_plot_mouse_position(x: ImAxis, y: ImAxis) -> ImPlotPoint {
|
||||
let mut point = ImPlotPoint { x: 0.0, y: 0.0 }; // doesn't seem to have default()
|
||||
unsafe {
|
||||
sys::ImPlot_GetPlotMousePos(&mut point as *mut ImPlotPoint, y_axis_choice_i32);
|
||||
sys::ImPlot_GetPlotMousePos(&mut point as *mut ImPlotPoint, x, y);
|
||||
}
|
||||
point
|
||||
}
|
||||
|
@ -441,18 +373,10 @@ pub fn get_plot_mouse_position(y_axis_choice: Option<YAxisChoice>) -> ImPlotPoin
|
|||
/// Convert pixels, given as an `ImVec2`, to a position in the current plot's coordinate system.
|
||||
/// Uses the specified Y axis, if any, otherwise whatever was previously chosen.
|
||||
#[rustversion::attr(since(1.48), doc(alias = "PixelsToPlot"))]
|
||||
pub fn pixels_to_plot_vec2(
|
||||
pixel_position: &ImVec2,
|
||||
y_axis_choice: Option<YAxisChoice>,
|
||||
) -> ImPlotPoint {
|
||||
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||
pub fn pixels_to_plot_vec2(pixel_position: &ImVec2, x: ImAxis, y: ImAxis) -> ImPlotPoint {
|
||||
let mut point = ImPlotPoint { x: 0.0, y: 0.0 }; // doesn't seem to have default()
|
||||
unsafe {
|
||||
sys::ImPlot_PixelsToPlotVec2(
|
||||
&mut point as *mut ImPlotPoint,
|
||||
*pixel_position,
|
||||
y_axis_choice_i32,
|
||||
);
|
||||
sys::ImPlot_PixelsToPlot_Vec2(&mut point as *mut ImPlotPoint, *pixel_position, x, y);
|
||||
}
|
||||
point
|
||||
}
|
||||
|
@ -463,16 +387,17 @@ pub fn pixels_to_plot_vec2(
|
|||
pub fn pixels_to_plot_f32(
|
||||
pixel_position_x: f32,
|
||||
pixel_position_y: f32,
|
||||
y_axis_choice: Option<YAxisChoice>,
|
||||
x: ImAxis,
|
||||
y: ImAxis,
|
||||
) -> ImPlotPoint {
|
||||
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||
let mut point = ImPlotPoint { x: 0.0, y: 0.0 }; // doesn't seem to have default()
|
||||
unsafe {
|
||||
sys::ImPlot_PixelsToPlotFloat(
|
||||
sys::ImPlot_PixelsToPlot_Float(
|
||||
&mut point as *mut ImPlotPoint,
|
||||
pixel_position_x,
|
||||
pixel_position_y,
|
||||
y_axis_choice_i32,
|
||||
x,
|
||||
y,
|
||||
);
|
||||
}
|
||||
point
|
||||
|
@ -482,17 +407,14 @@ pub fn pixels_to_plot_f32(
|
|||
/// axis, if any, otherwise whatever was previously chosen.
|
||||
///
|
||||
#[rustversion::attr(since(1.48), doc(alias = "PlotToPixels"))]
|
||||
pub fn plot_to_pixels_vec2(
|
||||
plot_position: &ImPlotPoint,
|
||||
y_axis_choice: Option<YAxisChoice>,
|
||||
) -> ImVec2 {
|
||||
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||
pub fn plot_to_pixels_vec2(plot_position: &ImPlotPoint, x_axis: ImAxis, y_axis: ImAxis) -> ImVec2 {
|
||||
let mut pixel_position = ImVec2 { x: 0.0, y: 0.0 }; // doesn't seem to have default()
|
||||
unsafe {
|
||||
sys::ImPlot_PlotToPixelsPlotPoInt(
|
||||
sys::ImPlot_PlotToPixels_PlotPoInt(
|
||||
&mut pixel_position as *mut ImVec2,
|
||||
*plot_position,
|
||||
y_axis_choice_i32,
|
||||
x_axis,
|
||||
y_axis,
|
||||
);
|
||||
}
|
||||
pixel_position
|
||||
|
@ -504,16 +426,17 @@ pub fn plot_to_pixels_vec2(
|
|||
pub fn plot_to_pixels_f32(
|
||||
plot_position_x: f64,
|
||||
plot_position_y: f64,
|
||||
y_axis_choice: Option<YAxisChoice>,
|
||||
x_axis: ImAxis,
|
||||
y_axis: ImAxis,
|
||||
) -> ImVec2 {
|
||||
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||
let mut pixel_position = ImVec2 { x: 0.0, y: 0.0 }; // doesn't seem to have default()
|
||||
unsafe {
|
||||
sys::ImPlot_PlotToPixelsdouble(
|
||||
sys::ImPlot_PlotToPixels_double(
|
||||
&mut pixel_position as *mut ImVec2,
|
||||
plot_position_x,
|
||||
plot_position_y,
|
||||
y_axis_choice_i32,
|
||||
x_axis,
|
||||
y_axis,
|
||||
);
|
||||
}
|
||||
pixel_position
|
||||
|
@ -522,57 +445,18 @@ pub fn plot_to_pixels_f32(
|
|||
/// Returns the current or most recent plot axis range for the specified choice of Y axis. If
|
||||
/// `None` is the Y axis choice, that means the most recently selected Y axis is chosen.
|
||||
#[rustversion::attr(since(1.48), doc(alias = "GetPlotLimits"))]
|
||||
pub fn get_plot_limits(y_axis_choice: Option<YAxisChoice>) -> ImPlotLimits {
|
||||
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||
// ImPlotLimits doesn't seem to have default()
|
||||
let mut limits = ImPlotLimits {
|
||||
pub fn get_plot_limits(x: ImAxis, y: ImAxis) -> ImPlotRect {
|
||||
// ImPlotRect doesn't seem to have default()
|
||||
let mut limits = ImPlotRect {
|
||||
X: ImPlotRange { Min: 0.0, Max: 0.0 },
|
||||
Y: ImPlotRange { Min: 0.0, Max: 0.0 },
|
||||
};
|
||||
unsafe {
|
||||
sys::ImPlot_GetPlotLimits(&mut limits as *mut ImPlotLimits, y_axis_choice_i32);
|
||||
sys::ImPlot_GetPlotLimits(&mut limits as *mut ImPlotRect, x, y);
|
||||
}
|
||||
limits
|
||||
}
|
||||
|
||||
/// Returns the query limits of the current or most recent plot, for the specified choice of Y
|
||||
/// axis. If `None` is the Y axis choice, that means the most recently selected Y axis is chosen.
|
||||
#[rustversion::attr(since(1.48), doc(alias = "GetPlotQuery"))]
|
||||
pub fn get_plot_query(y_axis_choice: Option<YAxisChoice>) -> ImPlotLimits {
|
||||
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||
// ImPlotLimits doesn't seem to have default()
|
||||
let mut limits = ImPlotLimits {
|
||||
X: ImPlotRange { Min: 0.0, Max: 0.0 },
|
||||
Y: ImPlotRange { Min: 0.0, Max: 0.0 },
|
||||
};
|
||||
unsafe {
|
||||
sys::ImPlot_GetPlotQuery(&mut limits as *mut ImPlotLimits, y_axis_choice_i32);
|
||||
}
|
||||
limits
|
||||
}
|
||||
|
||||
/// Set the Y axis to be used for any upcoming plot elements
|
||||
#[rustversion::attr(since(1.48), doc(alias = "SetPlotYAxis"))]
|
||||
pub fn set_plot_y_axis(y_axis_choice: YAxisChoice) {
|
||||
unsafe {
|
||||
sys::ImPlot_SetPlotYAxis(y_axis_choice as i32);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the XAxis plot area in the current plot is hovered.
|
||||
#[rustversion::attr(since(1.48), doc(alias = "IsPlotXAxisHovered"))]
|
||||
pub fn is_plot_x_axis_hovered() -> bool {
|
||||
unsafe { sys::ImPlot_IsPlotXAxisHovered() }
|
||||
}
|
||||
|
||||
/// Returns true if the Y axis area of the given Y axis choice in the current plot is hovered. If
|
||||
/// `None` is the Y axis choice, that means the most recently selected Y axis is chosen.
|
||||
#[rustversion::attr(since(1.48), doc(alias = "IsPlotYAxisHovered"))]
|
||||
pub fn is_plot_y_axis_hovered(y_axis_choice: Option<YAxisChoice>) -> bool {
|
||||
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||
unsafe { sys::ImPlot_IsPlotYAxisHovered(y_axis_choice_i32) }
|
||||
}
|
||||
|
||||
/// Returns true if the given item in the legend of the current plot is hovered.
|
||||
pub fn is_legend_entry_hovered(legend_entry: &str) -> bool {
|
||||
unsafe { sys::ImPlot_IsLegendEntryHovered(legend_entry.as_ptr() as *const c_char) }
|
||||
|
|
36
src/lines.rs
Normal file
36
src/lines.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
use crate::sys;
|
||||
use std::ffi::CString;
|
||||
use std::os::raw::c_char;
|
||||
|
||||
pub use crate::sys::ImPlotPoint;
|
||||
|
||||
pub struct PlotLine {
|
||||
label: CString,
|
||||
}
|
||||
|
||||
impl PlotLine {
|
||||
pub fn new(label: &str) -> Self {
|
||||
Self {
|
||||
label: CString::new(label)
|
||||
.unwrap_or_else(|_| panic!("label string has internal null bytes: {}", label)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn plot(&self, x: &[f64], y: &[f64]) {
|
||||
if x.len().min(y.len()) == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
sys::ImPlot_PlotLine_doublePtrdoublePtr(
|
||||
self.label.as_ptr() as *const c_char,
|
||||
x.as_ptr(),
|
||||
y.as_ptr(),
|
||||
x.len().min(y.len()) as i32,
|
||||
0,
|
||||
0,
|
||||
std::mem::size_of::<f64>() as i32,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
659
src/plot.rs
659
src/plot.rs
|
@ -1,625 +1,141 @@
|
|||
//! # Plot module
|
||||
//!
|
||||
//! This module defines the `Plot` struct, which is used to create a 2D plot that will
|
||||
//! contain all other objects that can be created using this library.
|
||||
use crate::{Context, PlotLocation, PlotOrientation, PlotUi, YAxisChoice, NUMBER_OF_Y_AXES};
|
||||
use bitflags::bitflags;
|
||||
pub use imgui::Condition;
|
||||
use implot_sys as sys;
|
||||
use std::ffi::CString;
|
||||
use std::os::raw::c_char;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
pub use sys::{ImPlotLimits, ImPlotPoint, ImPlotRange, ImVec2, ImVec4};
|
||||
|
||||
use bitflags::bitflags;
|
||||
use implot_sys as sys;
|
||||
use sys::{ImAxis, ImVec2, *};
|
||||
|
||||
use crate::{Context, PlotUi};
|
||||
|
||||
const DEFAULT_PLOT_SIZE_X: f32 = 400.0;
|
||||
const DEFAULT_PLOT_SIZE_Y: f32 = 400.0;
|
||||
|
||||
#[rustversion::attr(since(1.48), doc(alias = "ImPlotFlags"))]
|
||||
pub enum Axis {
|
||||
X1 = 0,
|
||||
X2 = 1,
|
||||
X3 = 2,
|
||||
Y1 = 3,
|
||||
Y2 = 4,
|
||||
Y3 = 5,
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
/// Flags for customizing plot behavior and interaction. Documentation copied from implot.h for
|
||||
/// convenience. ImPlot itself also has a "CanvasOnly" flag, which can be emulated here with
|
||||
/// the combination of `NO_LEGEND`, `NO_MENUS`, `NO_BOX_SELECT` and `NO_MOUSE_POSITION`.
|
||||
#[repr(transparent)]
|
||||
pub struct PlotFlags: u32 {
|
||||
/// "Default" according to original docs
|
||||
const NONE = sys::ImPlotFlags__ImPlotFlags_None;
|
||||
/// Plot items will not be highlighted when their legend entry is hovered
|
||||
const NO_LEGEND = sys::ImPlotFlags__ImPlotFlags_NoLegend;
|
||||
/// The user will not be able to open context menus with double-right click
|
||||
const NO_MENUS = sys::ImPlotFlags__ImPlotFlags_NoMenus;
|
||||
/// The user will not be able to box-select with right-mouse
|
||||
const NO_BOX_SELECT = sys::ImPlotFlags__ImPlotFlags_NoBoxSelect;
|
||||
/// The mouse position, in plot coordinates, will not be displayed
|
||||
const NO_MOUSE_POSITION = sys::ImPlotFlags__ImPlotFlags_NoMousePos;
|
||||
/// Plot items will not be highlighted when their legend entry is hovered
|
||||
const NO_HIGHLIGHT = sys::ImPlotFlags__ImPlotFlags_NoHighlight;
|
||||
/// A child window region will not be used to capture mouse scroll (can boost performance
|
||||
/// for single ImGui window applications)
|
||||
const NO_CHILD = sys::ImPlotFlags__ImPlotFlags_NoChild;
|
||||
/// Use an aspect ratio of 1:1 for the plot
|
||||
const AXIS_EQUAL = sys::ImPlotFlags__ImPlotFlags_Equal;
|
||||
/// Enable a 2nd y axis
|
||||
const Y_AXIS_2 = sys::ImPlotFlags__ImPlotFlags_YAxis2;
|
||||
/// Enable a 3nd y axis
|
||||
const Y_AXIS_3 = sys::ImPlotFlags__ImPlotFlags_YAxis3;
|
||||
/// The user will be able to draw query rects with middle-mouse
|
||||
const QUERY = sys::ImPlotFlags__ImPlotFlags_Query;
|
||||
/// The default mouse cursor will be replaced with a crosshair when hovered
|
||||
const CROSSHAIRS = sys::ImPlotFlags__ImPlotFlags_Crosshairs;
|
||||
/// Plot data outside the plot area will be culled from rendering
|
||||
const ANTIALIASED = sys::ImPlotFlags__ImPlotFlags_AntiAliased;
|
||||
const NONE = ImPlotFlags__ImPlotFlags_None;
|
||||
const NOTITLE = ImPlotFlags__ImPlotFlags_NoTitle;
|
||||
const NOLEGEND = ImPlotFlags__ImPlotFlags_NoLegend;
|
||||
const NOMOUSETEXT = ImPlotFlags__ImPlotFlags_NoMouseText;
|
||||
const NOINPUTS = ImPlotFlags__ImPlotFlags_NoInputs;
|
||||
const NOMENUS = ImPlotFlags__ImPlotFlags_NoMenus;
|
||||
const NOBOXSELECT = ImPlotFlags__ImPlotFlags_NoBoxSelect;
|
||||
const NOCHILD = ImPlotFlags__ImPlotFlags_NoChild;
|
||||
const NOFRAME = ImPlotFlags__ImPlotFlags_NoFrame;
|
||||
const EQUAL = ImPlotFlags__ImPlotFlags_Equal;
|
||||
const CROSSHAIRS = ImPlotFlags__ImPlotFlags_Crosshairs;
|
||||
const CANVASONLY = ImPlotFlags__ImPlotFlags_CanvasOnly;
|
||||
}
|
||||
}
|
||||
|
||||
#[rustversion::attr(since(1.48), doc(alias = "ImPlotAxisFlags"))]
|
||||
bitflags! {
|
||||
/// Axis flags. Documentation copied from implot.h for convenience. ImPlot itself also
|
||||
/// has `Lock`, which combines `LOCK_MIN` and `LOCK_MAX`, and `NoDecorations`, which combines
|
||||
/// `NO_GRID_LINES`, `NO_TICK_MARKS` and `NO_TICK_LABELS`.
|
||||
#[repr(transparent)]
|
||||
pub struct AxisFlags: u32 {
|
||||
/// "Default" according to original docs
|
||||
const NONE = sys::ImPlotAxisFlags__ImPlotAxisFlags_None;
|
||||
/// Grid lines will not be displayed
|
||||
const NO_GRID_LINES = sys::ImPlotAxisFlags__ImPlotAxisFlags_NoGridLines;
|
||||
/// Tick marks will not be displayed
|
||||
const NO_TICK_MARKS = sys::ImPlotAxisFlags__ImPlotAxisFlags_NoTickMarks;
|
||||
/// Text labels will not be displayed
|
||||
const NO_TICK_LABELS = sys::ImPlotAxisFlags__ImPlotAxisFlags_NoTickLabels;
|
||||
/// A logartithmic (base 10) axis scale will be used (mutually exclusive with AxisFlags::TIME)
|
||||
const LOG_SCALE = sys::ImPlotAxisFlags__ImPlotAxisFlags_LogScale;
|
||||
/// Axis will display date/time formatted labels (mutually exclusive with AxisFlags::LOG_SCALE)
|
||||
const TIME = sys::ImPlotAxisFlags__ImPlotAxisFlags_Time;
|
||||
/// The axis will be inverted
|
||||
const INVERT = sys::ImPlotAxisFlags__ImPlotAxisFlags_Invert;
|
||||
/// The axis minimum value will be locked when panning/zooming
|
||||
const LOCK_MIN = sys::ImPlotAxisFlags__ImPlotAxisFlags_LockMin;
|
||||
/// The axis maximum value will be locked when panning/zooming
|
||||
const LOCK_MAX = sys::ImPlotAxisFlags__ImPlotAxisFlags_LockMax;
|
||||
pub struct PlotAxisFlags: u32 {
|
||||
const NONE = ImPlotAxisFlags__ImPlotAxisFlags_None;
|
||||
const NO_LABEL = ImPlotAxisFlags__ImPlotAxisFlags_NoLabel;
|
||||
const NO_GRID_LINES = ImPlotAxisFlags__ImPlotAxisFlags_NoGridLines;
|
||||
const NO_TICK_MARKS = ImPlotAxisFlags__ImPlotAxisFlags_NoTickMarks;
|
||||
const NO_TICK_LABELS = ImPlotAxisFlags__ImPlotAxisFlags_NoTickLabels;
|
||||
const NO_INITIAL_FIT = ImPlotAxisFlags__ImPlotAxisFlags_NoInitialFit;
|
||||
const NO_MENUS = ImPlotAxisFlags__ImPlotAxisFlags_NoMenus;
|
||||
const NO_SIDESWITCH = ImPlotAxisFlags__ImPlotAxisFlags_NoSideSwitch;
|
||||
const NO_HIGHLIGHT = ImPlotAxisFlags__ImPlotAxisFlags_NoHighlight;
|
||||
const OPPOSITE = ImPlotAxisFlags__ImPlotAxisFlags_Opposite;
|
||||
const FOREGROUND = ImPlotAxisFlags__ImPlotAxisFlags_Foreground;
|
||||
const INVERT = ImPlotAxisFlags__ImPlotAxisFlags_Invert;
|
||||
const AUTO_FIT = ImPlotAxisFlags__ImPlotAxisFlags_AutoFit;
|
||||
const RANGE_FIT = ImPlotAxisFlags__ImPlotAxisFlags_RangeFit;
|
||||
const PAN_STRETCH = ImPlotAxisFlags__ImPlotAxisFlags_PanStretch;
|
||||
const LOCK_MIN = ImPlotAxisFlags__ImPlotAxisFlags_LockMin;
|
||||
const LOCK_MAX = ImPlotAxisFlags__ImPlotAxisFlags_LockMax;
|
||||
const LOCK = ImPlotAxisFlags__ImPlotAxisFlags_Lock;
|
||||
const NO_DECORATIONS = ImPlotAxisFlags__ImPlotAxisFlags_NoDecorations;
|
||||
const AUX_DEFAULT = ImPlotAxisFlags__ImPlotAxisFlags_AuxDefault;
|
||||
}
|
||||
}
|
||||
|
||||
/// Internally-used struct for storing axis limits
|
||||
#[derive(Clone)]
|
||||
enum AxisLimitSpecification {
|
||||
/// Direct limits, specified as values
|
||||
Single(ImPlotRange, Condition),
|
||||
/// Limits that are linked to limits of other plots (via clones of the same Rc)
|
||||
Linked(Rc<RefCell<ImPlotRange>>),
|
||||
}
|
||||
|
||||
/// Struct to represent an ImPlot. This is the main construct used to contain all kinds of plots in ImPlot.
|
||||
///
|
||||
/// `Plot` is to be used (within an imgui window) with the following pattern:
|
||||
/// ```no_run
|
||||
/// # use implot;
|
||||
/// let plotting_context = implot::Context::create();
|
||||
/// let plot_ui = plotting_context.get_plot_ui();
|
||||
/// implot::Plot::new("my title")
|
||||
/// .size([300.0, 200.0]) // other things such as .x_label("some_label") can be added too
|
||||
/// .build(&plot_ui, || {
|
||||
/// // Do things such as plotting lines
|
||||
/// });
|
||||
///
|
||||
/// ```
|
||||
/// (If you are coming from the C++ implementation or the C bindings: build() calls both
|
||||
/// begin() and end() internally)
|
||||
pub struct Plot {
|
||||
/// Title of the plot, shown on top. Stored as CString because that's what we'll use
|
||||
/// afterwards, and this ensures the CString itself will stay alive long enough for the plot.
|
||||
title: CString,
|
||||
/// Size of the plot in [x, y] direction, in the same units imgui uses.
|
||||
size: [f32; 2],
|
||||
/// Label of the x axis, shown on the bottom. Stored as CString because that's what we'll use
|
||||
/// afterwards, and this ensures the CString itself will stay alive long enough for the plot.
|
||||
x_label: CString,
|
||||
/// Label of the y axis, shown on the left. Stored as CString because that's what we'll use
|
||||
/// afterwards, and this ensures the CString itself will stay alive long enough for the plot.
|
||||
y_label: CString,
|
||||
/// X axis limits, if present
|
||||
x_limits: Option<AxisLimitSpecification>,
|
||||
/// Y axis limits, if present
|
||||
y_limits: [Option<AxisLimitSpecification>; NUMBER_OF_Y_AXES],
|
||||
/// Positions for custom X axis ticks, if any
|
||||
x_tick_positions: Option<Vec<f64>>,
|
||||
/// Labels for custom X axis ticks, if any. I'd prefer to store these together
|
||||
/// with the positions in one vector of an algebraic data type, but this would mean extra
|
||||
/// copies when it comes time to draw the plot because the C++ library expects separate lists.
|
||||
/// The data is stored as CStrings because those are null-terminated, and since we have to
|
||||
/// convert to null-terminated data anyway, we may as well do that directly instead of cloning
|
||||
/// Strings and converting them afterwards.
|
||||
x_tick_labels: Option<Vec<CString>>,
|
||||
/// Whether to also show the default X ticks when showing custom ticks or not
|
||||
show_x_default_ticks: bool,
|
||||
/// Positions for custom Y axis ticks, if any
|
||||
y_tick_positions: [Option<Vec<f64>>; NUMBER_OF_Y_AXES],
|
||||
/// Labels for custom Y axis ticks, if any. I'd prefer to store these together
|
||||
/// with the positions in one vector of an algebraic data type, but this would mean extra
|
||||
/// copies when it comes time to draw the plot because the C++ library expects separate lists.
|
||||
/// The data is stored as CStrings because those are null-terminated, and since we have to
|
||||
/// convert to null-terminated data anyway, we may as well do that directly instead of cloning
|
||||
/// Strings and converting them afterwards.
|
||||
y_tick_labels: [Option<Vec<CString>>; NUMBER_OF_Y_AXES],
|
||||
/// Whether to also show the default Y ticks when showing custom ticks or not
|
||||
show_y_default_ticks: [bool; NUMBER_OF_Y_AXES],
|
||||
/// Configuration for the legend, if specified. The tuple contains location, orientation
|
||||
/// and a boolean (true means legend is outside of plot, false means within). If nothing
|
||||
/// is set, implot's defaults are used. Note also that if these are set, then implot's
|
||||
/// interactive legend configuration does not work because it is overridden by the settings
|
||||
/// here.
|
||||
legend_configuration: Option<(PlotLocation, PlotOrientation, bool)>,
|
||||
/// Flags relating to the plot TODO(4bb4) make those into bitflags
|
||||
plot_flags: sys::ImPlotFlags,
|
||||
/// Flags relating to the X axis of the plot TODO(4bb4) make those into bitflags
|
||||
x_flags: sys::ImPlotAxisFlags,
|
||||
/// Flags relating to the each of the Y axes of the plot TODO(4bb4) make those into bitflags
|
||||
y_flags: [sys::ImPlotAxisFlags; NUMBER_OF_Y_AXES],
|
||||
flags: ImPlotFlags,
|
||||
x_flags: ImPlotAxisFlags,
|
||||
y_flags: ImPlotAxisFlags,
|
||||
}
|
||||
|
||||
impl Plot {
|
||||
/// Create a new plot with some defaults set. Does not draw anything yet.
|
||||
/// Note that this uses antialiasing by default, unlike the C++ API. If you are seeing
|
||||
/// artifacts or weird rendering, try disabling it.
|
||||
///
|
||||
/// # Panics
|
||||
/// Will panic if the title string contains internal null bytes.
|
||||
pub fn new(title: &str) -> Self {
|
||||
// Needed for initialization, see https://github.com/rust-lang/rust/issues/49147
|
||||
const POS_NONE: Option<Vec<f64>> = None;
|
||||
const TICK_NONE: Option<Vec<CString>> = None;
|
||||
|
||||
// TODO(4bb4) question these defaults, maybe remove some of them
|
||||
Self {
|
||||
title: CString::new(title)
|
||||
.unwrap_or_else(|_| panic!("String contains internal null bytes: {}", title)),
|
||||
.unwrap_or_else(|_| panic!("string contains internal null bytes: {}", title)),
|
||||
size: [DEFAULT_PLOT_SIZE_X, DEFAULT_PLOT_SIZE_Y],
|
||||
x_label: CString::new("").unwrap(),
|
||||
y_label: CString::new("").unwrap(),
|
||||
x_limits: None,
|
||||
y_limits: Default::default(),
|
||||
x_tick_positions: None,
|
||||
x_tick_labels: None,
|
||||
show_x_default_ticks: false,
|
||||
y_tick_positions: [POS_NONE; NUMBER_OF_Y_AXES],
|
||||
y_tick_labels: [TICK_NONE; NUMBER_OF_Y_AXES],
|
||||
show_y_default_ticks: [false; NUMBER_OF_Y_AXES],
|
||||
legend_configuration: None,
|
||||
plot_flags: PlotFlags::ANTIALIASED.bits() as sys::ImPlotFlags,
|
||||
x_flags: AxisFlags::NONE.bits() as sys::ImPlotAxisFlags,
|
||||
y_flags: [AxisFlags::NONE.bits() as sys::ImPlotAxisFlags; NUMBER_OF_Y_AXES],
|
||||
flags: PlotFlags::NONE.bits() as ImPlotFlags,
|
||||
x_flags: PlotAxisFlags::NONE.bits() as ImPlotAxisFlags,
|
||||
y_flags: PlotAxisFlags::NONE.bits() as ImPlotAxisFlags,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the plot size, given as [size_x, size_y]. Units are the same as
|
||||
/// what imgui uses. TODO(4bb4) ... which is? I'm not sure it's pixels
|
||||
#[inline]
|
||||
pub fn size(mut self, size: [f32; 2]) -> Self {
|
||||
self.size = size;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the x label of the plot
|
||||
///
|
||||
/// # Panics
|
||||
/// Will panic if the label string contains internal null bytes.
|
||||
#[inline]
|
||||
pub fn with_flags(mut self, flags: &PlotFlags) -> Self {
|
||||
self.flags = flags.bits() as ImPlotFlags;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_x_flags(mut self, flags: &PlotAxisFlags) -> Self {
|
||||
self.x_flags = flags.bits() as ImPlotAxisFlags;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_y_flags(mut self, flags: &PlotAxisFlags) -> Self {
|
||||
self.y_flags = flags.bits() as ImPlotAxisFlags;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn x_label(mut self, label: &str) -> Self {
|
||||
self.x_label = CString::new(label)
|
||||
.unwrap_or_else(|_| panic!("String contains internal null bytes: {}", label));
|
||||
.unwrap_or_else(|_| panic!("string contains internal null bytes: {}", label));
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the y label of the plot
|
||||
///
|
||||
/// # Panics
|
||||
/// Will panic if the label string contains internal null bytes.
|
||||
#[inline]
|
||||
pub fn y_label(mut self, label: &str) -> Self {
|
||||
self.y_label = CString::new(label)
|
||||
.unwrap_or_else(|_| panic!("String contains internal null bytes: {}", label));
|
||||
.unwrap_or_else(|_| panic!("string contains internal null bytes: {}", label));
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the x limits of the plot.
|
||||
///
|
||||
/// Note: This conflicts with `linked_x_limits`, whichever is called last on plot construction
|
||||
/// takes effect.
|
||||
#[inline]
|
||||
pub fn x_limits<L: Into<ImPlotRange>>(mut self, limits: L, condition: Condition) -> Self {
|
||||
self.x_limits = Some(AxisLimitSpecification::Single(limits.into(), condition));
|
||||
self
|
||||
}
|
||||
|
||||
/// Set linked x limits for this plot. Pass clones of the same `Rc` into other plots
|
||||
/// to link their limits with the same values.
|
||||
///
|
||||
/// Note: This conflicts with `x_limits`, whichever is called last on plot construction takes
|
||||
/// effect.
|
||||
#[inline]
|
||||
pub fn linked_x_limits(mut self, limits: Rc<RefCell<ImPlotRange>>) -> Self {
|
||||
self.x_limits = Some(AxisLimitSpecification::Linked(limits));
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the Y limits of the plot for the given Y axis. Call multiple times with different
|
||||
/// `y_axis_choice` values to set for multiple axes, or use the convenience methods such as
|
||||
/// [`Plot::y1_limits`].
|
||||
///
|
||||
/// Note: This conflicts with `linked_y_limits`, whichever is called last on plot construction
|
||||
/// takes effect for a given axis.
|
||||
#[inline]
|
||||
pub fn y_limits<L: Into<ImPlotRange>>(
|
||||
mut self,
|
||||
limits: L,
|
||||
y_axis_choice: YAxisChoice,
|
||||
condition: Condition,
|
||||
) -> Self {
|
||||
let axis_index = y_axis_choice as usize;
|
||||
self.y_limits[axis_index] = Some(AxisLimitSpecification::Single(limits.into(), condition));
|
||||
self
|
||||
}
|
||||
|
||||
/// Convenience function to directly set the Y limits for the first Y axis. To programmatically
|
||||
/// (or on demand) decide which axis to set limits for, use [`Plot::y_limits`]
|
||||
#[inline]
|
||||
pub fn y1_limits<L: Into<ImPlotRange>>(self, limits: L, condition: Condition) -> Self {
|
||||
self.y_limits(limits, YAxisChoice::First, condition)
|
||||
}
|
||||
|
||||
/// Convenience function to directly set the Y limits for the second Y axis. To
|
||||
/// programmatically (or on demand) decide which axis to set limits for, use [`Plot::y_limits`]
|
||||
#[inline]
|
||||
pub fn y2_limits<L: Into<ImPlotRange>>(self, limits: L, condition: Condition) -> Self {
|
||||
self.y_limits(limits, YAxisChoice::Second, condition)
|
||||
}
|
||||
|
||||
/// Convenience function to directly set the Y limits for the third Y axis. To programmatically
|
||||
/// (or on demand) decide which axis to set limits for, use [`Plot::y_limits`]
|
||||
#[inline]
|
||||
pub fn y3_limits<L: Into<ImPlotRange>>(self, limits: L, condition: Condition) -> Self {
|
||||
self.y_limits(limits, YAxisChoice::Third, condition)
|
||||
}
|
||||
|
||||
/// Set linked Y limits of the plot for the given Y axis. Pass clones of the same `Rc` into
|
||||
/// other plots to link their limits with the same values. Call multiple times with different
|
||||
/// `y_axis_choice` values to set for multiple axes, or use the convenience methods such as
|
||||
/// [`Plot::y1_limits`].
|
||||
///
|
||||
/// Note: This conflicts with `y_limits`, whichever is called last on plot construction takes
|
||||
/// effect for a given axis.
|
||||
#[inline]
|
||||
pub fn linked_y_limits(
|
||||
mut self,
|
||||
limits: Rc<RefCell<ImPlotRange>>,
|
||||
y_axis_choice: YAxisChoice,
|
||||
) -> Self {
|
||||
let axis_index = y_axis_choice as usize;
|
||||
self.y_limits[axis_index] = Some(AxisLimitSpecification::Linked(limits));
|
||||
self
|
||||
}
|
||||
|
||||
/// Convenience function to directly set linked Y limits for the first Y axis. To
|
||||
/// programmatically (or on demand) decide which axis to set limits for, use
|
||||
/// [`Plot::linked_y_limits`].
|
||||
#[inline]
|
||||
pub fn linked_y1_limits(self, limits: Rc<RefCell<ImPlotRange>>) -> Self {
|
||||
self.linked_y_limits(limits, YAxisChoice::First)
|
||||
}
|
||||
|
||||
/// Convenience function to directly set linked Y limits for the second Y axis. To
|
||||
/// programmatically (or on demand) decide which axis to set limits for, use
|
||||
/// [`Plot::linked_y_limits`].
|
||||
#[inline]
|
||||
pub fn linked_y2_limits(self, limits: Rc<RefCell<ImPlotRange>>) -> Self {
|
||||
self.linked_y_limits(limits, YAxisChoice::Second)
|
||||
}
|
||||
|
||||
/// Convenience function to directly set linked Y limits for the third Y axis. To
|
||||
/// programmatically (or on demand) decide which axis to set limits for, use
|
||||
/// [`Plot::linked_y_limits`].
|
||||
#[inline]
|
||||
pub fn linked_y3_limits(self, limits: Rc<RefCell<ImPlotRange>>) -> Self {
|
||||
self.linked_y_limits(limits, YAxisChoice::Third)
|
||||
}
|
||||
|
||||
/// Set X ticks without labels for the plot. The vector contains one label each in
|
||||
/// the form of a tuple `(label_position, label_string)`. The `show_default` setting
|
||||
/// determines whether the default ticks are also shown.
|
||||
#[inline]
|
||||
pub fn x_ticks(mut self, ticks: &[f64], show_default: bool) -> Self {
|
||||
self.x_tick_positions = Some(ticks.into());
|
||||
self.show_x_default_ticks = show_default;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set X ticks without labels for the plot. The vector contains one label each in
|
||||
/// the form of a tuple `(label_position, label_string)`. The `show_default` setting
|
||||
/// determines whether the default ticks are also shown.
|
||||
#[inline]
|
||||
pub fn y_ticks(
|
||||
mut self,
|
||||
y_axis_choice: YAxisChoice,
|
||||
ticks: &[f64],
|
||||
show_default: bool,
|
||||
) -> Self {
|
||||
let axis_index = y_axis_choice as usize;
|
||||
self.y_tick_positions[axis_index] = Some(ticks.into());
|
||||
self.show_y_default_ticks[axis_index] = show_default;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set X ticks with labels for the plot. The vector contains one position and label
|
||||
/// each in the form of a tuple `(label_position, label_string)`. The `show_default`
|
||||
/// setting determines whether the default ticks are also shown.
|
||||
///
|
||||
/// # Panics
|
||||
/// Will panic if any of the tick label strings contain internal null bytes.
|
||||
#[inline]
|
||||
pub fn x_ticks_with_labels(
|
||||
mut self,
|
||||
tick_labels: &[(f64, String)],
|
||||
show_default: bool,
|
||||
) -> Self {
|
||||
self.x_tick_positions = Some(tick_labels.iter().map(|x| x.0).collect());
|
||||
self.x_tick_labels = Some(
|
||||
tick_labels
|
||||
.iter()
|
||||
.map(|x| {
|
||||
CString::new(x.1.as_str())
|
||||
.unwrap_or_else(|_| panic!("String contains internal null bytes: {}", x.1))
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
self.show_x_default_ticks = show_default;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set Y ticks with labels for the plot. The vector contains one position and label
|
||||
/// each in the form of a tuple `(label_position, label_string)`. The `show_default`
|
||||
/// setting determines whether the default ticks are also shown.
|
||||
///
|
||||
/// # Panics
|
||||
/// Will panic if any of the tick label strings contain internal null bytes.
|
||||
#[inline]
|
||||
pub fn y_ticks_with_labels(
|
||||
mut self,
|
||||
y_axis_choice: YAxisChoice,
|
||||
tick_labels: &[(f64, String)],
|
||||
show_default: bool,
|
||||
) -> Self {
|
||||
let axis_index = y_axis_choice as usize;
|
||||
self.y_tick_positions[axis_index] = Some(tick_labels.iter().map(|x| x.0).collect());
|
||||
self.y_tick_labels[axis_index] = Some(
|
||||
tick_labels
|
||||
.iter()
|
||||
.map(|x| {
|
||||
CString::new(x.1.as_str())
|
||||
.unwrap_or_else(|_| panic!("String contains internal null bytes: {}", x.1))
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
self.show_y_default_ticks[axis_index] = show_default;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the plot flags, see the help for `PlotFlags` for what the available flags are
|
||||
#[inline]
|
||||
pub fn with_plot_flags(mut self, flags: &PlotFlags) -> Self {
|
||||
self.plot_flags = flags.bits() as sys::ImPlotFlags;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the axis flags for the X axis in this plot
|
||||
#[inline]
|
||||
pub fn with_x_axis_flags(mut self, flags: &AxisFlags) -> Self {
|
||||
self.x_flags = flags.bits() as sys::ImPlotAxisFlags;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the axis flags for the selected Y axis in this plot
|
||||
#[inline]
|
||||
pub fn with_y_axis_flags(mut self, y_axis_choice: YAxisChoice, flags: &AxisFlags) -> Self {
|
||||
let axis_index = y_axis_choice as usize;
|
||||
self.y_flags[axis_index] = flags.bits() as sys::ImPlotAxisFlags;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the legend location, orientation and whether it is to be drawn outside the plot
|
||||
#[rustversion::attr(since(1.48), doc(alias = "SetLegendLocation"))]
|
||||
#[inline]
|
||||
pub fn with_legend_location(
|
||||
mut self,
|
||||
location: &PlotLocation,
|
||||
orientation: &PlotOrientation,
|
||||
outside: bool,
|
||||
) -> Self {
|
||||
self.legend_configuration = Some((*location, *orientation, outside));
|
||||
self
|
||||
}
|
||||
|
||||
/// Internal helper function to set axis limits in case they are specified.
|
||||
fn maybe_set_axis_limits(&self) {
|
||||
// Limit-setting can either happen via direct limits or through linked limits. The version
|
||||
// of implot we link to here has different APIs for the two (separate per-axis calls for
|
||||
// direct, and one call for everything together for linked), hence the code here is a bit
|
||||
// clunky and takes the two approaches separately instead of a unified "match".
|
||||
|
||||
// --- Direct limit-setting ---
|
||||
if let Some(AxisLimitSpecification::Single(limits, condition)) = &self.x_limits {
|
||||
unsafe {
|
||||
sys::ImPlot_SetNextPlotLimitsX(
|
||||
limits.Min,
|
||||
limits.Max,
|
||||
*condition as sys::ImGuiCond,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
self.y_limits
|
||||
.iter()
|
||||
.enumerate()
|
||||
.for_each(|(k, limit_spec)| {
|
||||
if let Some(AxisLimitSpecification::Single(limits, condition)) = limit_spec {
|
||||
unsafe {
|
||||
sys::ImPlot_SetNextPlotLimitsY(
|
||||
limits.Min,
|
||||
limits.Max,
|
||||
*condition as sys::ImGuiCond,
|
||||
k as i32,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// --- Linked limit-setting ---
|
||||
let (xmin_pointer, xmax_pointer) =
|
||||
if let Some(AxisLimitSpecification::Linked(value)) = &self.x_limits {
|
||||
let mut borrowed = value.borrow_mut();
|
||||
(
|
||||
&mut (*borrowed).Min as *mut _,
|
||||
&mut (*borrowed).Max as *mut _,
|
||||
)
|
||||
} else {
|
||||
(std::ptr::null_mut(), std::ptr::null_mut())
|
||||
};
|
||||
|
||||
let y_limit_pointers: Vec<(*mut f64, *mut f64)> = self
|
||||
.y_limits
|
||||
.iter()
|
||||
.map(|limit_spec| {
|
||||
if let Some(AxisLimitSpecification::Linked(value)) = limit_spec {
|
||||
let mut borrowed = value.borrow_mut();
|
||||
(
|
||||
&mut (*borrowed).Min as *mut _,
|
||||
&mut (*borrowed).Max as *mut _,
|
||||
)
|
||||
} else {
|
||||
(std::ptr::null_mut(), std::ptr::null_mut())
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
unsafe {
|
||||
// Calling this unconditionally here as calling it with all NULL pointers should not
|
||||
// affect anything. In terms of unsafety, the pointers should be OK as long as any plot
|
||||
// struct that has an Rc to the same data is alive.
|
||||
sys::ImPlot_LinkNextPlotLimits(
|
||||
xmin_pointer,
|
||||
xmax_pointer,
|
||||
y_limit_pointers[0].0,
|
||||
y_limit_pointers[0].1,
|
||||
y_limit_pointers[1].0,
|
||||
y_limit_pointers[1].1,
|
||||
y_limit_pointers[2].0,
|
||||
y_limit_pointers[2].1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Internal helper function to set tick labels in case they are specified. This does the
|
||||
/// preparation work that is the same for both the X and Y axis plots, then calls the
|
||||
/// "set next plot ticks" wrapper functions for both X and Y.
|
||||
fn maybe_set_tick_labels(&self) {
|
||||
// Show x ticks if they are available
|
||||
if self.x_tick_positions.is_some() && !self.x_tick_positions.as_ref().unwrap().is_empty() {
|
||||
let mut pointer_vec; // The vector of pointers we create has to have a longer lifetime
|
||||
let labels_pointer = if let Some(labels_value) = &self.x_tick_labels {
|
||||
pointer_vec = labels_value
|
||||
.iter()
|
||||
.map(|x| x.as_ptr() as *const c_char)
|
||||
.collect::<Vec<*const c_char>>();
|
||||
pointer_vec.as_mut_ptr()
|
||||
} else {
|
||||
std::ptr::null_mut()
|
||||
};
|
||||
|
||||
unsafe {
|
||||
sys::ImPlot_SetNextPlotTicksXdoublePtr(
|
||||
self.x_tick_positions.as_ref().unwrap().as_ptr(),
|
||||
self.x_tick_positions.as_ref().unwrap().len() as i32,
|
||||
labels_pointer,
|
||||
self.show_x_default_ticks,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
self.y_tick_positions
|
||||
.iter()
|
||||
.zip(self.y_tick_labels.iter())
|
||||
.zip(self.show_y_default_ticks.iter())
|
||||
.enumerate()
|
||||
.for_each(|(k, ((positions, labels), show_defaults))| {
|
||||
if positions.is_some() && !positions.as_ref().unwrap().is_empty() {
|
||||
// The vector of pointers we create has to have a longer lifetime
|
||||
let mut pointer_vec;
|
||||
let labels_pointer = if let Some(labels_value) = &labels {
|
||||
pointer_vec = labels_value
|
||||
.iter()
|
||||
.map(|x| x.as_ptr() as *const c_char)
|
||||
.collect::<Vec<*const c_char>>();
|
||||
pointer_vec.as_mut_ptr()
|
||||
} else {
|
||||
std::ptr::null_mut()
|
||||
};
|
||||
|
||||
unsafe {
|
||||
sys::ImPlot_SetNextPlotTicksYdoublePtr(
|
||||
positions.as_ref().unwrap().as_ptr(),
|
||||
positions.as_ref().unwrap().len() as i32,
|
||||
labels_pointer,
|
||||
*show_defaults,
|
||||
k as i32,
|
||||
)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Attempt to show the plot. If this returns a token, the plot will actually
|
||||
/// be drawn. In this case, use the drawing functionality to draw things on the
|
||||
/// plot, and then call `end()` on the token when done with the plot.
|
||||
/// If none was returned, that means the plot is not rendered.
|
||||
///
|
||||
/// For a convenient implementation of all this, use [`build()`](struct.Plot.html#method.build)
|
||||
/// instead.
|
||||
#[rustversion::attr(since(1.48), doc(alias = "BeginPlot"))]
|
||||
pub fn begin(&self, plot_ui: &PlotUi) -> Option<PlotToken> {
|
||||
self.maybe_set_axis_limits();
|
||||
self.maybe_set_tick_labels();
|
||||
|
||||
let should_render = unsafe {
|
||||
let size_vec: ImVec2 = ImVec2 {
|
||||
x: self.size[0],
|
||||
y: self.size[1],
|
||||
};
|
||||
sys::ImPlot_BeginPlot(
|
||||
self.title.as_ptr(),
|
||||
self.x_label.as_ptr(),
|
||||
self.y_label.as_ptr(),
|
||||
size_vec,
|
||||
self.plot_flags,
|
||||
self.x_flags,
|
||||
self.y_flags[0],
|
||||
self.y_flags[1],
|
||||
self.y_flags[2],
|
||||
)
|
||||
|
||||
let should_render = sys::ImPlot_BeginPlot(self.title.as_ptr(), size_vec, self.flags);
|
||||
|
||||
should_render
|
||||
};
|
||||
|
||||
if should_render {
|
||||
// Configure legend location, if one was set. This has to be called between begin() and
|
||||
// end(), but since only the last call to it actually affects the outcome, I'm adding
|
||||
// it here instead of as a freestanding function. If this is too restrictive (for
|
||||
// example, if you want to set the location based on code running _during_ the plotting
|
||||
// for some reason), file an issue and we'll move it.
|
||||
if let Some(legend_config) = &self.legend_configuration {
|
||||
// We introduce variables with typechecks here to safeguard against accidental
|
||||
// changes in order in the config tuple
|
||||
let location: PlotLocation = legend_config.0;
|
||||
let orientation: PlotOrientation = legend_config.1;
|
||||
let outside_plot: bool = legend_config.2;
|
||||
unsafe {
|
||||
sys::ImPlot_SetLegendLocation(location as i32, orientation as i32, outside_plot)
|
||||
}
|
||||
sys::ImPlot_SetupAxis(Axis::X1 as i32, self.x_label.as_ptr(), self.x_flags);
|
||||
sys::ImPlot_SetupAxis(Axis::Y1 as i32, self.y_label.as_ptr(), self.y_flags);
|
||||
}
|
||||
|
||||
Some(PlotToken {
|
||||
|
@ -627,19 +143,10 @@ impl Plot {
|
|||
plot_title: self.title.clone(),
|
||||
})
|
||||
} else {
|
||||
// In contrast with imgui windows, end() does not have to be
|
||||
// called if we don't render. This is more like an imgui popup modal.
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a window and runs a closure to construct the contents. This internally
|
||||
/// calls `begin` and `end`.
|
||||
///
|
||||
/// Note: the closure is not called if ImPlot::BeginPlot() returned
|
||||
/// false - TODO(4bb4) figure out if this is if things are not rendered
|
||||
#[rustversion::attr(since(1.48), doc(alias = "BeginPlot"))]
|
||||
#[rustversion::attr(since(1.48), doc(alias = "EndPlot"))]
|
||||
pub fn build<F: FnOnce()>(self, plot_ui: &PlotUi, f: F) {
|
||||
if let Some(token) = self.begin(plot_ui) {
|
||||
f();
|
||||
|
@ -648,16 +155,12 @@ impl Plot {
|
|||
}
|
||||
}
|
||||
|
||||
/// Tracks a plot that must be ended by calling `.end()`
|
||||
pub struct PlotToken {
|
||||
context: *const Context,
|
||||
/// For better error messages
|
||||
plot_title: CString,
|
||||
}
|
||||
|
||||
impl PlotToken {
|
||||
/// End a previously begin()'ed plot.
|
||||
#[rustversion::attr(since(1.48), doc(alias = "EndPlot"))]
|
||||
pub fn end(mut self) {
|
||||
self.context = std::ptr::null();
|
||||
unsafe { sys::ImPlot_EndPlot() };
|
||||
|
@ -668,7 +171,7 @@ impl Drop for PlotToken {
|
|||
fn drop(&mut self) {
|
||||
if !self.context.is_null() && !std::thread::panicking() {
|
||||
panic!(
|
||||
"Warning: A PlotToken for plot \"{:?}\" was not called end() on",
|
||||
"warning a plottoken for plot \"{:?}\" was not called end() on.",
|
||||
self.plot_title
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,435 +1 @@
|
|||
//! # Plot elements module
|
||||
//!
|
||||
//! This module defines the various structs that can be used for drawing different things such
|
||||
//! as lines, bars, scatter plots and text in a plot. For the module to create plots themselves,
|
||||
//! see `plot`.
|
||||
use crate::sys;
|
||||
use std::ffi::CString;
|
||||
use std::os::raw::c_char;
|
||||
|
||||
pub use crate::sys::ImPlotPoint;
|
||||
|
||||
// --- Actual plotting functionality -------------------------------------------------------------
|
||||
/// Struct to provide functionality for plotting a line in a plot.
|
||||
pub struct PlotLine {
|
||||
/// Label to show in the legend for this line
|
||||
label: CString,
|
||||
}
|
||||
|
||||
impl PlotLine {
|
||||
/// Create a new line to be plotted. Does not draw anything yet.
|
||||
///
|
||||
/// # Panics
|
||||
/// Will panic if the label string contains internal null bytes.
|
||||
pub fn new(label: &str) -> Self {
|
||||
Self {
|
||||
label: CString::new(label)
|
||||
.unwrap_or_else(|_| panic!("Label string has internal null bytes: {}", label)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Plot a line. Use this in closures passed to [`Plot::build()`](struct.Plot.html#method.build)
|
||||
pub fn plot(&self, x: &[f64], y: &[f64]) {
|
||||
// If there is no data to plot, we stop here
|
||||
if x.len().min(y.len()) == 0 {
|
||||
return;
|
||||
}
|
||||
unsafe {
|
||||
sys::ImPlot_PlotLinedoublePtrdoublePtr(
|
||||
self.label.as_ptr() as *const c_char,
|
||||
x.as_ptr(),
|
||||
y.as_ptr(),
|
||||
x.len().min(y.len()) as i32, // "as" casts saturate as of Rust 1.45. This is safe here.
|
||||
0, // No offset
|
||||
std::mem::size_of::<f64>() as i32, // Stride, set to one f64 for the standard use case
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Struct to provide functionality for plotting a line in a plot with stairs style.
|
||||
pub struct PlotStairs {
|
||||
/// Label to show in the legend for this line
|
||||
label: CString,
|
||||
}
|
||||
|
||||
impl PlotStairs {
|
||||
/// Create a new line to be plotted. Does not draw anything yet.
|
||||
///
|
||||
/// # Panics
|
||||
/// Will panic if the label string contains internal null bytes.
|
||||
pub fn new(label: &str) -> Self {
|
||||
Self {
|
||||
label: CString::new(label)
|
||||
.unwrap_or_else(|_| panic!("Label string has internal null bytes: {}", label)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Plot a stairs style line. Use this in closures passed to
|
||||
/// [`Plot::build()`](struct.Plot.html#method.build)
|
||||
pub fn plot(&self, x: &[f64], y: &[f64]) {
|
||||
// If there is no data to plot, we stop here
|
||||
if x.len().min(y.len()) == 0 {
|
||||
return;
|
||||
}
|
||||
unsafe {
|
||||
sys::ImPlot_PlotStairsdoublePtrdoublePtr(
|
||||
self.label.as_ptr() as *const c_char,
|
||||
x.as_ptr(),
|
||||
y.as_ptr(),
|
||||
x.len().min(y.len()) as i32, // "as" casts saturate as of Rust 1.45. This is safe here.
|
||||
0, // No offset
|
||||
std::mem::size_of::<f64>() as i32, // Stride, set to one f64 for the standard use case
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Struct to provide functionality for creating a scatter plot
|
||||
pub struct PlotScatter {
|
||||
/// Label to show in the legend for this scatter plot
|
||||
///
|
||||
/// # Panics
|
||||
/// Will panic if the label string contains internal null bytes.
|
||||
label: CString,
|
||||
}
|
||||
|
||||
impl PlotScatter {
|
||||
/// Create a new scatter plot to be shown. Does not draw anything yet.
|
||||
pub fn new(label: &str) -> Self {
|
||||
Self {
|
||||
label: CString::new(label)
|
||||
.unwrap_or_else(|_| panic!("Label string has internal null bytes: {}", label)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw a previously-created scatter plot. Use this in closures passed to
|
||||
/// [`Plot::build()`](struct.Plot.html#method.build)
|
||||
pub fn plot(&self, x: &[f64], y: &[f64]) {
|
||||
// If there is no data to plot, we stop here
|
||||
if x.len().min(y.len()) == 0 {
|
||||
return;
|
||||
}
|
||||
unsafe {
|
||||
sys::ImPlot_PlotScatterdoublePtrdoublePtr(
|
||||
self.label.as_ptr() as *const c_char,
|
||||
x.as_ptr(),
|
||||
y.as_ptr(),
|
||||
x.len().min(y.len()) as i32, // "as" casts saturate as of Rust 1.45. This is safe here.
|
||||
0, // No offset
|
||||
std::mem::size_of::<f64>() as i32, // Stride, set to one f64 for the standard use case
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Struct to provide bar plotting functionality.
|
||||
pub struct PlotBars {
|
||||
/// Label to show in the legend for this line
|
||||
label: CString,
|
||||
|
||||
/// Width of the bars, in plot coordinate terms
|
||||
bar_width: f64,
|
||||
|
||||
/// Horizontal bar mode
|
||||
horizontal_bars: bool,
|
||||
}
|
||||
|
||||
impl PlotBars {
|
||||
/// Create a new bar plot to be shown. Defaults to drawing vertical bars.
|
||||
/// Does not draw anything yet.
|
||||
///
|
||||
/// # Panics
|
||||
/// Will panic if the label string contains internal null bytes.
|
||||
pub fn new(label: &str) -> Self {
|
||||
Self {
|
||||
label: CString::new(label)
|
||||
.unwrap_or_else(|_| panic!("Label string has internal null bytes: {}", label)),
|
||||
bar_width: 0.67, // Default value taken from C++ implot
|
||||
horizontal_bars: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the width of the bars
|
||||
pub fn with_bar_width(mut self, bar_width: f64) -> Self {
|
||||
self.bar_width = bar_width;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the bars to be horizontal (default is vertical)
|
||||
pub fn with_horizontal_bars(mut self) -> Self {
|
||||
self.horizontal_bars = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Draw a previously-created bar plot. Use this in closures passed to
|
||||
/// [`Plot::build()`](struct.Plot.html#method.build). The `axis_positions`
|
||||
/// specify where on the corresponding axis (X for vertical mode, Y for horizontal mode) the
|
||||
/// bar is drawn, and the `bar_values` specify what values the bars have.
|
||||
pub fn plot(&self, axis_positions: &[f64], bar_values: &[f64]) {
|
||||
let number_of_points = axis_positions.len().min(bar_values.len());
|
||||
// If there is no data to plot, we stop here
|
||||
if number_of_points == 0 {
|
||||
return;
|
||||
}
|
||||
unsafe {
|
||||
// C++ implot has separate functions for the two variants, but the interfaces
|
||||
// are the same, so they are unified here. The x and y values have different
|
||||
// meanings though, hence the swapping around before they are passed to the
|
||||
// plotting function.
|
||||
let (plot_function, x, y);
|
||||
if self.horizontal_bars {
|
||||
plot_function = sys::ImPlot_PlotBarsHdoublePtrdoublePtr
|
||||
as unsafe extern "C" fn(
|
||||
*const c_char,
|
||||
*const f64,
|
||||
*const f64,
|
||||
i32,
|
||||
f64,
|
||||
i32,
|
||||
i32,
|
||||
);
|
||||
x = bar_values;
|
||||
y = axis_positions;
|
||||
} else {
|
||||
plot_function = sys::ImPlot_PlotBarsdoublePtrdoublePtr
|
||||
as unsafe extern "C" fn(
|
||||
*const c_char,
|
||||
*const f64,
|
||||
*const f64,
|
||||
i32,
|
||||
f64,
|
||||
i32,
|
||||
i32,
|
||||
);
|
||||
x = axis_positions;
|
||||
y = bar_values;
|
||||
};
|
||||
|
||||
plot_function(
|
||||
self.label.as_ptr() as *const c_char,
|
||||
x.as_ptr(),
|
||||
y.as_ptr(),
|
||||
number_of_points as i32, // "as" casts saturate as of Rust 1.45. This is safe here.
|
||||
self.bar_width,
|
||||
0, // No offset
|
||||
std::mem::size_of::<f64>() as i32, // Stride, set to one f64 for the standard use case
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Struct to provide functionality for adding text within a plot
|
||||
pub struct PlotText {
|
||||
/// Label to show in plot
|
||||
label: CString,
|
||||
|
||||
/// X component of the pixel offset to be used. Will be used independently of the actual plot
|
||||
/// scaling. Defaults to 0.
|
||||
pixel_offset_x: f32,
|
||||
|
||||
/// Y component of the pixel offset to be used. Will be used independently of the actual plot
|
||||
/// scaling. Defaults to 0.
|
||||
pixel_offset_y: f32,
|
||||
}
|
||||
|
||||
impl PlotText {
|
||||
/// Create a new text label to be shown. Does not draw anything yet.
|
||||
///
|
||||
/// # Panics
|
||||
/// Will panic if the label string contains internal null bytes.
|
||||
pub fn new(label: &str) -> Self {
|
||||
Self {
|
||||
label: CString::new(label)
|
||||
.unwrap_or_else(|_| panic!("Label string has internal null bytes: {}", label)),
|
||||
pixel_offset_x: 0.0,
|
||||
pixel_offset_y: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a pixel offset to the text to be plotted. This offset will be independent of the
|
||||
/// scaling of the plot itself.
|
||||
pub fn with_pixel_offset(mut self, offset_x: f32, offset_y: f32) -> Self {
|
||||
self.pixel_offset_x = offset_x;
|
||||
self.pixel_offset_y = offset_y;
|
||||
self
|
||||
}
|
||||
|
||||
/// Draw the text label in the plot at the given position, optionally vertically. Use this in
|
||||
/// closures passed to [`Plot::build()`](struct.Plot.html#method.build)
|
||||
pub fn plot(&self, x: f64, y: f64, vertical: bool) {
|
||||
// If there is nothing to show, don't do anything
|
||||
if self.label.as_bytes().is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
sys::ImPlot_PlotText(
|
||||
self.label.as_ptr() as *const c_char,
|
||||
x,
|
||||
y,
|
||||
vertical,
|
||||
sys::ImVec2 {
|
||||
x: self.pixel_offset_x,
|
||||
y: self.pixel_offset_y,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Struct to provide functionality for creating headmaps.
|
||||
pub struct PlotHeatmap {
|
||||
/// Label to show in plot
|
||||
label: CString,
|
||||
|
||||
/// Scale range of the values shown. If this is set to `None`, the scale
|
||||
/// is computed based on the values given to the `plot` function. If there
|
||||
/// is a value, the tuple is interpreted as `(minimum, maximum)`.
|
||||
scale_range: Option<(f64, f64)>,
|
||||
|
||||
/// Label C style format string, this is shown when a a value point is hovered.
|
||||
/// None means don't show a label. The label is stored directly as an ImString because
|
||||
/// that is what's needed for the plot call anyway. Conversion is done in the setter.
|
||||
label_format: Option<CString>,
|
||||
|
||||
/// Lower left point for the bounding rectangle. This is called `bounds_min` in the C++ code.
|
||||
drawarea_lower_left: ImPlotPoint,
|
||||
|
||||
/// Upper right point for the bounding rectangle. This is called `bounds_max` in the C++ code.
|
||||
drawarea_upper_right: ImPlotPoint,
|
||||
}
|
||||
|
||||
impl PlotHeatmap {
|
||||
/// Create a new heatmap to be shown. Uses the same defaults as the C++ version (see code for
|
||||
/// what those are), aside from the `scale_min` and `scale_max` values, which default to
|
||||
/// `None`, which is interpreted as "automatically make the scale fit the data". Does not draw
|
||||
/// anything yet.
|
||||
pub fn new(label: &str) -> Self {
|
||||
Self {
|
||||
label: CString::new(label)
|
||||
.unwrap_or_else(|_| panic!("Label string has internal null bytes: {}", label)),
|
||||
scale_range: None,
|
||||
label_format: Some(CString::new("%.1f").unwrap()),
|
||||
drawarea_lower_left: ImPlotPoint { x: 0.0, y: 0.0 },
|
||||
drawarea_upper_right: ImPlotPoint { x: 1.0, y: 1.0 },
|
||||
}
|
||||
}
|
||||
|
||||
/// Specify the scale for the shown colors by minimum and maximum value.
|
||||
pub fn with_scale(mut self, scale_min: f64, scale_max: f64) -> Self {
|
||||
self.scale_range = Some((scale_min, scale_max));
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify the label format for hovered data points. `None` means no label is shown.
|
||||
///
|
||||
/// # Panics
|
||||
/// Will panic if the label format string contains internal null bytes.
|
||||
///
|
||||
/// # Safety
|
||||
/// This function directly sets the format string of a C formatting function (`sprintf`). As
|
||||
/// such, one has to check oneself that the formatted numbers do not yield strings exceeding
|
||||
/// the length of the buffer used in the C++ code (32 bytes right now, this might change in the
|
||||
/// future, make sure to check in the vendored-in C++ code to be sure). While the string is
|
||||
/// not used until later and hence the function here is strictly speaking safe, the effect
|
||||
/// of this function can lead to unsoundness later, hence it is marked as unsafe.
|
||||
pub unsafe fn with_label_format(mut self, label_format: Option<&str>) -> Self {
|
||||
self.label_format = label_format.map(|x| {
|
||||
CString::new(x)
|
||||
.unwrap_or_else(|_| panic!("Format label string has internal null bytes: {}", x))
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify the drawing area as the lower left and upper right point
|
||||
pub fn with_drawing_area(mut self, lower_left: ImPlotPoint, upper_right: ImPlotPoint) -> Self {
|
||||
self.drawarea_lower_left = lower_left;
|
||||
self.drawarea_upper_right = upper_right;
|
||||
self
|
||||
}
|
||||
|
||||
/// Plot the heatmap, with the given values (assumed to be in row-major order),
|
||||
/// number of rows and number of columns.
|
||||
pub fn plot(&self, values: &[f64], number_of_rows: u32, number_of_cols: u32) {
|
||||
// If no range was given, determine that range
|
||||
let scale_range = self.scale_range.unwrap_or_else(|| {
|
||||
let mut min_seen = values[0];
|
||||
let mut max_seen = values[0];
|
||||
values.iter().for_each(|value| {
|
||||
min_seen = min_seen.min(*value);
|
||||
max_seen = max_seen.max(*value);
|
||||
});
|
||||
(min_seen, max_seen)
|
||||
});
|
||||
|
||||
unsafe {
|
||||
sys::ImPlot_PlotHeatmapdoublePtr(
|
||||
self.label.as_ptr() as *const c_char,
|
||||
values.as_ptr(),
|
||||
number_of_rows as i32, // Not sure why C++ code uses a signed value here
|
||||
number_of_cols as i32, // Not sure why C++ code uses a signed value here
|
||||
scale_range.0,
|
||||
scale_range.1,
|
||||
// "no label" is taken as null pointer in the C++ code, but we're using
|
||||
// option types in the Rust bindings because they are more idiomatic.
|
||||
if self.label_format.is_some() {
|
||||
self.label_format.as_ref().unwrap().as_ptr() as *const c_char
|
||||
} else {
|
||||
std::ptr::null()
|
||||
},
|
||||
self.drawarea_lower_left,
|
||||
self.drawarea_upper_right,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Struct to provide stem plotting functionality.
|
||||
pub struct PlotStems {
|
||||
/// Label to show in the legend for this line
|
||||
label: CString,
|
||||
|
||||
/// Reference value for the y value, which the stems are "with respect to"
|
||||
reference_y: f64,
|
||||
}
|
||||
|
||||
impl PlotStems {
|
||||
/// Create a new stem plot to be shown. Does not draw anything by itself, call
|
||||
/// [`PlotStems::plot`] on the struct for that.
|
||||
pub fn new(label: &str) -> Self {
|
||||
Self {
|
||||
label: CString::new(label)
|
||||
.unwrap_or_else(|_| panic!("Label string has internal null bytes: {}", label)),
|
||||
reference_y: 0.0, // Default value taken from C++ implot
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the reference y value for the stems
|
||||
pub fn with_reference_y(mut self, reference_y: f64) -> Self {
|
||||
self.reference_y = reference_y;
|
||||
self
|
||||
}
|
||||
|
||||
/// Draw a previously-created stem plot. Use this in closures passed to
|
||||
/// [`Plot::build()`](struct.Plot.html#method.build). The `axis_positions` specify where on the
|
||||
/// X axis the stems are drawn, and the `stem_values` specify what values the stems have.
|
||||
pub fn plot(&self, axis_positions: &[f64], stem_values: &[f64]) {
|
||||
let number_of_points = axis_positions.len().min(stem_values.len());
|
||||
// If there is no data to plot, we stop here
|
||||
if number_of_points == 0 {
|
||||
return;
|
||||
}
|
||||
unsafe {
|
||||
sys::ImPlot_PlotStemsdoublePtrdoublePtr(
|
||||
self.label.as_ptr() as *const c_char,
|
||||
axis_positions.as_ptr(),
|
||||
stem_values.as_ptr(),
|
||||
number_of_points as i32, // "as" casts saturate as of Rust 1.45. This is safe here.
|
||||
self.reference_y,
|
||||
0, // No offset
|
||||
std::mem::size_of::<f64>() as i32, // Stride, set to one f64 for the standard use case
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
22
src/rect.rs
Normal file
22
src/rect.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
use sys::{ImPlotRect, ImVec4};
|
||||
|
||||
use crate::sys;
|
||||
|
||||
pub fn drag_rect(rect: &mut ImPlotRect) {
|
||||
unsafe {
|
||||
sys::ImPlot_DragRect(
|
||||
0,
|
||||
&mut rect.X.Min,
|
||||
&mut rect.Y.Min,
|
||||
&mut rect.X.Max,
|
||||
&mut rect.Y.Max,
|
||||
ImVec4 {
|
||||
x: 1.0,
|
||||
y: 0.0,
|
||||
z: 1.0,
|
||||
w: 0.4,
|
||||
},
|
||||
0,
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue