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