Skip to main content

DicomViewerApp

Struct DicomViewerApp 

Source
pub struct DicomViewerApp {
Show 16 fields pub paths: Paths, pub config: Config, pub ui_state: UiState, pub studies: Vec<Study>, pub raw_cache: HashMap<String, Arc<RawImage>>, pub raw_failures: HashMap<String, String>, pub metadata_cache: HashMap<String, Arc<Vec<TagRow>>>, pub metadata_filter: String, pub thumbnails: HashMap<String, ThumbnailState>, pub grid: GridLayout, pub cells: Vec<CellState>, pub active_cell: usize, pub annotation_store: AnnotationStore, pub annotations_path: PathBuf, pub last_error: Option<String>, pub last_info: Option<String>, /* private fields */
}
Expand description

The single eframe application.

Created by Self::new from main, then handed to [eframe::run_native]. Every per-frame operation goes through the eframe::App::update method below.

Fields§

§paths: Paths

Resolved data/log/exe paths. See Paths::resolve.

§config: Config

Loaded config.toml (or defaults on first run).

§ui_state: UiState

Transient UI state — disclaimer/about dialogs, active tool, panel visibility, in-progress measurement, etc.

§studies: Vec<Study>

All loaded studies (metadata only; pixels live in Self::raw_cache).

§raw_cache: HashMap<String, Arc<RawImage>>

Decoded pixel buffers, keyed by SOP Instance UID. Filled lazily by Self::raw_for; cleared on Self::open_folder.

§raw_failures: HashMap<String, String>

SOP UIDs whose decode failed and the reason — so we don’t retry every frame.

§metadata_cache: HashMap<String, Arc<Vec<TagRow>>>

Flattened DICOM tag rows for the metadata panel, keyed by SOP UID. Lazily populated by Self::metadata_for.

§metadata_filter: String

Substring filter applied to the metadata panel.

§thumbnails: HashMap<String, ThumbnailState>

Sidebar previews. Lazily populated one-per-frame so the UI never stalls behind a chain of pixel decodes.

§grid: GridLayout

Active grid layout (1×1 up to 4×4).

§cells: Vec<CellState>

One CellState per visible viewport cell. Length matches grid.cell_count().

§active_cell: usize

Index into Self::cells receiving toolbar actions and keyboard input.

§annotation_store: AnnotationStore

Per-SOP-UID annotation list, persisted to a JSON sidecar.

§annotations_path: PathBuf

Where Self::annotation_store is loaded from / saved to.

§last_error: Option<String>

Last error message — shown in the status bar.

§last_info: Option<String>

Last informational message — shown in the status bar.

Implementations§

Source§

impl DicomViewerApp

Source

pub fn new( cc: &CreationContext<'_>, paths: Paths, config: Config, startup_folder: Option<PathBuf>, ) -> Self

Build the app, install the theme, and load annotations from <data_dir>/annotations.json.

startup_folder defers the actual folder scan to the first update tick so the window paints before the (potentially CD-slow) scan begins.

Source

pub fn save_annotations(&self)

Persist Self::annotation_store to Self::annotations_path. Failures are logged but not propagated — losing one annotation save shouldn’t crash the viewer.

Source

pub fn push_annotation(&mut self, sop_uid: &str, ann: Annotation)

Append ann to the list for sop_uid and immediately save.

Source

pub fn clear_annotations_for_active(&mut self)

Drop every annotation on the instance currently shown by the active cell and immediately save.

Source

pub fn undo_last_annotation_for_active(&mut self)

Remove the most recently pushed annotation on the active cell’s instance and immediately save.

Source

pub fn set_grid(&mut self, g: GridLayout)

Switch grid layout, resizing Self::cells to match. Existing cells are preserved in array order; extras (when shrinking) are truncated. Resets Self::active_cell if it now falls out of range.

Source

pub fn open_folder(&mut self, folder: &Path)

Scan a folder for DICOM files, replace Self::studies, and auto-arrange the first one. Clears every per-instance cache (raw pixels, metadata rows, thumbnails) and every CellState. Errors are surfaced via Self::last_error for the status bar — they’re not propagated to the caller.

Source

pub fn open_file(&mut self, file: &Path)

Convenience: open the parent folder of a single file. We always load a folder — there is no single-file mode.

Source

pub fn select_series(&mut self, study_idx: usize, series_idx: usize)

Click on a series in the sidebar. First tries the MG hanging protocol across the whole study (covers the 4-series-of-1-instance case). If that doesn’t apply, falls back to single-series MG (≥4 instances in this series) or assigning to the active cell.

Source

pub fn try_arrange_mg_study(&mut self, study_idx: usize) -> bool

Look across every MG series in the study and assemble a 2×2 layout when there’s at least one right-breast and one left-breast view.

Placement priority:

  1. Strict — RCC, LCC, RMLO, LMLO all present: place in that order.
  2. View-known — at least 2 R and 2 L with ViewPosition set: sort each side’s queue by view (CC before MLO) so the top row is the cranio-caudal pair.
  3. Laterality-only — at least 2 R and 2 L but ViewPosition is missing (common in some PACS exports): pair in series/instance order.
Source

pub fn drop_series_onto_cell( &mut self, cell_idx: usize, series_ref: (usize, usize), )

Queue a drag-drop assignment. Validated now (so we don’t push garbage), applied next frame (so the cell’s current TextureHandle survives the rest of this frame’s GPU submission).

Source

pub fn raw_for(&mut self, sop_uid: &str, path: &Path) -> Option<Arc<RawImage>>

Get the decoded RawImage for an instance, decoding on first miss. Returns None (and remembers the failure in Self::raw_failures) when decode fails, so the viewport doesn’t re-attempt every frame.

Source

pub fn handle_dropped_files(&mut self, ctx: &Context)

Pick up files dropped onto the egui window. A dropped folder triggers Self::open_folder; a dropped file triggers Self::open_file.

Source

pub fn reset_active_cell(&mut self)

Apply CellState::reset_view to the active cell.

Source

pub fn active_instance(&self) -> Option<&Instance>

Return the instance the active cell is currently showing, if any.

Source

pub fn thumbnail_for(&mut self, series_uid: &str) -> Option<TextureHandle>

Sidebar asks per row: “do you have a thumbnail for this series?” We register a Pending entry on first miss; the per-frame pump in Self::pump_thumbnails decodes one at a time.

Source

pub fn pump_thumbnails(&mut self, ctx: &Context)

Decode at most one pending sidebar thumbnail per frame, so the UI thread isn’t blocked by a long chain of MG-sized decodes.

Source

pub fn metadata_for( &mut self, sop_uid: &str, path: &Path, ) -> Option<Arc<Vec<TagRow>>>

Get the flattened metadata rows for an instance, parsing on first miss. Failures are logged but not cached, since metadata parsing is cheap and unlikely to repeat-fail.

Trait Implementations§

Source§

impl App for DicomViewerApp

Source§

fn update(&mut self, ctx: &Context, _frame: &mut Frame)

Called each time the UI needs repainting, which may be many times per second. Read more
Source§

fn on_exit(&mut self)

Called once on shutdown, after [Self::save]. Read more
§

fn save(&mut self, _storage: &mut dyn Storage)

Called on shutdown, and perhaps at regular intervals. Allows you to save state. Read more
§

fn auto_save_interval(&self) -> Duration

Time between automatic calls to [Self::save]
§

fn clear_color(&self, _visuals: &Visuals) -> [f32; 4]

Background color values for the app, e.g. what is sent to gl.clearColor. Read more
§

fn persist_egui_memory(&self) -> bool

Controls whether or not the egui memory (window positions etc) will be persisted (only if the “persistence” feature is enabled).
§

fn raw_input_hook(&mut self, _ctx: &Context, _raw_input: &mut RawInput)

A hook for manipulating or filtering raw input before it is processed by [Self::update]. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Downcast<T> for T

§

fn downcast(&self) -> &T

§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<D> OwoColorize for D

§

fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>
where C: Color,

Set the foreground color generically Read more
§

fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>
where C: Color,

Set the background color generically. Read more
§

fn black(&self) -> FgColorDisplay<'_, Black, Self>

Change the foreground color to black
§

fn on_black(&self) -> BgColorDisplay<'_, Black, Self>

Change the background color to black
§

fn red(&self) -> FgColorDisplay<'_, Red, Self>

Change the foreground color to red
§

fn on_red(&self) -> BgColorDisplay<'_, Red, Self>

Change the background color to red
§

fn green(&self) -> FgColorDisplay<'_, Green, Self>

Change the foreground color to green
§

fn on_green(&self) -> BgColorDisplay<'_, Green, Self>

Change the background color to green
§

fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>

Change the foreground color to yellow
§

fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>

Change the background color to yellow
§

fn blue(&self) -> FgColorDisplay<'_, Blue, Self>

Change the foreground color to blue
§

fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>

Change the background color to blue
§

fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>

Change the foreground color to magenta
§

fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>

Change the background color to magenta
§

fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>

Change the foreground color to purple
§

fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>

Change the background color to purple
§

fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>

Change the foreground color to cyan
§

fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>

Change the background color to cyan
§

fn white(&self) -> FgColorDisplay<'_, White, Self>

Change the foreground color to white
§

fn on_white(&self) -> BgColorDisplay<'_, White, Self>

Change the background color to white
§

fn default_color(&self) -> FgColorDisplay<'_, Default, Self>

Change the foreground color to the terminal default
§

fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>

Change the background color to the terminal default
§

fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>

Change the foreground color to bright black
§

fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>

Change the background color to bright black
§

fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>

Change the foreground color to bright red
§

fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>

Change the background color to bright red
§

fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>

Change the foreground color to bright green
§

fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>

Change the background color to bright green
§

fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>

Change the foreground color to bright yellow
§

fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>

Change the background color to bright yellow
§

fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>

Change the foreground color to bright blue
§

fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>

Change the background color to bright blue
§

fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>

Change the foreground color to bright magenta
§

fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>

Change the background color to bright magenta
§

fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>

Change the foreground color to bright purple
§

fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>

Change the background color to bright purple
§

fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>

Change the foreground color to bright cyan
§

fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>

Change the background color to bright cyan
§

fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>

Change the foreground color to bright white
§

fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>

Change the background color to bright white
§

fn bold(&self) -> BoldDisplay<'_, Self>

Make the text bold
§

fn dimmed(&self) -> DimDisplay<'_, Self>

Make the text dim
§

fn italic(&self) -> ItalicDisplay<'_, Self>

Make the text italicized
§

fn underline(&self) -> UnderlineDisplay<'_, Self>

Make the text underlined
Make the text blink
Make the text blink (but fast!)
§

fn reversed(&self) -> ReversedDisplay<'_, Self>

Swap the foreground and background colors
§

fn hidden(&self) -> HiddenDisplay<'_, Self>

Hide the text
§

fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>

Cross out the text
§

fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>
where Color: DynColor,

Set the foreground color at runtime. Only use if you do not know which color will be used at compile-time. If the color is constant, use either [OwoColorize::fg] or a color-specific method, such as [OwoColorize::green], Read more
§

fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>
where Color: DynColor,

Set the background color at runtime. Only use if you do not know what color to use at compile-time. If the color is constant, use either [OwoColorize::bg] or a color-specific method, such as [OwoColorize::on_yellow], Read more
§

fn fg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> FgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the foreground color to a specific RGB value.
§

fn bg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> BgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the background color to a specific RGB value.
§

fn truecolor(&self, r: u8, g: u8, b: u8) -> FgDynColorDisplay<'_, Rgb, Self>

Sets the foreground color to an RGB value.
§

fn on_truecolor(&self, r: u8, g: u8, b: u8) -> BgDynColorDisplay<'_, Rgb, Self>

Sets the background color to an RGB value.
§

fn style(&self, style: Style) -> Styled<&Self>

Apply a runtime-determined style
§

fn if_supports_color<'a, Out, ApplyFn>( &'a self, stream: impl Into<Stream>, apply: ApplyFn, ) -> SupportsColorsDisplay<'a, Self, Out, ApplyFn>
where ApplyFn: Fn(&'a Self) -> Out,

Apply a given transformation function to all formatters if the given stream supports at least basic ANSI colors, allowing you to conditionally apply given styles/colors. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Upcast<T> for T

§

fn upcast(&self) -> Option<&T>

§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> WasmNotSend for T
where T: Send,

§

impl<T> WasmNotSendSync for T
where T: WasmNotSend + WasmNotSync,

§

impl<T> WasmNotSync for T
where T: Sync,