parent
5f0e1732c1
commit
f99337cb9a
2 changed files with 47 additions and 24 deletions
|
|
@ -93,6 +93,20 @@ mod util;
|
|||
mod viewport;
|
||||
|
||||
impl OpenCADStudio {
|
||||
fn sync_open_command_history(&mut self) {
|
||||
if !self.command_line.history_open {
|
||||
return;
|
||||
}
|
||||
let latest = self.command_line.history_plain_text();
|
||||
if self.history_content.text() == latest {
|
||||
return;
|
||||
}
|
||||
use iced::widget::text_editor::{Action, Motion};
|
||||
self.history_content = iced::widget::text_editor::Content::with_text(&latest);
|
||||
self.history_content
|
||||
.perform(Action::Move(Motion::DocumentEnd));
|
||||
}
|
||||
|
||||
/// Close the active in-canvas modal (Plan B), mirroring what closing the
|
||||
/// old OS window did: a style editor discards its staged (un-applied)
|
||||
/// changes, and the ribbon tool that launched the dialog is de-highlighted.
|
||||
|
|
@ -178,6 +192,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
let task = self.update_inner(msg);
|
||||
self.sync_open_command_history();
|
||||
// Close the document-level first-touch transaction started by
|
||||
// push_undo_snapshot at this message boundary.
|
||||
self.finish_all_pending_history();
|
||||
|
|
@ -1295,17 +1310,7 @@ impl OpenCADStudio {
|
|||
|
||||
Message::CommandHistoryToggle => {
|
||||
self.command_line.toggle_history();
|
||||
// On open, snapshot the current log into the read-only editor
|
||||
// buffer so it can be drag-selected across lines and copied.
|
||||
if self.command_line.history_open {
|
||||
use iced::widget::text_editor::{Action, Motion};
|
||||
self.history_content = iced::widget::text_editor::Content::with_text(
|
||||
&self.command_line.history_plain_text(),
|
||||
);
|
||||
// Scroll to the newest line (bottom), the most useful when
|
||||
// opening the log to grab a recent error.
|
||||
self.history_content.perform(Action::Move(Motion::DocumentEnd));
|
||||
}
|
||||
self.sync_open_command_history();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use iced::time::Instant;
|
|||
use crate::app::Message;
|
||||
use crate::command::CmdOption;
|
||||
use iced::widget::{
|
||||
button, column, container, opaque, row, text, text_editor, text_input, tooltip, Space,
|
||||
button, column, container, opaque, row, rule, text, text_editor, text_input, tooltip, Space,
|
||||
};
|
||||
use iced::{Background, Border, Color, Element, Length, Theme};
|
||||
|
||||
|
|
@ -361,11 +361,18 @@ impl CommandLine {
|
|||
// Only the most recent entries pushed within the last few
|
||||
// seconds show on the overlay. The dropdown button keeps the
|
||||
// full backlog reachable when the user actually wants it.
|
||||
let visible: Vec<&HistoryEntry> = self
|
||||
let mut visible: Vec<&HistoryEntry> = self
|
||||
.history
|
||||
.iter()
|
||||
.filter(|e| e.pinned || e.created_at.elapsed().as_secs_f32() < HISTORY_VISIBLE_SECS)
|
||||
.collect();
|
||||
// Keep the active prompt/options immediately above the input. Commands
|
||||
// may emit informational lines while waiting for the next option; those
|
||||
// lines belong above the pinned interaction row, not below it.
|
||||
if let Some(index) = visible.iter().position(|entry| entry.pinned) {
|
||||
let pinned = visible.remove(index);
|
||||
visible.push(pinned);
|
||||
}
|
||||
let start = visible.len().saturating_sub(4);
|
||||
let history_rows = visible[start..]
|
||||
.iter()
|
||||
|
|
@ -602,7 +609,6 @@ impl CommandLine {
|
|||
.width(Length::Fill)
|
||||
.padding([2, 6]);
|
||||
let panel = container(column![header, log])
|
||||
.style(container::bordered_box)
|
||||
.width(Length::Fill)
|
||||
.padding([4, 0]);
|
||||
opaque(panel).into()
|
||||
|
|
@ -610,9 +616,12 @@ impl CommandLine {
|
|||
container(column![]).height(0).into()
|
||||
};
|
||||
|
||||
container(column![
|
||||
autocomplete,
|
||||
dropdown,
|
||||
// The transient recent lines and the full archive are two views of the
|
||||
// same history. Showing both while the archive is open creates a fake
|
||||
// second history region and visually disconnects the input row (#555).
|
||||
let recent_history: Element<'a, Message> = if self.history_open {
|
||||
container(column![]).height(0).into()
|
||||
} else {
|
||||
container(history_rows)
|
||||
.style(|theme: &Theme| container::Style {
|
||||
background: Some(Background::Color(
|
||||
|
|
@ -621,17 +630,25 @@ impl CommandLine {
|
|||
..Default::default()
|
||||
})
|
||||
.width(Length::Fill)
|
||||
.padding([2, 0]),
|
||||
.padding([2, 0])
|
||||
.into()
|
||||
};
|
||||
let history_divider: Element<'a, Message> = if self.history_open {
|
||||
rule::horizontal(1).into()
|
||||
} else {
|
||||
container(column![]).height(0).into()
|
||||
};
|
||||
|
||||
container(column![
|
||||
autocomplete,
|
||||
dropdown,
|
||||
recent_history,
|
||||
history_divider,
|
||||
container(input_row)
|
||||
.style(|theme: &Theme| {
|
||||
let palette = theme.extended_palette();
|
||||
container::Style {
|
||||
background: Some(Background::Color(palette.background.weakest.color)),
|
||||
border: Border {
|
||||
color: palette.background.neutral.color,
|
||||
width: 1.0,
|
||||
radius: 3.0.into()
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
})
|
||||
|
|
@ -652,7 +669,8 @@ impl CommandLine {
|
|||
..Default::default()
|
||||
}
|
||||
})
|
||||
.width(Length::Fixed(720.0))
|
||||
.width(Length::Fill)
|
||||
.max_width(720.0)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue