master
svelte 127 lines 3.89 KB
Raw
1 <script lang="ts">
2 import VerticalDots from "carbon-icons-svelte/lib/OverflowMenuVertical.svelte";
3 import Menu from "./utility/Menu.svelte";
4 import TabList from "./Tab/TabList.svelte";
5 import NotSupported from "./utility/NotSupported.svelte";
6 import { Tab } from "./Tab/Tab";
7 import { afterUpdate, onMount } from "svelte";
8 import { appWindow } from "@tauri-apps/api/window";
9 import { writable } from "svelte/store";
10 import { invoke } from "@tauri-apps/api";
11
12 onMount(() => {
13 appWindow.onResized(() => {
14 updateTablistWidth();
15 })
16 })
17
18 afterUpdate(() => {
19 updateTablistWidth();
20 })
21 </script>
22 <script lang="ts" context="module">
23
24 let computedWidth = writable("");
25 let toolbar: HTMLElement = null;
26 let tablist: HTMLElement = null;
27 export function updateTablistWidth() {
28 let tablistwidth = tablist.nextElementSibling.clientWidth;
29 computedWidth.set(`${tablistwidth - toolbar.clientWidth}px`);
30 }
31 let activetabid = null;
32 class EditorTab {
33 id: number;
34 label: string;
35 active: boolean;
36 path: string;
37 content;
38 isfile: boolean;
39 saved = true;
40 constructor(id: number, label = "", content = null, path = "") {
41 this.id = id;
42 this.label = label === "" ? `Untitled-${id}` : label;
43 this.path = path === "" ? this.label : path;
44 this.content = content;
45 }
46 updateView(id) {
47 this.content.$set({ hidden: !(this.id === id) });
48 }
49 refreshView(tab) {
50 if (tab.isfile) {
51 tab.content.updateTheme();
52 }
53 }
54 setActive(id) {
55 editorTab.setActive(id);
56 activetabid = id;
57 }
58 }
59
60 const editorTab = new Tab(EditorTab);
61
62 export function addTab(path?: string, label?: string, content = null) {
63 editorTab.addTab(path, label, content);
64 }
65 export async function addEditorTab(path?: string, label?: string) {
66 if (path && !await invoke("is_supported", {path: path})) {
67 addTab(path, label, new NotSupported({target: document.getElementById("tabview"), props: {path: path}}));
68 return;
69 }
70 editorTab.addEditorTab(path, label);
71 }
72 export async function closeTab(tabid: number) {
73 await editorTab.closeTab(tabid);
74 }
75 export async function closeActiveTab() {
76 await editorTab.closeTab(activetabid);
77 }
78 export function renameTab(tab, label, path) {
79 if (tab) {
80 tab.label = label;
81 tab.path = path;
82 editorTab.setActive(tab.id);
83 }
84 }
85 export async function closeAllTabs() {
86 await editorTab.closeAllTabs();
87 }
88 export function getActiveTab() {
89 return editorTab.activeTab;
90 }
91 export function getCurrentEditor() {
92 return editorTab.activeTab.content;
93 }
94 export function refreshTabs() {
95 editorTab.refreshTabList();
96 }
97
98 export let hidden = editorTab.hidden;
99 export let isfile = editorTab.isfile;
100 export let tabs = editorTab.tabs;
101 </script>
102 <div id="editor-tabs" bind:this={tablist} class:hidden={$hidden}>
103 <TabList width={$computedWidth} tabs={tabs} on:closetab={async (e) => {await closeTab(e.detail.tabid)}} on:select={(e) => {editorTab.setActive(e.detail.tabid)}}></TabList>
104 <div class="tab-toolbar" bind:this={toolbar}>
105 <Menu right menu={{icon: VerticalDots, children: [
106 {name: "Close All Tabs", action: async () => {await closeAllTabs()}},
107 ]}}></Menu>
108 </div>
109 </div>
110
111 <style lang="scss">
112 .hidden {
113 visibility: hidden;
114 }
115 #editor-tabs {
116 width: 100%;
117 display: grid;
118 grid-auto-flow: column;
119 justify-content: space-between;
120 }
121 .tab-toolbar {
122 height: 100%;
123 display: flex;
124 align-items: center;
125 padding: 0 5px;
126 }
127 </style>