mirror of
https://github.com/microsoft/edit.git
synced 2026-06-14 06:43:49 -05:00
Implement menubar checkboxes
This commit is contained in:
@@ -354,10 +354,12 @@ impl TextBuffer {
|
||||
|
||||
// NOTE: It's expected that the tui code calls `set_width()` sometime after this.
|
||||
// This will then trigger the actual recalculation of the cursor position.
|
||||
pub fn toggle_word_wrap(&mut self) {
|
||||
self.word_wrap_enabled = !self.word_wrap_enabled;
|
||||
self.width = 0; // Force a reflow.
|
||||
self.make_cursor_visible();
|
||||
pub fn set_word_wrap(&mut self, enabled: bool) {
|
||||
if self.word_wrap_enabled != enabled {
|
||||
self.word_wrap_enabled = enabled;
|
||||
self.width = 0; // Force a reflow.
|
||||
self.make_cursor_visible();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_width(&mut self, width: CoordType) -> bool {
|
||||
|
||||
33
src/main.rs
33
src/main.rs
@@ -528,46 +528,46 @@ fn draw_menubar(ctx: &mut Context, state: &mut State) {
|
||||
}
|
||||
|
||||
fn draw_menu_file(ctx: &mut Context, state: &mut State) {
|
||||
if ctx.menubar_menu_item(loc(LocId::FileOpen), 'O', kbmod::CTRL | vk::O) {
|
||||
if ctx.menubar_menu_button(loc(LocId::FileOpen), 'O', kbmod::CTRL | vk::O) {
|
||||
state.wants_file_picker = StateFilePicker::Open;
|
||||
}
|
||||
if ctx.menubar_menu_item(loc(LocId::FileSave), 'S', kbmod::CTRL | vk::S) {
|
||||
if ctx.menubar_menu_button(loc(LocId::FileSave), 'S', kbmod::CTRL | vk::S) {
|
||||
state.wants_file_picker = StateFilePicker::Save;
|
||||
}
|
||||
if ctx.menubar_menu_item(loc(LocId::FileSaveAs), 'A', vk::NULL) {
|
||||
if ctx.menubar_menu_button(loc(LocId::FileSaveAs), 'A', vk::NULL) {
|
||||
state.wants_file_picker = StateFilePicker::SaveAs;
|
||||
}
|
||||
if ctx.menubar_menu_item(loc(LocId::FileExit), 'X', kbmod::CTRL | vk::Q) {
|
||||
if ctx.menubar_menu_button(loc(LocId::FileExit), 'X', kbmod::CTRL | vk::Q) {
|
||||
state.wants_exit = true;
|
||||
}
|
||||
ctx.menubar_menu_end();
|
||||
}
|
||||
|
||||
fn draw_menu_edit(ctx: &mut Context, state: &mut State) {
|
||||
if ctx.menubar_menu_item(loc(LocId::EditUndo), 'U', kbmod::CTRL | vk::Z) {
|
||||
if ctx.menubar_menu_button(loc(LocId::EditUndo), 'U', kbmod::CTRL | vk::Z) {
|
||||
state.buffer.borrow_mut().undo();
|
||||
ctx.needs_rerender();
|
||||
}
|
||||
if ctx.menubar_menu_item(loc(LocId::EditRedo), 'R', kbmod::CTRL | vk::Y) {
|
||||
if ctx.menubar_menu_button(loc(LocId::EditRedo), 'R', kbmod::CTRL | vk::Y) {
|
||||
state.buffer.borrow_mut().redo();
|
||||
ctx.needs_rerender();
|
||||
}
|
||||
if ctx.menubar_menu_item(loc(LocId::EditCut), 'T', kbmod::CTRL | vk::X) {
|
||||
if ctx.menubar_menu_button(loc(LocId::EditCut), 'T', kbmod::CTRL | vk::X) {
|
||||
ctx.set_clipboard(state.buffer.borrow_mut().extract_selection(true));
|
||||
}
|
||||
if ctx.menubar_menu_item(loc(LocId::EditCopy), 'C', kbmod::CTRL | vk::C) {
|
||||
if ctx.menubar_menu_button(loc(LocId::EditCopy), 'C', kbmod::CTRL | vk::C) {
|
||||
ctx.set_clipboard(state.buffer.borrow_mut().extract_selection(false));
|
||||
}
|
||||
if ctx.menubar_menu_item(loc(LocId::EditPaste), 'P', kbmod::CTRL | vk::V) {
|
||||
if ctx.menubar_menu_button(loc(LocId::EditPaste), 'P', kbmod::CTRL | vk::V) {
|
||||
state.buffer.borrow_mut().write(ctx.get_clipboard(), true);
|
||||
ctx.needs_rerender();
|
||||
}
|
||||
if state.wants_search.kind != StateSearchKind::Disabled {
|
||||
if ctx.menubar_menu_item(loc(LocId::EditFind), 'F', kbmod::CTRL | vk::F) {
|
||||
if ctx.menubar_menu_button(loc(LocId::EditFind), 'F', kbmod::CTRL | vk::F) {
|
||||
state.wants_search.kind = StateSearchKind::Search;
|
||||
state.wants_search.focus = true;
|
||||
}
|
||||
if ctx.menubar_menu_item(loc(LocId::EditReplace), 'R', kbmod::CTRL | vk::R) {
|
||||
if ctx.menubar_menu_button(loc(LocId::EditReplace), 'R', kbmod::CTRL | vk::R) {
|
||||
state.wants_search.kind = StateSearchKind::Replace;
|
||||
state.wants_search.focus = true;
|
||||
}
|
||||
@@ -576,18 +576,21 @@ fn draw_menu_edit(ctx: &mut Context, state: &mut State) {
|
||||
}
|
||||
|
||||
fn draw_menu_view(ctx: &mut Context, state: &mut State) {
|
||||
if ctx.menubar_menu_item(loc(LocId::ViewFocusStatusbar), 'S', vk::NULL) {
|
||||
let mut tb = state.buffer.borrow_mut();
|
||||
let word_wrap = tb.is_word_wrap_enabled();
|
||||
|
||||
if ctx.menubar_menu_button(loc(LocId::ViewFocusStatusbar), 'S', vk::NULL) {
|
||||
state.wants_statusbar_focus = true;
|
||||
}
|
||||
if ctx.menubar_menu_item(loc(LocId::ViewWordWrap), 'W', kbmod::ALT | vk::Z) {
|
||||
state.buffer.borrow_mut().toggle_word_wrap();
|
||||
if ctx.menubar_menu_checkbox(loc(LocId::ViewWordWrap), 'W', kbmod::ALT | vk::Z, word_wrap) {
|
||||
tb.set_word_wrap(!word_wrap);
|
||||
ctx.needs_rerender();
|
||||
}
|
||||
ctx.menubar_menu_end();
|
||||
}
|
||||
|
||||
fn draw_menu_help(ctx: &mut Context, state: &mut State) {
|
||||
if ctx.menubar_menu_item(loc(LocId::HelpAbout), 'A', vk::NULL) {
|
||||
if ctx.menubar_menu_button(loc(LocId::HelpAbout), 'A', vk::NULL) {
|
||||
state.wants_about = true;
|
||||
}
|
||||
ctx.menubar_menu_end();
|
||||
|
||||
42
src/tui.rs
42
src/tui.rs
@@ -2140,7 +2140,7 @@ impl<'a> Context<'a, '_> {
|
||||
vk::Z => match modifiers {
|
||||
kbmod::CTRL => tb.undo(),
|
||||
kbmod::CTRL_SHIFT => tb.redo(),
|
||||
kbmod::ALT => tb.toggle_word_wrap(),
|
||||
kbmod::ALT => tb.set_word_wrap(tb.is_word_wrap_enabled()),
|
||||
_ => return false,
|
||||
},
|
||||
_ => return false,
|
||||
@@ -2458,7 +2458,7 @@ impl<'a> Context<'a, '_> {
|
||||
|
||||
pub fn menubar_menu_begin(&mut self, text: &str, accelerator: char) -> bool {
|
||||
self.next_block_id_mixin(self.tree.current_node.borrow().child_count as u64);
|
||||
self.menubar_label(text, accelerator);
|
||||
self.menubar_label(text, accelerator, None);
|
||||
self.attr_focusable();
|
||||
self.attr_padding(Rect::two(0, 1));
|
||||
|
||||
@@ -2485,7 +2485,22 @@ impl<'a> Context<'a, '_> {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn menubar_menu_item(&mut self, text: &str, accelerator: char, shortcut: InputKey) -> bool {
|
||||
pub fn menubar_menu_button(
|
||||
&mut self,
|
||||
text: &str,
|
||||
accelerator: char,
|
||||
shortcut: InputKey,
|
||||
) -> bool {
|
||||
self.menubar_menu_checkbox(text, accelerator, shortcut, false)
|
||||
}
|
||||
|
||||
pub fn menubar_menu_checkbox(
|
||||
&mut self,
|
||||
text: &str,
|
||||
accelerator: char,
|
||||
shortcut: InputKey,
|
||||
checked: bool,
|
||||
) -> bool {
|
||||
self.table_next_row();
|
||||
self.attr_focusable();
|
||||
if self.is_focused() {
|
||||
@@ -2496,7 +2511,7 @@ impl<'a> Context<'a, '_> {
|
||||
let clicked =
|
||||
self.button_activated() || self.consume_shortcut(InputKey::new(accelerator as u32));
|
||||
|
||||
self.menubar_label(text, accelerator);
|
||||
self.menubar_label(text, accelerator, Some(checked));
|
||||
self.menubar_shortcut(shortcut);
|
||||
|
||||
if clicked {
|
||||
@@ -2573,7 +2588,7 @@ impl<'a> Context<'a, '_> {
|
||||
self.set_input_consumed();
|
||||
}
|
||||
|
||||
fn menubar_label(&mut self, text: &str, accelerator: char) {
|
||||
fn menubar_label(&mut self, text: &str, accelerator: char, checked: Option<bool>) {
|
||||
if !accelerator.is_ascii_uppercase() {
|
||||
self.label("label", Overflow::Clip, text);
|
||||
return;
|
||||
@@ -2594,6 +2609,9 @@ impl<'a> Context<'a, '_> {
|
||||
}
|
||||
|
||||
self.styled_label_begin("label", Overflow::Clip);
|
||||
if let Some(checked) = checked {
|
||||
self.styled_label_add_text(if checked { "▣ " } else { " " });
|
||||
}
|
||||
|
||||
if off < text.len() {
|
||||
// Highlight the accelerator in red.
|
||||
@@ -2614,7 +2632,12 @@ impl<'a> Context<'a, '_> {
|
||||
}
|
||||
|
||||
self.styled_label_end();
|
||||
self.attr_padding(Rect::two(0, 1));
|
||||
self.attr_padding(Rect {
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 2,
|
||||
bottom: 0,
|
||||
});
|
||||
}
|
||||
|
||||
fn menubar_shortcut(&mut self, shortcut: InputKey) {
|
||||
@@ -2633,11 +2656,16 @@ impl<'a> Context<'a, '_> {
|
||||
shortcut_text.push(shortcut_letter);
|
||||
|
||||
self.label("shortcut", Overflow::Clip, &shortcut_text);
|
||||
self.attr_padding(Rect::two(0, 1));
|
||||
} else {
|
||||
self.block_begin("shortcut");
|
||||
self.block_end();
|
||||
}
|
||||
self.attr_padding(Rect {
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 2,
|
||||
bottom: 0,
|
||||
});
|
||||
}
|
||||
|
||||
fn arena(&self) -> &'a Arena {
|
||||
|
||||
Reference in New Issue
Block a user