pub fn clear_lines(line_count: usize) -> Result<()>Expand description
Clear the specified number of lines from the terminal
Examples found in repository?
examples/inline-playback.rs (line 337)
309fn create_inline_frame_menu() -> cactui::KeyMenuConfig<PlaybackSession> {
310 cactui::KeyMenuConfig {
311 header_lines: Some(Box::new(|session: &PlaybackSession| {
312 get_frame_header_lines(session)
313 })),
314 items: vec![
315 cactui::KeyMenuItem {
316 key: KeyCode::Char('e'),
317 description: "edit description".to_string(),
318 color: Some(Color::Cyan),
319 action: cactui::MenuAction::Callback {
320 callback: Box::new(|session, line_counts| {
321 // Get current description for placeholder
322 let current_desc = session
323 .frame_descriptions
324 .get(&session.current_frame_num)
325 .map(|s| s.as_str());
326
327 // Calculate how many lines the current description takes up
328 let current_description = session
329 .frame_descriptions
330 .get(&session.current_frame_num)
331 .map(|s| s.as_str())
332 .unwrap_or("(none)");
333 let current_lines_to_clear =
334 calculate_description_lines(current_description)?;
335
336 // Clear the description lines so we can draw over them with our InlinePrompt
337 cactui::inline_keymenu::clear_lines(current_lines_to_clear)?;
338 // Call the inline input with escape-to-exit mode for multi-line descriptions
339 let mut opts = InlineInputOpts::new().escape_to_exit();
340 if current_desc.is_some() {
341 opts = opts.placeholder(current_desc.unwrap());
342 };
343 let new_desc = InlinePrompt::input("Description:", Some(opts))?;
344 // Update line_counts.header to reflect the new header size
345 let new_lines_to_clear = calculate_description_lines(&new_desc)?;
346 if new_lines_to_clear > current_lines_to_clear {
347 line_counts.header += new_lines_to_clear - current_lines_to_clear
348 } else if new_lines_to_clear < current_lines_to_clear {
349 line_counts.header = line_counts
350 .header
351 .saturating_sub(current_lines_to_clear - new_lines_to_clear)
352 }
353
354 // Update description in session
355 if !new_desc.is_empty() {
356 session
357 .frame_descriptions
358 .insert(session.current_frame_num, new_desc);
359 } else {
360 session
361 .frame_descriptions
362 .remove(&session.current_frame_num);
363 }
364
365 Ok(cactui::MenuResult::Stay)
366 }),
367 clear_menu: true,
368 },
369 },
370 cactui::KeyMenuItem {
371 key: KeyCode::Char('c'),
372 description: "channels".to_string(),
373 color: Some(Color::Cyan),
374 action: cactui::MenuAction::Submenu(cactui::KeyMenuConfig {
375 header_lines: Some(Box::new(|session: &PlaybackSession| {
376 get_frame_header_lines(session)
377 })),
378 items: vec![
379 cactui::KeyMenuItem {
380 key: KeyCode::Char('1'),
381 description: "fg red".to_string(),
382 color: Some(Color::Red),
383 action: cactui::MenuAction::Callback {
384 callback: Box::new(|session, _| {
385 session.get_current_channels_mut().fg_red =
386 !session.get_current_channels().fg_red;
387 Ok(cactui::MenuResult::Stay)
388 }),
389 clear_menu: false,
390 },
391 },
392 cactui::KeyMenuItem {
393 key: KeyCode::Char('2'),
394 description: "fg green".to_string(),
395 color: Some(Color::Green),
396 action: cactui::MenuAction::Callback {
397 callback: Box::new(|session, _| {
398 session.get_current_channels_mut().fg_green =
399 !session.get_current_channels().fg_green;
400 Ok(cactui::MenuResult::Stay)
401 }),
402 clear_menu: false,
403 },
404 },
405 cactui::KeyMenuItem {
406 key: KeyCode::Char('3'),
407 description: "fg blue".to_string(),
408 color: Some(Color::Blue),
409 action: cactui::MenuAction::Callback {
410 callback: Box::new(|session, _| {
411 session.get_current_channels_mut().fg_blue =
412 !session.get_current_channels().fg_blue;
413 Ok(cactui::MenuResult::Stay)
414 }),
415 clear_menu: false,
416 },
417 },
418 cactui::KeyMenuItem {
419 key: KeyCode::Char('4'),
420 description: "bg red".to_string(),
421 color: Some(Color::Red),
422 action: cactui::MenuAction::Callback {
423 callback: Box::new(|session, _| {
424 session.get_current_channels_mut().bg_red =
425 !session.get_current_channels().bg_red;
426 Ok(cactui::MenuResult::Stay)
427 }),
428 clear_menu: false,
429 },
430 },
431 cactui::KeyMenuItem {
432 key: KeyCode::Char('5'),
433 description: "bg green".to_string(),
434 color: Some(Color::Green),
435 action: cactui::MenuAction::Callback {
436 callback: Box::new(|session, _| {
437 session.get_current_channels_mut().bg_green =
438 !session.get_current_channels().bg_green;
439 Ok(cactui::MenuResult::Stay)
440 }),
441 clear_menu: false,
442 },
443 },
444 cactui::KeyMenuItem {
445 key: KeyCode::Char('6'),
446 description: "bg blue".to_string(),
447 color: Some(Color::Blue),
448 action: cactui::MenuAction::Callback {
449 callback: Box::new(|session, _| {
450 session.get_current_channels_mut().bg_blue =
451 !session.get_current_channels().bg_blue;
452 Ok(cactui::MenuResult::Stay)
453 }),
454 clear_menu: false,
455 },
456 },
457 cactui::KeyMenuItem {
458 key: KeyCode::Char('7'),
459 description: "mods".to_string(),
460 color: Some(Color::White),
461 action: cactui::MenuAction::Callback {
462 callback: Box::new(|session, _| {
463 session.get_current_channels_mut().modifiers =
464 !session.get_current_channels().modifiers;
465 Ok(cactui::MenuResult::Stay)
466 }),
467 clear_menu: false,
468 },
469 },
470 cactui::KeyMenuItem {
471 key: KeyCode::Esc,
472 description: "return".to_string(),
473 color: None,
474 action: cactui::MenuAction::Exit,
475 },
476 ],
477 should_loop: true,
478 }),
479 },
480 cactui::KeyMenuItem {
481 key: KeyCode::Enter,
482 description: "next frame".to_string(),
483 color: Some(Color::Cyan),
484 action: cactui::MenuAction::ExitKeepHeader,
485 },
486 ],
487 should_loop: true,
488 }
489}