mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-26 19:36:46 -06:00
M7: preserve active tab and support tab reordering
This commit is contained in:
@@ -92,6 +92,20 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
),
|
||||
spec!("file.placeImage", "Place image", "{path | data, x?, y?}", true, super::create::place_image),
|
||||
spec!("file.close", "Close tab", "{index?, force? (discard unsaved changes)}", false, close),
|
||||
spec!("file.moveTab", "Move tab", "{from, to} (indices among open documents)", false, |s, p| {
|
||||
let from = req_index("file.moveTab", p, "from")?;
|
||||
let to = req_index("file.moveTab", p, "to")?;
|
||||
if from >= s.docs.len() || to >= s.docs.len() {
|
||||
return Err(bad("file.moveTab", "no such document"));
|
||||
}
|
||||
if from != to {
|
||||
let active_uid = s.docs.get(s.active).map(|d| d.uid);
|
||||
let doc = s.docs.remove(from);
|
||||
s.docs.insert(to, doc);
|
||||
s.active = active_uid.and_then(|uid| s.docs.iter().position(|d| d.uid == uid)).unwrap_or(0);
|
||||
}
|
||||
Ok(json!({"index": to}))
|
||||
}),
|
||||
spec!(
|
||||
"file.recover",
|
||||
"Recover file",
|
||||
@@ -1374,14 +1388,36 @@ fn close(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
return Err(EngineError::Disabled("file.close".into(), "the document has unsaved changes (pass force: true to discard)".into()));
|
||||
}
|
||||
let uid = ds.uid;
|
||||
let active_uid = s.docs.get(s.active).map(|d| d.uid);
|
||||
s.docs.remove(i);
|
||||
if s.active >= s.docs.len() {
|
||||
s.active = s.docs.len().saturating_sub(1);
|
||||
}
|
||||
// Removing a tab before the active one shifts its index; keep the same document selected.
|
||||
s.active = active_uid.and_then(|a| s.docs.iter().position(|d| d.uid == a)).unwrap_or(i.min(s.docs.len().saturating_sub(1)));
|
||||
crate::branches::close_tabs(s, uid, None);
|
||||
ok()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tab_order_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn moving_and_closing_inactive_tabs_preserves_the_active_document() {
|
||||
let mut session = Session::new();
|
||||
for name in ["Two", "Three", "Four"] {
|
||||
session.execute("file.new", &json!({"name": name})).unwrap();
|
||||
}
|
||||
session.execute("doc.switch", &json!({"index": 2})).unwrap();
|
||||
let active_uid = session.docs[session.active].uid;
|
||||
let moved_uid = session.docs[0].uid;
|
||||
session.execute("file.moveTab", &json!({"from": 0, "to": 2})).unwrap();
|
||||
assert_eq!(session.docs[2].uid, moved_uid);
|
||||
assert_eq!(session.docs[session.active].uid, active_uid);
|
||||
session.execute("file.close", &json!({"index": 0})).unwrap();
|
||||
assert_eq!(session.docs[session.active].uid, active_uid);
|
||||
assert!(session.execute("file.moveTab", &json!({"from": 0, "to": 99})).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
/// Ctrl+Tab / Ctrl+Shift+Tab: the next or previous open document, wrapping around.
|
||||
fn cycle_doc(s: &mut Session, dir: i64) -> Result<Value> {
|
||||
let n = s.docs.len() as i64;
|
||||
|
||||
@@ -1849,6 +1849,7 @@ status = "draft — needs native review"
|
||||
"file.exportLayers" = "Exportovat vrstvy"
|
||||
"file.exportSvg" = "Exportovat výběr jako SVG"
|
||||
"file.import" = "Importovat"
|
||||
"file.moveTab" = "Přesunout kartu"
|
||||
"file.new" = "Nový soubor návrhu"
|
||||
"file.newFromTemplate" = "Nový ze šablony"
|
||||
"file.open" = "Otevřít"
|
||||
|
||||
@@ -1795,6 +1795,7 @@ status = "draft — needs native review"
|
||||
"file.exportLayers" = "Ebenen exportieren"
|
||||
"file.exportSvg" = "Auswahl als SVG exportieren"
|
||||
"file.import" = "Importieren"
|
||||
"file.moveTab" = "Tab verschieben"
|
||||
"file.new" = "Neue Designdatei"
|
||||
"file.open" = "Öffnen"
|
||||
"file.openRecent" = "Zuletzt verwendete öffnen"
|
||||
|
||||
@@ -1890,6 +1890,7 @@ status = "draft — needs native review"
|
||||
"file.exportLayers" = "Exportar capas"
|
||||
"file.exportSvg" = "Exportar selección como SVG"
|
||||
"file.import" = "Importar"
|
||||
"file.moveTab" = "Mover pestaña"
|
||||
"file.new" = "Nuevo archivo de diseño"
|
||||
"file.newFromTemplate" = "Nuevo desde plantilla"
|
||||
"file.open" = "Abrir"
|
||||
|
||||
@@ -1891,6 +1891,7 @@ status = "draft — needs native review"
|
||||
"file.exportLayers" = "Vie tasot"
|
||||
"file.exportSvg" = "Vie valinta SVG-muodossa"
|
||||
"file.import" = "Tuo"
|
||||
"file.moveTab" = "Siirrä välilehti"
|
||||
"file.new" = "Uusi suunnittelutiedosto"
|
||||
"file.newFromTemplate" = "Uusi mallista"
|
||||
"file.open" = "Avaa"
|
||||
|
||||
@@ -1879,6 +1879,7 @@ status = "draft — needs native review"
|
||||
"file.exportLayers" = "Exporter les calques"
|
||||
"file.exportSvg" = "Exporter la sélection en SVG"
|
||||
"file.import" = "Importer"
|
||||
"file.moveTab" = "Déplacer l’onglet"
|
||||
"file.new" = "Nouveau fichier de design"
|
||||
"file.newFromTemplate" = "Nouveau à partir d’un modèle"
|
||||
"file.open" = "Ouvrir"
|
||||
|
||||
@@ -1853,6 +1853,7 @@ status = "draft — needs native review"
|
||||
"file.exportLayers" = "Ekspor layer"
|
||||
"file.exportSvg" = "Ekspor pilihan sebagai SVG"
|
||||
"file.import" = "Impor"
|
||||
"file.moveTab" = "Pindahkan tab"
|
||||
"file.new" = "File desain baru"
|
||||
"file.newFromTemplate" = "Baru dari templat"
|
||||
"file.open" = "Buka"
|
||||
|
||||
@@ -1864,6 +1864,7 @@ status = "draft — needs native review"
|
||||
"file.exportLayers" = "レイヤーを書き出し"
|
||||
"file.exportSvg" = "選択範囲を SVG で書き出し"
|
||||
"file.import" = "インポート"
|
||||
"file.moveTab" = "タブを移動"
|
||||
"file.new" = "新規デザインファイル"
|
||||
"file.newFromTemplate" = "テンプレートから新規作成"
|
||||
"file.open" = "開く"
|
||||
|
||||
@@ -1786,6 +1786,7 @@ status = "draft — needs native review"
|
||||
"file.exportLayers" = "레이어 내보내기"
|
||||
"file.exportSvg" = "선택 항목을 SVG로 내보내기"
|
||||
"file.import" = "가져오기"
|
||||
"file.moveTab" = "탭 이동"
|
||||
"file.new" = "새 디자인 파일"
|
||||
"file.open" = "열기"
|
||||
"file.openRecent" = "최근 파일 열기"
|
||||
|
||||
@@ -1890,6 +1890,7 @@ status = "draft — needs native review"
|
||||
"file.exportLayers" = "Lagen exporteren"
|
||||
"file.exportSvg" = "Selectie exporteren als SVG"
|
||||
"file.import" = "Importeren"
|
||||
"file.moveTab" = "Tabblad verplaatsen"
|
||||
"file.new" = "Nieuw ontwerpbestand"
|
||||
"file.newFromTemplate" = "Nieuw vanuit sjabloon"
|
||||
"file.open" = "Openen"
|
||||
|
||||
@@ -1785,6 +1785,7 @@ status = "draft — needs native review"
|
||||
"file.exportLayers" = "Exportar camadas"
|
||||
"file.exportSvg" = "Exportar seleção como SVG"
|
||||
"file.import" = "Importar"
|
||||
"file.moveTab" = "Mover aba"
|
||||
"file.new" = "Novo arquivo de design"
|
||||
"file.open" = "Abrir"
|
||||
"file.openRecent" = "Abrir recente"
|
||||
|
||||
@@ -1855,6 +1855,7 @@ name = "Русский"
|
||||
"file.exportLayers" = "Экспортировать слои"
|
||||
"file.exportSvg" = "Экспортировать выделение в SVG"
|
||||
"file.import" = "Импорт"
|
||||
"file.moveTab" = "Переместить вкладку"
|
||||
"file.new" = "Новый файл дизайна"
|
||||
"file.newFromTemplate" = "Создать из шаблона"
|
||||
"file.open" = "Открыть"
|
||||
|
||||
@@ -1872,6 +1872,7 @@ name = "Svenska"
|
||||
"file.exportLayers" = "Exportera lager"
|
||||
"file.exportSvg" = "Exportera som SVG"
|
||||
"file.import" = "Importera"
|
||||
"file.moveTab" = "Flytta flik"
|
||||
"file.new" = "Nytt"
|
||||
"file.newFromTemplate" = "Nytt från mall"
|
||||
"file.open" = "Öppna"
|
||||
|
||||
@@ -1853,6 +1853,7 @@ name = "Türkçe"
|
||||
"file.exportLayers" = "Katmanları dışa aktar"
|
||||
"file.exportSvg" = "Seçimi SVG olarak dışa aktar"
|
||||
"file.import" = "İçe aktar"
|
||||
"file.moveTab" = "Sekmeyi taşı"
|
||||
"file.new" = "Yeni tasarım dosyası"
|
||||
"file.newFromTemplate" = "Şablondan yeni"
|
||||
"file.open" = "Aç"
|
||||
|
||||
@@ -1787,6 +1787,7 @@ status = "draft — needs native review"
|
||||
"file.exportLayers" = "导出图层"
|
||||
"file.exportSvg" = "将所选项导出为 SVG"
|
||||
"file.import" = "导入"
|
||||
"file.moveTab" = "移动标签页"
|
||||
"file.new" = "新建设计文件"
|
||||
"file.open" = "打开"
|
||||
"file.openRecent" = "打开最近的文件"
|
||||
|
||||
Reference in New Issue
Block a user