Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion crates/app/src/shot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use plotx_core::settings::Settings;
use plotx_core::state::{
AnalysisSelection, AxisRange, DEFAULT_CANVAS_SIZE_MM, Dataset, FrameRef, LineShapeKind,
Nmr2DDataset, NmrDataset, Peak2DOrigin, Peak2DPoint, Peak2DReview, PlotxApp, Region, RegionId,
Tool, XpsDataset, region_color,
Tool, WorkflowTab, XpsDataset, region_color,
};
use plotx_io::xps::{
XpsEnergyKind, XpsExperiment, XpsMeasurement, XpsMeasurementId, XpsRegion, XpsRegionId,
Expand Down Expand Up @@ -91,6 +91,10 @@ enum Op {
XpsSetup,
CraftSetup,
XpsTab(plotx_core::state::XpsWorkbenchTab),
/// Show a Ribbon task tab. Sets the state directly (like [`Op::XpsTab`])
/// so the capture shows the tab's command row without the side effects a
/// real tab click has (opening task cards or sidebar tool groups).
RibbonTab(plotx_core::state::WorkflowTab),
Zoom(f32),
Resize(f32, f32),
}
Expand Down Expand Up @@ -143,6 +147,20 @@ const SCENES: &[Scene] = &[
shot(10, "ribbon_720"),
act(2, Op::Resize(900.0, 760.0)),
shot(12, "ribbon_900"),
// Every task tab at the in-between width, where density and overflow do
// the most work. The state carries a fitted 1D spectrum, so contextual
// groups representative of the core workflow are present.
act(2, Op::RibbonTab(WorkflowTab::Data)),
shot(6, "ribbon_data_900"),
act(2, Op::RibbonTab(WorkflowTab::Process)),
shot(6, "ribbon_process_900"),
act(2, Op::RibbonTab(WorkflowTab::Figure)),
shot(6, "ribbon_figure_900"),
act(2, Op::RibbonTab(WorkflowTab::Arrange)),
shot(6, "ribbon_arrange_900"),
act(2, Op::RibbonTab(WorkflowTab::View)),
shot(6, "ribbon_view_900"),
act(2, Op::RibbonTab(WorkflowTab::Analyze)),
act(2, Op::Resize(1440.0, 900.0)),
shot(12, "ribbon_1440"),
act(2, Op::RegionResult),
Expand Down Expand Up @@ -361,6 +379,7 @@ fn run_op(op: Op, app: &mut PlotxApp, ctx: &egui::Context) -> Result<(), String>
Op::XpsSetup => xps_setup(app, ctx)?,
Op::CraftSetup => craft_shot::setup(app, ctx)?,
Op::XpsTab(tab) => app.session.ui.xps_workbench_tab = tab,
Op::RibbonTab(tab) => app.session.ui.ribbon_tab = tab,
Op::Zoom(factor) => ctx.set_zoom_factor(factor),
Op::Resize(w, h) => {
ctx.send_viewport_cmd(egui::ViewportCommand::InnerSize(egui::vec2(w, h)));
Expand Down
4 changes: 4 additions & 0 deletions crates/app/src/typography.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ pub(crate) fn caption(text: impl Into<String>) -> RichText {
RichText::new(text).text_style(named(CAPTION_STYLE))
}

pub(crate) fn caption_font() -> FontId {
FontId::new(CAPTION_PT, FontFamily::Proportional)
}

#[cfg(test)]
pub(crate) fn test_context() -> egui::Context {
let ctx = egui::Context::default();
Expand Down
168 changes: 18 additions & 150 deletions crates/app/src/ui/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ use identity::command_identity;
pub(crate) use identity::recent_entry_label;
mod helpers;
pub(super) use helpers::chart_plot_target;
use helpers::{has_active_plot, requires, selected_paths_unlocked, tool_commands};
use helpers::{has_active_plot, requires, selected_paths_unlocked};
mod ribbon;
mod roster;
use ribbon::ribbon_placement;
pub use ribbon::{Applicability, RibbonPlacement};
use roster::command_ids;
pub(crate) const MANUAL_URL: &str = "https://docs.plotx.nmrtist.space/";
/// The public source repository, linked from About.
pub(crate) const REPOSITORY_URL: &str = "https://github.com/nmrtist/plotx";
Expand Down Expand Up @@ -155,163 +157,29 @@ pub struct CommandDescriptor {
}

pub fn catalog(app: &PlotxApp) -> Vec<CommandDescriptor> {
let mut ids = vec![
CommandId::NewProject,
CommandId::OpenProject,
CommandId::CloseProject,
CommandId::OpenFile,
CommandId::OpenFolder,
CommandId::RunBatchWorkflow,
CommandId::RunScientificScript,
CommandId::ClearRecentFiles,
CommandId::HelpManual,
CommandId::ImportTable,
CommandId::ImportImage,
CommandId::ImportImageFirstFrame,
CommandId::ImportImageWithoutMetadata,
CommandId::ImportTiffPages,
CommandId::PasteImage,
CommandId::CancelImageImport,
CommandId::ReplaceImage,
CommandId::PasteTable,
CommandId::SaveProject,
CommandId::NewTable,
CommandId::ExportData,
CommandId::CopyFigure,
CommandId::Quit,
CommandId::Undo,
CommandId::Redo,
CommandId::SelectAll,
CommandId::DeselectAll,
CommandId::Group,
CommandId::Ungroup,
CommandId::CreatePanel,
CommandId::ComposePanel,
CommandId::DissolvePanel,
CommandId::DeletePanel,
CommandId::DuplicatePanel,
CommandId::MergePanels,
CommandId::SplitPanel,
CommandId::ReorderPanelLabels,
CommandId::SetPanelLayout(plotx_core::state::PanelLayout::Free),
CommandId::SetPanelLayout(plotx_core::state::PanelLayout::VerticalStack),
CommandId::SetPanelLayout(plotx_core::state::PanelLayout::HorizontalStack),
CommandId::SetPanelLayout(plotx_core::state::PanelLayout::Grid { rows: 2, cols: 2 }),
CommandId::TogglePrimarySidebar,
CommandId::ToggleSecondarySidebar,
CommandId::ZoomToFit,
CommandId::ZoomToSelection,
CommandId::FitPlotY,
CommandId::FitPlotXY,
CommandId::UiScaleUp,
CommandId::UiScaleDown,
CommandId::UiScaleReset,
CommandId::Present,
CommandId::ToggleGrid,
CommandId::ToggleSnap,
CommandId::Preferences,
CommandId::CommandPalette,
CommandId::CheckUpdates,
CommandId::OperationHistory,
CommandId::About,
CommandId::SaveProcessingTemplate,
CommandId::ApplyProcessingTemplate,
CommandId::Craft,
CommandId::RunCraft,
CommandId::CraftComponentTable,
CommandId::SpectrumArithmetic,
CommandId::AlignSpectra,
CommandId::AlignTraces,
CommandId::StackData,
CommandId::ExtractMassSpectrum,
CommandId::SelectRange,
CommandId::ClearRange,
CommandId::Regions,
CommandId::SeriesTable,
CommandId::DetectPeaks,
CommandId::PeakList,
CommandId::LineFit,
CommandId::RunPeakFit,
CommandId::CurveFit,
CommandId::RunCurveFit,
CommandId::Statistics,
CommandId::ChartType,
CommandId::FigureTypography,
CommandId::Integrate,
CommandId::Multiplets,
CommandId::TidyBoard,
CommandId::CanvasSettings,
CommandId::SimplifyInnerAxes,
];
ids.extend((0..app.session.recent_files.len()).map(CommandId::OpenRecent));
ids.extend(
plotx_core::templates::CanvasTemplate::all()
.iter()
.enumerate()
.map(|(i, _)| CommandId::NewCanvas(i)),
);
ids.extend([SpacingMode::Frame, SpacingMode::Visual].map(CommandId::SetSpacingMode));
ids.extend(GutterPreset::ALL.map(CommandId::SetGutterPreset));
ids.extend(
[
ExportFormat::Svg,
ExportFormat::Pdf,
ExportFormat::Png,
ExportFormat::Jpeg,
ExportFormat::Tiff,
]
command_ids(app.session.recent_files.len())
.into_iter()
.map(CommandId::Export),
);
ids.extend(
plotx_core::state::size_presets()
.iter()
.map(|preset| CommandId::SetCanvasSizePreset(preset.id)),
);
ids.extend(
plotx_core::layout::GRID_PRESETS
.iter()
.map(|&(_, rows, cols)| CommandId::ArrangeGrid(rows, cols)),
);
ids.extend([
CommandId::Align(Align::Left),
CommandId::Align(Align::HCenter),
CommandId::Align(Align::Right),
CommandId::Align(Align::Top),
CommandId::Align(Align::VCenter),
CommandId::Align(Align::Bottom),
CommandId::Distribute(Distribute::Horizontal),
CommandId::Distribute(Distribute::Vertical),
CommandId::ZOrder(ZOrder::Front),
CommandId::ZOrder(ZOrder::Forward),
CommandId::ZOrder(ZOrder::Backward),
CommandId::ZOrder(ZOrder::Back),
]);
ids.extend(
plotx_core::theme::Theme::all()
.into_iter()
.map(|theme| CommandId::ApplyTheme(theme.id)),
);
// Every declared property group, and the step gesture. Both are derived
// from the property catalog: a group declared once appears here, and a
// property that declares itself steppable is driven by the existing
// binding without any new command.
ids.extend(
super::properties::GROUPS
.iter()
.map(|group| CommandId::PropertyGroup(group.section)),
);
ids.extend([PropertyStep::Lower, PropertyStep::Raise].map(CommandId::StepProperty));
ids.push(CommandId::CycleCursor);
ids.extend(tool_commands().into_iter().map(CommandId::Tool));
ids.into_iter()
.map(|id| {
debug_assert!(!id.stable_id().is_empty());
describe(app, id)
})
.collect()
}

/// Every (tab, group) pair the Ribbon placement tables can produce, so layout
/// tests stay exhaustive as placements evolve.
#[cfg(test)]
pub(super) fn ribbon_group_pairs() -> Vec<(plotx_core::state::WorkflowTab, &'static str)> {
let mut pairs: Vec<_> = command_ids(0)
.into_iter()
.filter_map(ribbon_placement)
.map(|placement| (placement.tab, placement.group))
.collect();
pairs.sort_by_key(|&(tab, group)| (tab as u8, group));
pairs.dedup();
pairs
}

pub fn describe(app: &PlotxApp, id: CommandId) -> CommandDescriptor {
let has_canvas = app.session.active_canvas.is_some();
let selected = app.session.ui.selection.objects().len();
Expand Down
Loading
Loading