11import { Project , service } from "@/core/Project" ;
22import { allKeyBinds } from "./shortcutKeysRegister" ;
3- import { parseSingleEmacsKey } from "@/utils/emacs" ;
3+ import { parseEmacsKey , parseSingleEmacsKey } from "@/utils/emacs" ;
44import { isMac } from "@/utils/platform" ;
55import { Vector } from "@graphif/data-structures" ;
6- import { Rectangle } from "@graphif/shapes" ;
76import { getTextSize } from "@/utils/font" ;
8- import { KeyBindsUI } from "./KeyBindsUI" ;
7+ import { KeyBindsUI , type UIKeyBind } from "./KeyBindsUI" ;
8+ import { formatKeyBindSequenceToString } from "@/utils/keyDisplay" ;
99
1010/**
1111 * 快捷键提示引擎
@@ -101,13 +101,14 @@ export class KeyBindHintEngine {
101101 private isKeyBindMatchModifier ( key : string , modifierCombo : string ) : boolean {
102102 // 解析快捷键
103103 const parsed = parseSingleEmacsKey ( key ) ;
104+ const parsedList = parseEmacsKey ( key ) ;
104105
105106 // 构建快捷键的修饰键组合(存储格式)
106107 const keyModifiers : string [ ] = [ ] ;
107- if ( parsed . control ) keyModifiers . push ( "C" ) ;
108- if ( parsed . alt ) keyModifiers . push ( "A" ) ;
109- if ( parsed . shift ) keyModifiers . push ( "S" ) ;
110- if ( parsed . meta ) keyModifiers . push ( "M" ) ;
108+ if ( parsedList . some ( ( p ) => p . control ) ) keyModifiers . push ( "C" ) ;
109+ if ( parsedList . some ( ( p ) => p . alt ) ) keyModifiers . push ( "A" ) ;
110+ if ( parsedList . some ( ( p ) => p . shift ) ) keyModifiers . push ( "S" ) ;
111+ if ( parsedList . some ( ( p ) => p . meta ) ) keyModifiers . push ( "M" ) ;
111112
112113 const keyModifierCombo = keyModifiers . join ( "-" ) ;
113114
@@ -125,6 +126,7 @@ export class KeyBindHintEngine {
125126
126127 /**
127128 * 获取所有匹配的快捷键
129+ * O(N)
128130 */
129131 private getMatchingKeyBinds ( modifierCombo : string ) : Array < {
130132 id : string ;
@@ -147,16 +149,15 @@ export class KeyBindHintEngine {
147149 if ( keyBind . isGlobal ) continue ;
148150
149151 // 获取当前快捷键的配置
150- const uiKeyBind = allUIKeyBinds . find ( ( kb : any ) => kb . id === keyBind . id ) ;
152+ const uiKeyBind = allUIKeyBinds . find ( ( kb : UIKeyBind ) => kb . id === keyBind . id ) ;
151153 if ( uiKeyBind && ! uiKeyBind . isEnabled ) continue ;
152154
153155 const key = uiKeyBind ?. key || keyBind . defaultKey ;
154156
155157 // 检查是否匹配当前修饰键组合
156158 if ( this . isKeyBindMatchModifier ( key , modifierCombo ) ) {
157- // 解析快捷键获取显示用的按键
158- const parsed = parseSingleEmacsKey ( key ) ;
159- const displayKey = this . formatKeyForDisplay ( parsed . key ) ;
159+ // 使用复用的函数格式化按键显示
160+ const displayKey = formatKeyBindSequenceToString ( key ) ;
160161
161162 result . push ( {
162163 id : keyBind . id ,
@@ -170,46 +171,10 @@ export class KeyBindHintEngine {
170171 return result ;
171172 }
172173
173- /**
174- * 格式化按键显示
175- */
176- private formatKeyForDisplay ( key : string ) : string {
177- // 特殊键映射
178- const specialKeyMap : Record < string , string > = {
179- arrowup : "↑" ,
180- arrowdown : "↓" ,
181- arrowleft : "←" ,
182- arrowright : "→" ,
183- enter : "↵" ,
184- escape : "Esc" ,
185- backspace : "⌫" ,
186- delete : "Del" ,
187- tab : "Tab" ,
188- space : "Space" ,
189- home : "Home" ,
190- end : "End" ,
191- pageup : "PgUp" ,
192- pagedown : "PgDn" ,
193- } ;
194-
195- if ( key in specialKeyMap ) {
196- return specialKeyMap [ key ] ;
197- }
198-
199- // 大写字母
200- if ( key . length === 1 && / [ a - z ] / . test ( key ) ) {
201- return key . toUpperCase ( ) ;
202- }
203-
204- return key ;
205- }
206-
207174 /**
208175 * 获取快捷键标题
209176 */
210177 private getKeyBindTitle ( id : string ) : string {
211- // 这里可以后续从翻译文件中获取
212- // 暂时返回简化版的标题
213178 const titleMap : Record < string , string > = {
214179 saveFile : "保存文件" ,
215180 openFile : "打开文件" ,
@@ -331,60 +296,27 @@ export class KeyBindHintEngine {
331296 const lineHeight = 28 ;
332297 const startY = this . project . renderer . h - 140 - pageItems . length * lineHeight ;
333298
334- // 渲染背景
335- const maxWidth = this . calculateMaxWidth ( pageItems ) ;
336- const bgPadding = 8 ;
337- const bgRect = new Rectangle (
338- new Vector ( margin - bgPadding , startY - bgPadding ) ,
339- new Vector ( maxWidth + bgPadding * 2 , pageItems . length * lineHeight + bgPadding * 2 ) ,
340- ) ;
341- this . project . shapeRenderer . renderRect (
342- bgRect ,
343- this . project . stageStyleManager . currentStyle . Background . toNewAlpha ( 0.9 ) ,
344- this . project . stageStyleManager . currentStyle . StageObjectBorder . toNewAlpha ( 0.3 ) ,
345- 1 ,
346- ) ;
347-
348299 // 渲染每个快捷键提示
349300 for ( let i = 0 ; i < pageItems . length ; i ++ ) {
350301 const item = pageItems [ i ] ;
351302 const y = startY + i * lineHeight ;
352303
353- // 渲染修饰键组合
354- const modifierText = this . formatModifierCombo ( this . currentModifierCombo ) ;
355- this . project . textRenderer . renderText (
356- modifierText ,
357- new Vector ( margin , y ) ,
358- 14 ,
359- this . project . stageStyleManager . currentStyle . StageObjectBorder ,
360- ) ;
361-
362- const modifierWidth = getTextSize ( modifierText , 14 ) . x ;
363-
364- // 渲染 + 号
365- this . project . textRenderer . renderText (
366- " + " ,
367- new Vector ( margin + modifierWidth , y ) ,
368- 14 ,
369- this . project . stageStyleManager . currentStyle . effects . successShadow ,
370- ) ;
371-
372- const plusWidth = getTextSize ( " + " , 14 ) . x ;
304+ // 使用复用的函数格式化修饰键组合
305+ let currentX = margin ;
373306
374307 // 渲染按键
375308 this . project . textRenderer . renderText (
376309 item . displayKey ,
377- new Vector ( margin + modifierWidth + plusWidth , y ) ,
310+ new Vector ( currentX , y ) ,
378311 16 ,
379312 this . project . stageStyleManager . currentStyle . effects . flash ,
380313 ) ;
381-
382- const keyWidth = getTextSize ( item . displayKey , 16 ) . x ;
314+ currentX += getTextSize ( item . displayKey , 16 ) . x ;
383315
384316 // 渲染标题
385317 this . project . textRenderer . renderText (
386318 item . title ,
387- new Vector ( margin + modifierWidth + plusWidth + keyWidth + 15 , y + 2 ) ,
319+ new Vector ( currentX + 15 , y + 2 ) ,
388320 12 ,
389321 this . project . stageStyleManager . currentStyle . DetailsDebugText ,
390322 ) ;
@@ -393,48 +325,12 @@ export class KeyBindHintEngine {
393325 // 渲染页码指示器
394326 if ( totalPages > 1 ) {
395327 const pageIndicator = `${ actualPage + 1 } /${ totalPages } ` ;
396- const indicatorWidth = getTextSize ( pageIndicator , 12 ) . x ;
397328 this . project . textRenderer . renderText (
398329 pageIndicator ,
399- new Vector ( margin + maxWidth - indicatorWidth , startY - 20 ) ,
330+ new Vector ( margin , startY - 20 ) ,
400331 12 ,
401332 this . project . stageStyleManager . currentStyle . DetailsDebugText ,
402333 ) ;
403334 }
404335 }
405-
406- /**
407- * 格式化修饰键组合显示
408- */
409- private formatModifierCombo ( combo : string ) : string {
410- if ( ! combo ) return "" ;
411-
412- const parts = combo . split ( "-" ) ;
413- const displayMap : Record < string , string > = {
414- C : isMac ? "⌘" : "Ctrl" ,
415- A : isMac ? "⌥" : "Alt" ,
416- S : "⇧" ,
417- M : isMac ? "⌃" : "Win" ,
418- } ;
419-
420- return parts . map ( ( p ) => displayMap [ p ] || p ) . join ( "" ) ;
421- }
422-
423- /**
424- * 计算最大宽度
425- */
426- private calculateMaxWidth ( items : Array < { displayKey : string ; title : string } > ) : number {
427- let maxWidth = 0 ;
428- const modifierWidth = getTextSize ( this . formatModifierCombo ( this . currentModifierCombo ) , 14 ) . x ;
429- const plusWidth = getTextSize ( " + " , 14 ) . x ;
430-
431- for ( const item of items ) {
432- const keyWidth = getTextSize ( item . displayKey , 16 ) . x ;
433- const titleWidth = getTextSize ( item . title , 12 ) . x ;
434- const totalWidth = modifierWidth + plusWidth + keyWidth + 15 + titleWidth ;
435- maxWidth = Math . max ( maxWidth , totalWidth ) ;
436- }
437-
438- return maxWidth ;
439- }
440336}
0 commit comments