crates/veilvoice-gui/src/lib.rs
what this file is for · veilvoice-gui · 136 lines · the same file on GitHub
The file as it is in the tree, in the colours you chose. A line number is a link, and so is every box in this file’s diagram: it opens here with the function it names marked.
// SPDX-License-Identifier: GPL-3.0-or-later
//! # veilvoice-gui
//!
//! The VeilVoice desktop application: an egui/eframe front-end, monospace
//! throughout: anonymise a file, scramble a microphone live, watch what is
//! listening, manage the app lock, choose how the app looks, and an about
//! panel that states the honest scope.
//!
//! The binary lives in `main.rs`; this library exists so the UI logic can be
//! unit tested without opening a window.
//!
//! That split is worth stating plainly, because it is the reason this crate has
//! tests at all: a binary crate cannot be unit tested, so everything with logic
//! in it -- the app lock's state machine, preference loading, palette
//! resolution, the reduced-motion decision -- lives here where a test can reach
//! it without a display server. `main.rs` holds only what genuinely needs a
//! window.
//!
//! # The modules
//!
//! | Module | What it owns |
//! |---|---|
//! | [`security`] | The unlock screen, the lock tab, and the at-rest controls |
//! | [`prefs`] | Preferences, and recovering from a corrupt preferences file |
//! | [`policy`] | Settings somebody has fixed, and the reason beside each one |
//! | [`settings`] | The settings tab |
//! | [`setup`] | Installing this copy, and the optional companions |
//! | [`theme`] | The palette, shared with the command-line front end |
//! | [`soundbar`] | The animated level meter |
//! | [`reduced_motion`] | Whether to animate at all |
//! | [`watchfeed`] | The device monitor, on a thread that is not this one |
//!
//! # Two rules this crate keeps
//!
//! **The user interface never softens a scope note.** Where a control has a
//! bound -- the app lock is a verifier and not disk encryption, tamper detection
//! detects rather than prevents -- the interface says so next to the control,
//! and tests fail the build if that text changes. Documentation nobody opens
//! does not protect anybody.
//!
//! **Animation is a preference that is honoured, not a decoration.**
//! [`reduced_motion`] resolves the platform's own setting alongside the user's
//! explicit choice, and the whole interface reads that answer rather than each
//! widget deciding for itself.
//!
//! # In plain words
//!
//! This is the window.
//!
//! Tabs down the top for the things the program does: disguise a file, scramble a
//! microphone as you talk, handle a recording with several people, watch for
//! anything using your microphone, put the app behind a password, check a
//! download, and change how it looks.
//!
//! Nine colour schemes, and your own if you write one. It does the slow work on
//! another thread, so the window keeps answering while it is busy.
#![forbid(unsafe_code)]
#![warn(missing_docs)]
mod app;
/// The name of every tab the window shows, in the order it shows them.
///
/// Exported so that `veilvoice-gui --tabs` can print them and the screenshot
/// scripts can read them, rather than each carrying a copy of a list that goes
/// stale the first time a tab is added. When it went stale the failure was
/// silent: the run succeeded and the new tab simply had no picture.
pub fn tabs() -> impl Iterator<Item = &'static str> {
app::Tab::ALL.iter().map(|tab| tab.key())
}
/// Where JetBrains Mono is on this machine, if it is anywhere.
///
/// Re-exported so `--typeface` can answer without a window and without the
/// binary reaching into a module the rest of it does not use.
pub fn jetbrains_mono_path() -> Option<std::path::PathBuf> {
theme::jetbrains_mono_path()
}
pub mod autolock;
pub mod avnotice;
pub mod crashlog;
pub mod crashreport;
pub mod decoys;
pub mod dialog;
pub mod firstrun;
pub mod graphics;
pub mod group;
pub mod integrity;
pub mod layout;
pub mod monitor;
pub mod notify;
pub mod pace;
pub mod palettes;
pub mod paths;
pub mod policy;
pub mod prefs;
pub mod reduced_motion;
pub mod security;
pub mod settings;
pub mod setup;
pub mod soundbar;
pub mod storage;
pub mod studio;
pub mod theme;
pub mod tour;
pub mod updates;
pub mod vault_store;
pub mod verify;
pub mod watchfeed;
pub mod window;
pub use app::VeilVoiceApp;
/// Crate version string, surfaced in the About panel.
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
/// Draw one frame with no window, and discard what a real backend would have
/// uploaded.
///
/// Every test in this crate that renders headlessly goes through here.
/// `egui` 0.36 asserts that a frame's texture deltas were handled: dropping a
/// `FullOutput` that still carries one panics, which is exactly right for a
/// backend that forgot to upload a font atlas and exactly wrong for a test
/// that only wants the shapes back. Clearing it in one place beats repeating
/// the same two lines at fifteen call sites and forgetting it at the
/// sixteenth.
#[cfg(test)]
pub(crate) fn headless_frame(
ctx: &egui::Context,
input: egui::RawInput,
add_contents: impl FnMut(&mut egui::Ui),
) -> egui::FullOutput {
let mut output = ctx.run_ui(input, add_contents);
output.textures_delta.clear();
output
}