mirror of
				https://github.com/unanmed/HumanBreak.git
				synced 2025-10-31 12:12:58 +08:00 
			
		
		
		
	feat: 自定义状态栏编辑工具框架
This commit is contained in:
		
							parent
							
								
									49d8050e03
								
							
						
					
					
						commit
						60d708e5e3
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -42,3 +42,6 @@ dam2.png | ||||
| dam3.png | ||||
| dam4.png | ||||
| meeting.md | ||||
| 
 | ||||
| special.csv | ||||
| script/special.ts | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
|     <div class="colomn"> | ||||
|         <div class="tools"> | ||||
|             <span class="button-text" @click="emits('close')" | ||||
|                 ><left-outlined /> 返回游戏</span | ||||
|                 ><left-outlined /> 返回</span | ||||
|             > | ||||
|         </div> | ||||
|         <div class="column-main" :id="`column-${id}`"> | ||||
|  | ||||
| @ -1,7 +1,13 @@ | ||||
| import { EmitableEvent, EventEmitter } from '@/core/common/eventEmitter'; | ||||
| import { KeyCode } from '@/plugin/keyCodes'; | ||||
| import { flipBinary, has } from '@/plugin/utils'; | ||||
| import { FunctionalComponent, nextTick, reactive } from 'vue'; | ||||
| import { | ||||
|     FunctionalComponent, | ||||
|     markRaw, | ||||
|     nextTick, | ||||
|     reactive, | ||||
|     shallowReactive | ||||
| } from 'vue'; | ||||
| import { createToolbarComponents } from '../init/toolbar'; | ||||
| import { gameKey } from '../init/hotkey'; | ||||
| import { unwarpBinary } from './hotkey'; | ||||
| @ -12,7 +18,7 @@ interface CustomToolbarEvent extends EmitableEvent { | ||||
|     add: (item: ValueOf<ToolbarItemMap>) => void; | ||||
|     delete: (item: ValueOf<ToolbarItemMap>) => void; | ||||
|     set: (id: string, data: Partial<SettableItemData>) => void; | ||||
|     emit: (id: string) => void; | ||||
|     emit: (id: string, item: ValueOf<ToolbarItemMap>) => void; | ||||
| } | ||||
| 
 | ||||
| interface ToolbarItemBase<T extends ToolbarItemType> { | ||||
| @ -70,7 +76,7 @@ const comMap: { | ||||
| 
 | ||||
| export class CustomToolbar extends EventEmitter<CustomToolbarEvent> { | ||||
|     static num: number = 0; | ||||
|     static list: CustomToolbar[] = []; | ||||
|     static list: CustomToolbar[] = shallowReactive([]); | ||||
| 
 | ||||
|     items: ValueOf<ToolbarItemMap>[] = reactive([]); | ||||
|     num: number = CustomToolbar.num++; | ||||
| @ -97,7 +103,7 @@ export class CustomToolbar extends EventEmitter<CustomToolbarEvent> { | ||||
|     add<K extends ToolbarItemType>(item: Omit<ToolbarItemMap[K], 'com'>) { | ||||
|         // @ts-ignore
 | ||||
|         const data: ToolbarItemMap[K] = { | ||||
|             com: comMap[item.type], | ||||
|             com: markRaw(comMap[item.type]), | ||||
|             ...item | ||||
|         } as ToolbarItemMap[K]; | ||||
|         this.items.push(data); | ||||
| @ -141,7 +147,7 @@ export class CustomToolbar extends EventEmitter<CustomToolbarEvent> { | ||||
|     emitTool(id: string) { | ||||
|         const item = this.items.find(v => v.id === id); | ||||
|         if (!item) return this; | ||||
|         this.emit(id); | ||||
|         this.emit('emit', id, item); | ||||
|         if (item.type === 'hotkey') { | ||||
|             // 按键
 | ||||
|             const assist = item.assist | this.assistKey; | ||||
|  | ||||
| @ -8,7 +8,7 @@ interface Components { | ||||
|     BooleanSetting: SettingComponent; | ||||
|     NumberSetting: SettingComponent; | ||||
|     HotkeySetting: SettingComponent; | ||||
|     ToolbarSetting: SettingComponent; | ||||
|     ToolbarEditor: SettingComponent; | ||||
| } | ||||
| 
 | ||||
| export function createSettingComponents() { | ||||
| @ -17,7 +17,7 @@ export function createSettingComponents() { | ||||
|         BooleanSetting, | ||||
|         NumberSetting, | ||||
|         HotkeySetting, | ||||
|         ToolbarSetting | ||||
|         ToolbarEditor | ||||
|     }; | ||||
|     return com; | ||||
| } | ||||
| @ -104,15 +104,14 @@ function HotkeySetting(props: SettingComponentProps) { | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| function ToolbarSetting(props: SettingComponentProps) { | ||||
|     // todo: toolSetting.vue
 | ||||
| function ToolbarEditor(props: SettingComponentProps) { | ||||
|     return ( | ||||
|         <div style="display: flex; justify-content: center"> | ||||
|             <Button | ||||
|                 style="font-size: 75%" | ||||
|                 type="primary" | ||||
|                 size="large" | ||||
|                 onClick={() => showSpecialSetting('toolSetting')} | ||||
|                 onClick={() => showSpecialSetting('toolEditor')} | ||||
|             > | ||||
|                 自定义工具栏 | ||||
|             </Button> | ||||
|  | ||||
| @ -16,7 +16,8 @@ mainUi.register( | ||||
|     new GameUi('shop', UI.Shop), | ||||
|     new GameUi('achievement', UI.Achievement), | ||||
|     new GameUi('bgm', UI.BgmList), | ||||
|     new GameUi('hotkey', UI.Hotkey) | ||||
|     new GameUi('hotkey', UI.Hotkey), | ||||
|     new GameUi('toolEditor', UI.ToolEditor) | ||||
|     // todo: 把游戏主 div 加入到 mainUi 里面
 | ||||
| ); | ||||
| mainUi.showAll(); | ||||
|  | ||||
| @ -391,7 +391,7 @@ mainSetting | ||||
|             .register('fixed', '定点查看', true, COM.BooleanSetting) | ||||
|             .register('hotkey', '快捷键', false, COM.HotkeySetting) | ||||
|             .setDisplayFunc('hotkey', () => '') | ||||
|             .register('toolbar', '自定义工具栏', false, COM.BooleanSetting) | ||||
|             .register('toolbar', '自定义工具栏', false, COM.ToolbarEditor) | ||||
|             .setDisplayFunc('toolbar', () => '') | ||||
|     ) | ||||
|     .register( | ||||
|  | ||||
| @ -21,3 +21,4 @@ export { default as Study } from './study.vue'; | ||||
| export { default as Toolbox } from './toolbox.vue'; | ||||
| export { default as Hotkey } from './hotkey.vue'; | ||||
| export { default as Toolbar } from './toolbar.vue'; | ||||
| export { default as ToolEditor } from './toolEditor.vue'; | ||||
|  | ||||
							
								
								
									
										140
									
								
								src/ui/toolEditor.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								src/ui/toolEditor.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,140 @@ | ||||
| <template> | ||||
|     <Column :left="30" @close="exit"> | ||||
|         <template #left> | ||||
|             <div id="tool-list"> | ||||
|                 <div | ||||
|                     v-for="(item, i) of list" | ||||
|                     class="tool-list-item selectable" | ||||
|                     :selected="i === selected" | ||||
|                     @click="selected = i" | ||||
|                 > | ||||
|                     <span>{{ item.id }}</span> | ||||
|                     <a-button | ||||
|                         type="danger" | ||||
|                         class="tool-list-delete" | ||||
|                         @click.stop="deleteTool" | ||||
|                         >删除</a-button | ||||
|                     > | ||||
|                 </div> | ||||
|                 <div id="tool-list-add"> | ||||
|                     <div id="tool-add-div" @click="addTool"> | ||||
|                         <PlusOutlined></PlusOutlined>   | ||||
|                         <span>新增工具栏</span> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </template> | ||||
|         <template #right> | ||||
|             <div id="tool-info"> | ||||
|                 <div id="tool-detail"></div> | ||||
|                 <a-divider dashed></a-divider> | ||||
|                 <div id="tool-preview"> | ||||
|                     <div id="tool-preview-container"> | ||||
|                         <div | ||||
|                             class="tool-preview-item" | ||||
|                             v-for="item of bar.items" | ||||
|                         > | ||||
|                             <component | ||||
|                                 :is="(item.com as any)" | ||||
|                                 :item="item" | ||||
|                                 :bar="bar" | ||||
|                             ></component> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </template> | ||||
|     </Column> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { CustomToolbar } from '@/core/main/custom/toolbar'; | ||||
| import { GameUi } from '@/core/main/custom/ui'; | ||||
| import Column from '../components/colomn.vue'; | ||||
| import { computed, ref } from 'vue'; | ||||
| import { PlusOutlined } from '@ant-design/icons-vue'; | ||||
| import { mainUi } from '@/core/main/init/ui'; | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
|     ui: GameUi; | ||||
|     num: number; | ||||
| }>(); | ||||
| 
 | ||||
| const list = CustomToolbar.list; | ||||
| 
 | ||||
| const selected = ref(0); | ||||
| const bar = computed(() => list[selected.value]); | ||||
| 
 | ||||
| function exit() { | ||||
|     mainUi.close(props.num); | ||||
| } | ||||
| 
 | ||||
| function deleteTool() {} | ||||
| 
 | ||||
| function addTool() {} | ||||
| </script> | ||||
| 
 | ||||
| <style lang="less" scoped> | ||||
| .tool-list-item { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     justify-content: space-between; | ||||
| } | ||||
| 
 | ||||
| #tool-list { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
| } | ||||
| 
 | ||||
| #tool-list-add { | ||||
|     margin-top: 5%; | ||||
|     padding: 1% 3% 1% 3%; | ||||
| 
 | ||||
|     #tool-add-div { | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         flex-direction: row; | ||||
|         cursor: pointer; | ||||
|         padding: 1% 4%; | ||||
|         transition: background-color linear 0.1s; | ||||
|         border-radius: 5px; | ||||
|         text-overflow: ellipsis; | ||||
|     } | ||||
| 
 | ||||
|     #tool-add-div:hover { | ||||
|         background-color: rgba(39, 251, 209, 0.316); | ||||
|     } | ||||
| 
 | ||||
|     #tool-add-div:active { | ||||
|         background-color: rgba(39, 251, 209, 0.202); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| .tool-list-delete { | ||||
|     font-size: 80%; | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
| } | ||||
| 
 | ||||
| #tool-info { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
| } | ||||
| 
 | ||||
| #tool-preview { | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|     align-items: center; | ||||
| 
 | ||||
|     #tool-preview-container { | ||||
|         border: 2px solid #ddd9; | ||||
|         background-color: #0009; | ||||
|     } | ||||
| 
 | ||||
|     .tool-preview-item { | ||||
|         ::v-deep(*) { | ||||
|             pointer-events: none; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| </style> | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user