liushengqiang 1 year ago
parent
commit
d0c58a32d1

+ 3 - 2
src/pc/App.tsx

@@ -10,6 +10,7 @@ import {
 	NDialogProvider,
 	NMessageProvider,
 	NNotificationProvider,
+	darkTheme,
 } from "naive-ui";
 import { lighten } from "../utils";
 
@@ -64,10 +65,10 @@ export default defineComponent({
 			// return storeData.status === "login";
 		});
 		return () => (
-			<NConfigProvider inlineThemeDisabled themeOverrides={themeOverrides}>
+			<NConfigProvider inlineThemeDisabled themeOverrides={themeOverrides} abstract>
 				<NDialogProvider>
 					<NNotificationProvider>
-						<NMessageProvider max={1}>
+						<NMessageProvider max={1} theme={darkTheme.Message}>
 							{storeData.status === "error" ? <TheError /> : inited.value ? <RouterView /> : null}
 						</NMessageProvider>
 					</NNotificationProvider>

+ 94 - 0
src/pc/home/component/the-setting/index.module.less

@@ -0,0 +1,94 @@
+.setbox {
+    position: relative;
+    display: flex;
+    flex-direction: column;
+    width: 680px;
+    height: 623px;
+    border-radius: 6px;
+    background: #fff;
+    overflow: hidden;
+}
+
+.head {
+    position: relative;
+    line-height: 53px;
+    height: 53px;
+    text-align: center;
+    background: #F5F6FA;
+    color: #131415;
+    font-weight: 600;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 16px;
+    flex-shrink: 0;
+
+    .close {
+        position: absolute;
+        top: 50%;
+        right: 20px;
+        transform: translateY(-50%);
+    }
+}
+
+.content {
+    flex: 1;
+    overflow: hidden;
+    display: flex;
+
+    .slide {
+        width: 161px;
+        background: #FBFBFB;
+        flex-shrink: 0;
+        border-right: 1px solid #D4D7D9;
+        padding: 14px;
+    }
+
+    .box {
+        flex: 1;
+        overflow: hidden;
+        height: 100%;
+        :global{
+            .n-tabs .n-tabs-nav{
+                display: none;
+            }
+            .n-tabs,
+            .n-tab-pane{
+                padding: 0;
+                height: 100%;
+            }
+        }
+    }
+}
+
+.btn {
+    color: #131415;
+    font-weight: 500 !important;
+    font-size: 14px;
+    justify-content: flex-start;
+    padding: 0 0 0 26px;
+
+    &.activeBtn {
+        --n-color-pressed: #BADCFE;
+        --n-color-hover: #BADCFE;
+        background-color: #BADCFE;
+    }
+}
+
+.btnIcon {
+    width: 17px;
+}
+
+.keyBox{
+    padding: 20px 24px;
+}
+.table{
+    thead th{
+        background-color: #fff;
+        color: #777777;
+    }
+    tbody td{
+        color: #131415;
+        font-weight: 600;
+    }
+}

+ 154 - 9
src/pc/home/component/the-setting/index.tsx

@@ -1,7 +1,25 @@
-import { NIcon, NModal } from "naive-ui";
-import { defineComponent, reactive } from "vue";
+import {
+	NButton,
+	NCard,
+	NIcon,
+	NLayout,
+	NLayoutContent,
+	NLayoutSider,
+	NModal,
+	NRadio,
+	NRadioGroup,
+	NScrollbar,
+	NSpace,
+	NTabPane,
+	NTable,
+	NTabs,
+	useMessage,
+} from "naive-ui";
+import { defineComponent, reactive, watch } from "vue";
 import { Close } from "@vicons/ionicons5";
-
+import styles from "./index.module.less";
+import { getImage } from "../../images";
+import { settings } from "../../runtime";
 export default defineComponent({
 	name: "TheSetting",
 	props: {
@@ -12,18 +30,145 @@ export default defineComponent({
 	},
 	emits: ["update:show"],
 	setup(props, { emit }) {
+		const message = useMessage();
 		const data = reactive({
 			show: false,
+			btns: [
+				{
+					label: "播放设置",
+					key: "1",
+					icon: getImage("icon_28_1.png"),
+				},
+				{
+					label: "快捷键",
+					key: "3",
+					icon: getImage("icon_28_3.png"),
+				},
+			],
+			active: "3",
 		});
+		watch(
+			() => props.show,
+			() => {
+				data.show = props.show;
+			}
+		);
+
+		const keys = [
+			{
+				label: "音程向上",
+				value: "↑",
+			},
+			{
+				label: "音程向下",
+				value: "↓",
+			},
+			{
+				label: "音符C",
+				value: "C",
+			},
+			{
+				label: "音符D",
+				value: "D",
+			},
+			{
+				label: "音符E",
+				value: "E",
+			},
+			{
+				label: "音符F",
+				value: "F",
+			},
+			{
+				label: "音符G",
+				value: "G",
+			},
+			{
+				label: "音符A",
+				value: "A",
+			},
+			{
+				label: "音符B",
+				value: "B",
+			},
+			{
+				label: "BackSpace",
+				value: "删除音符",
+			},
+		];
 		return () => (
-			<NModal show={props.show}>
-				<div>
-					<div>设置</div>
-					<div onClick={() => emit('update:show', false)}>
-						<NIcon component={Close} />
+			<NModal autoFocus={false} show={props.show} onUpdate:show={(val) => emit("update:show", val)}>
+				<div class={styles.setbox}>
+					<div class={styles.head}>
+						<div>设置</div>
+						<NButton
+							class={styles.close}
+							quaternary
+							circle
+							size="small"
+							onClick={() => emit("update:show", false)}
+						>
+							<NIcon component={Close} size={18} />
+						</NButton>
+					</div>
+					<div class={styles.content}>
+						<div class={styles.slide}>
+							<NSpace vertical align="center" wrapItem={false}>
+								{data.btns.map((item) => (
+									<NButton
+										quaternary
+										block
+										class={[styles.btn, data.active === item.key && styles.activeBtn]}
+										onClick={() => (data.active = item.key)}
+									>
+										{{
+											icon: () => <img class={styles.btnIcon} src={item.icon} />,
+											default: () => item.label,
+										}}
+									</NButton>
+								))}
+							</NSpace>
+						</div>
+						<div class={styles.box}>
+							<NTabs v-model:value={data.active}>
+								<NTabPane name="1" tab="1">
+									<div class={styles.keyBox}>
+										<NCard title="光标设置" bordered={false}>
+											<NRadioGroup v-model:value={settings.cursorType}>
+												<NSpace>
+													<NRadio value="beat" disabled>光标跟随节拍</NRadio>
+													<NRadio value="note">光标跟随音符</NRadio>
+												</NSpace>
+											</NRadioGroup>
+										</NCard>
+									</div>
+								</NTabPane>
+								<NTabPane name="3" tab="3">
+									<NScrollbar>
+										<div class={styles.keyBox}>
+											<NTable class={styles.table} striped>
+												<thead>
+													<tr>
+														<th>命令</th>
+														<th>快捷键</th>
+													</tr>
+												</thead>
+												<tbody>
+													{keys.map((item) => (
+														<tr>
+															<td>{item.label}</td>
+															<td>{item.value}</td>
+														</tr>
+													))}
+												</tbody>
+											</NTable>
+										</div>
+									</NScrollbar>
+								</NTabPane>
+							</NTabs>
+						</div>
 					</div>
 				</div>
-				<div></div>
 			</NModal>
 		);
 	},

BIN
src/pc/home/images/icon_28_1.png


BIN
src/pc/home/images/icon_28_2.png


BIN
src/pc/home/images/icon_28_3.png


+ 29 - 26
src/pc/home/index.tsx

@@ -28,6 +28,7 @@ import {
 	NModal,
 	NPopover,
 	NPopselect,
+	NSelect,
 	NSpace,
 	useMessage,
 } from "naive-ui";
@@ -902,7 +903,9 @@ export default defineComponent({
 			handleResetRender();
 		};
 
-		const instruments = ABCJS.synth.instrumentIndexToName;
+		const instruments = computed(() => {
+			return ABCJS.synth.instrumentIndexToName.map((name, index) => ({ label: name, value: index }));
+		});
 		onMounted(async () => {
 			console.log(ABCJS);
 			await handleResetRender();
@@ -1218,34 +1221,34 @@ export default defineComponent({
 
 						<div class={styles.topLine}></div>
 
-						<div class={[styles.topBtn]}>
-							<Trigger trigger="click" v-model:popupVisible={popup.instrument}>
-								{{
-									default: () => (
+						<NPopover
+							v-model:value={popup.moveKeyShow}
+							trigger="click"
+							contentStyle={{ width: "320px" }}
+						>
+							{{
+								trigger: () => (
+									<div class={styles.topBtn}>
 										<div class={styles.btnImg} onClick={() => (popup.instrument = true)}>
 											<img class={styles.topBtnIcon} src={getImage("icon_25.png")} />
 										</div>
-									),
-									content: () => (
-										<div class={styles.instruments}>
-											<div class={styles.instrumentTitle}>选择声部</div>
-											<div class={styles.instrumentItems}>
-												<Select
-													allowSearch
-													v-model={abcData.synthOptions.program}
-													onChange={() => resetMidi()}
-												>
-													{instruments.map((instrument, instrumentIndex) => (
-														<Option label={instrument} value={instrumentIndex}></Option>
-													))}
-												</Select>
-											</div>
-										</div>
-									),
-								}}
-							</Trigger>
-							<div>选择声部</div>
-						</div>
+										<div>选择声部</div>
+									</div>
+								),
+								default: () => (
+									<>
+										<div class={styles.btnLineTitle}>选择声部</div>
+
+										<NSelect
+											filterable
+											options={instruments.value}
+											v-model:value={abcData.synthOptions.program}
+											onChange={() => handleResetRender()}
+										></NSelect>
+									</>
+								),
+							}}
+						</NPopover>
 
 						<NPopover
 							v-model:value={popup.moveKeyShow}

+ 6 - 0
src/pc/home/runtime.ts

@@ -1,3 +1,4 @@
+import { reactive } from "vue";
 import { IAbc, IMeasure, INote } from "../types";
 import { getImage } from "./images";
 
@@ -134,6 +135,11 @@ export const ABC_DATA = {
 	 */
 };
 
+export const settings = reactive({
+	/** 光标跟随 音符, 节拍 */
+	cursorType: 'note' as 'note' | 'beat',
+})
+
 export const createNote = (options: Partial<INote>): INote => {
 	return {
 		accidental: options.accidental || "",