344 lines
9.2 KiB
Rust
344 lines
9.2 KiB
Rust
//! Eine Befehlsliste für Menü, Tastatur und Statusleiste.
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum Command {
|
|
NewProject,
|
|
OpenProject,
|
|
SaveProject,
|
|
NewForm,
|
|
NewModule,
|
|
AddFile,
|
|
RemoveFile,
|
|
SaveFile,
|
|
SaveAs,
|
|
LoadText,
|
|
SaveText,
|
|
Print,
|
|
Shell,
|
|
Exit,
|
|
Undo,
|
|
Cut,
|
|
Copy,
|
|
Paste,
|
|
Clear,
|
|
Procedures,
|
|
PreviousCode,
|
|
Diagnostics,
|
|
NewSub,
|
|
NewFunction,
|
|
Events,
|
|
Code,
|
|
Form,
|
|
NextStatement,
|
|
OutputScreen,
|
|
IncludedFile,
|
|
IncludedLines,
|
|
MenuBar,
|
|
Grid,
|
|
Find,
|
|
SelectedText,
|
|
FindNext,
|
|
Replace,
|
|
Start,
|
|
Restart,
|
|
Continue,
|
|
Pause,
|
|
CommandLine,
|
|
MakeExe,
|
|
MakeLibrary,
|
|
Startup,
|
|
AddWatch,
|
|
InstantWatch,
|
|
Watchpoint,
|
|
DeleteWatch,
|
|
DeleteWatches,
|
|
Trace,
|
|
History,
|
|
Breakpoint,
|
|
ClearBreakpoints,
|
|
BreakErrors,
|
|
SetStatement,
|
|
RunToCursor,
|
|
Step,
|
|
ProcedureStep,
|
|
HistoryBack,
|
|
HistoryForward,
|
|
Display,
|
|
Paths,
|
|
RightMouse,
|
|
SaveOptions,
|
|
SyntaxChecking,
|
|
NewWindow,
|
|
Arrange,
|
|
Calls,
|
|
Debug,
|
|
HelpWindow,
|
|
Immediate,
|
|
Output,
|
|
Project,
|
|
Palette,
|
|
MenuDesign,
|
|
Toolbox,
|
|
Tool(&'static str),
|
|
HelpIndex,
|
|
HelpContents,
|
|
Keyboard,
|
|
Topic,
|
|
UsingHelp,
|
|
Tutorial,
|
|
About,
|
|
NextWindow,
|
|
PreviousWindow,
|
|
CloseWindow,
|
|
MoveWindow,
|
|
SizeWindow,
|
|
Minimize,
|
|
Maximize,
|
|
Restore,
|
|
ControlMenu,
|
|
FocusWindow(u64),
|
|
}
|
|
impl Command {
|
|
pub fn feature_phase(self) -> Option<u8> {
|
|
use Command::*;
|
|
match self {
|
|
NextStatement | AddWatch | InstantWatch | Watchpoint | DeleteWatch | DeleteWatches
|
|
| Trace | History | Breakpoint | ClearBreakpoints | BreakErrors | SetStatement
|
|
| RunToCursor | Step | ProcedureStep | HistoryBack | HistoryForward => Some(6),
|
|
HelpIndex | HelpContents | Keyboard | Topic | UsingHelp | Tutorial => Some(7),
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
#[derive(Debug, Clone)]
|
|
pub struct Item {
|
|
/// & markiert das sichtbare Mnemonic, … einen Dialog.
|
|
pub label: String,
|
|
pub command: Option<Command>,
|
|
}
|
|
impl Item {
|
|
pub fn text(&self) -> String {
|
|
self.label.replace('&', "")
|
|
}
|
|
pub fn mnemonic(&self) -> Option<char> {
|
|
self.label
|
|
.split_once('&')?
|
|
.1
|
|
.chars()
|
|
.next()
|
|
.map(|c| c.to_ascii_lowercase())
|
|
}
|
|
}
|
|
pub struct Menu {
|
|
pub title: &'static str,
|
|
pub mnemonic: char,
|
|
pub items: Vec<Item>,
|
|
}
|
|
pub fn menus(designer: bool) -> Vec<Menu> {
|
|
use Command::*;
|
|
let item = |label: &str, command| Item {
|
|
label: label.into(),
|
|
command: Some(command),
|
|
};
|
|
let sep = || Item {
|
|
label: "────────".into(),
|
|
command: None,
|
|
};
|
|
let menu = |title, mnemonic, items| Menu {
|
|
title,
|
|
mnemonic,
|
|
items,
|
|
};
|
|
let mut result = vec![
|
|
menu(
|
|
"File",
|
|
'f',
|
|
vec![
|
|
item("&New Project", NewProject),
|
|
item("&Open Project…", OpenProject),
|
|
item("Save &Project", SaveProject),
|
|
sep(),
|
|
item("New &Form", NewForm),
|
|
item("New &Module…", NewModule),
|
|
item("&Add File…", AddFile),
|
|
item("&Remove File…", RemoveFile),
|
|
item("&Save File", SaveFile),
|
|
item("Sa&ve File As…", SaveAs),
|
|
sep(),
|
|
item("&Load Text…", LoadText),
|
|
item("Save &Text…", SaveText),
|
|
sep(),
|
|
item("Pr&int…", Print),
|
|
item("S&hell", Shell),
|
|
sep(),
|
|
item("E&xit", Exit),
|
|
],
|
|
),
|
|
menu(
|
|
"Edit",
|
|
'e',
|
|
vec![
|
|
item("&Undo", Undo),
|
|
sep(),
|
|
item("Cu&t", Cut),
|
|
item("&Copy", Copy),
|
|
item("&Paste", Paste),
|
|
item("C&lear", Clear),
|
|
sep(),
|
|
item("New &Sub…", NewSub),
|
|
item("New &Function…", NewFunction),
|
|
item("&Event Procedures…", Events),
|
|
],
|
|
),
|
|
menu(
|
|
"View",
|
|
'v',
|
|
vec![
|
|
item("&Code…", Code),
|
|
item("&Procedures…", Procedures),
|
|
item("Diagno&stics…", Diagnostics),
|
|
item("&Form…", Form),
|
|
sep(),
|
|
item("&Next Statement", NextStatement),
|
|
item("&Output Screen", OutputScreen),
|
|
sep(),
|
|
item("&Included File", IncludedFile),
|
|
item("Included &Lines", IncludedLines),
|
|
],
|
|
),
|
|
];
|
|
if designer {
|
|
result[2]
|
|
.items
|
|
.extend([sep(), item("&Menu Bar", MenuBar), item("&Grid Lines", Grid)]);
|
|
result.push(menu("Tools", 't', {
|
|
let mut used = std::collections::BTreeSet::new();
|
|
crate::designer::tools()
|
|
.into_iter()
|
|
.map(|(name, _, _)| {
|
|
let mut label = name.to_owned();
|
|
if let Some((at, c)) = name
|
|
.char_indices()
|
|
.find(|(_, c)| !used.contains(&c.to_ascii_lowercase()))
|
|
{
|
|
used.insert(c.to_ascii_lowercase());
|
|
label.insert(at, '&');
|
|
} else {
|
|
let c = ('1'..='9').find(|c| !used.contains(c)).unwrap();
|
|
used.insert(c);
|
|
label = format!("&{c} {label}");
|
|
}
|
|
Item {
|
|
label,
|
|
command: Some(Tool(name)),
|
|
}
|
|
})
|
|
.collect()
|
|
}));
|
|
} else {
|
|
result.extend([
|
|
menu(
|
|
"Search",
|
|
's',
|
|
vec![
|
|
item("&Find…", Find),
|
|
item("&Selected Text", SelectedText),
|
|
item("&Repeat Last Find", FindNext),
|
|
item("&Change…", Replace),
|
|
],
|
|
),
|
|
menu(
|
|
"Run",
|
|
'r',
|
|
vec![
|
|
item("&Start", Start),
|
|
item("&Restart", Restart),
|
|
item("&Continue", Continue),
|
|
item("&Pause (Ctrl+Break)", Pause),
|
|
item("Modify COMMAND&$…", CommandLine),
|
|
sep(),
|
|
item("Make &EXE File…", MakeExe),
|
|
item("Make &Library…", MakeLibrary),
|
|
sep(),
|
|
item("Set Start-&up File…", Startup),
|
|
],
|
|
),
|
|
menu(
|
|
"Debug",
|
|
'd',
|
|
vec![
|
|
item("&Add Watch…", AddWatch),
|
|
item("&Instant Watch…", InstantWatch),
|
|
item("&Watchpoint…", Watchpoint),
|
|
item("&Delete Watch…", DeleteWatch),
|
|
item("Delete A&ll Watch", DeleteWatches),
|
|
sep(),
|
|
item("&Trace On", Trace),
|
|
item("&History On", History),
|
|
sep(),
|
|
item("Toggle &Breakpoint", Breakpoint),
|
|
item("&Clear All Breakpoints", ClearBreakpoints),
|
|
item("Break on &Errors", BreakErrors),
|
|
item("Set &Next Statement", SetStatement),
|
|
],
|
|
),
|
|
]);
|
|
}
|
|
result.push(menu(
|
|
"Options",
|
|
'o',
|
|
vec![
|
|
item("&Display…", Display),
|
|
item("Set &Paths…", Paths),
|
|
item("&Right Mouse…", RightMouse),
|
|
item("&Save…", SaveOptions),
|
|
item("S&yntax Checking", SyntaxChecking),
|
|
],
|
|
));
|
|
result.push(if designer {
|
|
menu(
|
|
"Window",
|
|
'w',
|
|
vec![
|
|
item("&Color Palette", Palette),
|
|
item("&Menu Design Window", MenuDesign),
|
|
item("&Toolbox", Toolbox),
|
|
item("&Help", HelpWindow),
|
|
],
|
|
)
|
|
} else {
|
|
menu(
|
|
"Window",
|
|
'w',
|
|
vec![
|
|
item("&New Window", NewWindow),
|
|
item("&Arrange All", Arrange),
|
|
sep(),
|
|
item("&Calls", Calls),
|
|
item("&Debug", Debug),
|
|
item("&Help", HelpWindow),
|
|
item("&Immediate", Immediate),
|
|
item("&Output", Output),
|
|
item("&Project", Project),
|
|
sep(),
|
|
],
|
|
)
|
|
});
|
|
result.push(menu(
|
|
"Help",
|
|
'h',
|
|
vec![
|
|
item("&Index", HelpIndex),
|
|
item("&Contents", HelpContents),
|
|
sep(),
|
|
item("&Keyboard", Keyboard),
|
|
sep(),
|
|
item("&Topic", Topic),
|
|
item("&Using Help", UsingHelp),
|
|
item("Tuto&rial", Tutorial),
|
|
sep(),
|
|
item("&About…", About),
|
|
],
|
|
));
|
|
result
|
|
}
|