feat: Stifte, Seiten löschen, lückenlose Seiten, sauberer Textmarker (Issues #11, #12, #14, #15, #17, #19)
- #15: Koordinatensystem ohne Kerbe am Ursprung (Achsen beginnen eine halbe Linienbreite hinter dem Ursprung; im PDF ein Linienzug mit spitzer Ecke) - #17: Jeder Strich deckt ein Pixel nur einmal (Stencil-Puffer), der Textmarker wird innerhalb eines Strichs nicht dunkler. Im PDF-Export ist der Textmarker jetzt halbtransparent statt deckend. - #11: ➕ in der Werkzeugleiste fügt nach der aktuellen Seite eine Seite ein - #12: Seite löschen im ☰-Menü mit Rückfrage, in der Sitzung wiederherstellbar - #14: Seiten liegen lückenlos untereinander, eine dunkle Linie markiert die Grenze - #19: Vier Stifte mit eigener Farbe und Stärke, die sich Änderungen merken (ui.json); Blätterpfeile nur noch in der Einzelseitenansicht Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1217,6 +1217,29 @@ impl Notebook {
|
||||
index
|
||||
}
|
||||
|
||||
/// Entfernt die aktuelle Seite und gibt sie zurück; danach ist die folgende Seite aktuell
|
||||
/// (bzw. die vorige, wenn es die letzte war). Die einzige Seite eines Notizbuchs bleibt
|
||||
/// stehen (`None`).
|
||||
pub fn remove_current_page(&mut self) -> Option<Page> {
|
||||
if self.pages.len() < 2 {
|
||||
return None;
|
||||
}
|
||||
let page = self.pages.remove(self.current_page_index);
|
||||
self.load_warnings.remove(&page.id);
|
||||
self.current_page_index = self.current_page_index.min(self.pages.len() - 1);
|
||||
Some(page)
|
||||
}
|
||||
|
||||
/// Setzt eine mit [`Self::remove_current_page`] entfernte Seite wieder an `index` ein
|
||||
/// (höchstens ans Ende) und macht sie zur aktuellen Seite; gibt ihren Index zurück.
|
||||
pub fn restore_page(&mut self, index: usize, page: Page) -> usize {
|
||||
let index = index.min(self.pages.len());
|
||||
self.next_page_id = self.next_page_id.max(page.id + 1);
|
||||
self.pages.insert(index, page);
|
||||
self.current_page_index = index;
|
||||
index
|
||||
}
|
||||
|
||||
/// Durchgehende Ansicht: Reicht ein neuer Strich auf der letzten Seite bis in deren
|
||||
/// unteres Fünftel ([`AUTO_APPEND_FRACTION`]), wird darunter eine leere Seite mit gleichem
|
||||
/// Hintergrund angehängt. `true`, wenn eine Seite angehängt wurde.
|
||||
@@ -1982,6 +2005,39 @@ mod tests {
|
||||
assert!(new.pdf_background.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_and_restore_current_page() {
|
||||
let mut nb = Notebook::new();
|
||||
// Die einzige Seite bleibt
|
||||
assert!(nb.remove_current_page().is_none());
|
||||
nb.add_page(PageBackground::Lined);
|
||||
nb.add_page(PageBackground::DotGrid);
|
||||
let ids: Vec<u64> = nb.pages.iter().map(|p| p.id).collect();
|
||||
|
||||
// Mittlere Seite: danach ist die folgende aktuell
|
||||
nb.current_page_index = 1;
|
||||
let removed = nb.remove_current_page().unwrap();
|
||||
assert_eq!(removed.id, ids[1]);
|
||||
assert_eq!(
|
||||
nb.pages.iter().map(|p| p.id).collect::<Vec<_>>(),
|
||||
[ids[0], ids[2]]
|
||||
);
|
||||
assert_eq!(nb.current_page_index, 1);
|
||||
|
||||
// Wiederherstellen an der alten Stelle
|
||||
assert_eq!(nb.restore_page(1, removed), 1);
|
||||
assert_eq!(nb.pages.iter().map(|p| p.id).collect::<Vec<_>>(), ids);
|
||||
assert_eq!(nb.current_page_index, 1);
|
||||
|
||||
// Letzte Seite: danach ist die vorige aktuell
|
||||
nb.current_page_index = 2;
|
||||
let last = nb.remove_current_page().unwrap();
|
||||
assert_eq!(last.id, ids[2]);
|
||||
assert_eq!(nb.current_page_index, 1);
|
||||
// Neue Seiten bekommen keine schon vergebene Kennung
|
||||
assert!(nb.next_page_id > ids[2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_append_page_when_writing_at_bottom_of_last_page() {
|
||||
let mut nb = Notebook::new();
|
||||
|
||||
Reference in New Issue
Block a user