@@ -8,7 +8,8 @@ import { StageManager } from "../core/stage/stageManager/StageManager";
8
8
import React from "react" ;
9
9
import Toolbar from "./_toolbar" ;
10
10
import { Settings } from "../core/Settings" ;
11
- import { invoke } from "@tauri-apps/api/core" ;
11
+ import { cn } from "../utils/cn" ;
12
+ import { Camera } from "../core/stage/Camera" ;
12
13
13
14
export default function Home ( ) {
14
15
const canvasRef : React . RefObject < HTMLCanvasElement > = useRef ( null ) ;
@@ -17,6 +18,24 @@ export default function Home() {
17
18
const dialog = useDialog ( ) ;
18
19
const [ cursorName , setCursorName ] = React . useState ( "default" ) ;
19
20
21
+ const [ isSearchingShow , setIsSearchingShow ] = React . useState ( false ) ;
22
+
23
+ const [ currentSearchResultIndex , setCurrentSearchResultIndex ] =
24
+ React . useState ( 0 ) ;
25
+
26
+ useEffect ( ( ) => {
27
+ if ( Stage . searchResultNodes . length == 0 ) {
28
+ setCurrentSearchResultIndex ( - 1 ) ;
29
+ } else {
30
+ setCurrentSearchResultIndex ( Stage . currentSearchResultIndex ) ;
31
+ }
32
+ } , [ Stage . currentSearchResultIndex ] ) ;
33
+
34
+ const [ searchResultCount , setSearchResultCount ] = React . useState ( 0 ) ;
35
+ useEffect ( ( ) => {
36
+ setSearchResultCount ( Stage . searchResultNodes . length ) ;
37
+ } , [ Stage . searchResultNodes ] ) ;
38
+
20
39
useEffect ( ( ) => {
21
40
const handleResize = ( ) => {
22
41
if ( canvasElement ) {
@@ -29,6 +48,41 @@ export default function Home() {
29
48
const handleBlur = ( ) => {
30
49
focus = false ;
31
50
} ;
51
+ const handleKeyDown = ( event : KeyboardEvent ) => {
52
+ // event.preventDefault();
53
+ if ( Controller . pressingKeySet . has ( "control" ) && event . key === "f" ) {
54
+ Controller . pressingKeySet . clear ( ) ;
55
+ // setIsSearching(true);
56
+ const searchString = prompt ( "请输入要搜索的节点名称" ) ;
57
+ if ( searchString ) {
58
+ // 开始搜索
59
+ Stage . searchResultNodes = [ ] ;
60
+ for ( const node of StageManager . nodes ) {
61
+ if ( node . text . includes ( searchString ) ) {
62
+ Stage . searchResultNodes . push ( node ) ;
63
+ }
64
+ }
65
+ Stage . currentSearchResultIndex = 0 ;
66
+ if ( Stage . searchResultNodes . length > 0 ) {
67
+ setIsSearchingShow ( true ) ;
68
+ setCurrentSearchResultIndex ( 0 ) ;
69
+ // 选择第一个搜索结果节点
70
+ const currentNode =
71
+ Stage . searchResultNodes [ Stage . currentSearchResultIndex ] ;
72
+ currentNode . isSelected = true ;
73
+ // 摄像机对准现在的节点
74
+ Camera . location = currentNode . rectangle . center . clone ( ) ;
75
+ } else {
76
+ dialog . show ( {
77
+ title : "提示" ,
78
+ type : "info" ,
79
+ content : "没有找到匹配的节点" ,
80
+ } ) ;
81
+ }
82
+ }
83
+ }
84
+ // setSearchString(searchString + event.key)
85
+ } ;
32
86
33
87
const canvasElement = canvasRef . current ;
34
88
let focus = true ;
@@ -49,6 +103,7 @@ export default function Home() {
49
103
window . addEventListener ( "resize" , handleResize ) ;
50
104
window . addEventListener ( "focus" , handleFocus ) ;
51
105
window . addEventListener ( "blur" , handleBlur ) ;
106
+ window . addEventListener ( "keydown" , handleKeyDown ) ;
52
107
53
108
Settings . get ( "windowBackgroundAlpha" ) . then ( ( value ) => {
54
109
Renderer . backgroundAlpha = value ;
@@ -86,11 +141,70 @@ export default function Home() {
86
141
return (
87
142
< >
88
143
< Toolbar />
144
+ { isSearchingShow && (
145
+ < div
146
+ className = { cn (
147
+ "fixed right-32 top-32 z-10 flex transform items-center rounded p-4 ring" ,
148
+ isSearchingShow ,
149
+ ) }
150
+ >
151
+ < span >
152
+ { currentSearchResultIndex + 1 } /{ searchResultCount }
153
+ </ span >
154
+ < button
155
+ className = "m-2 rounded-md bg-gray-500 text-white"
156
+ onClick = { ( ) => {
157
+ if ( Stage . currentSearchResultIndex > 0 ) {
158
+ Stage . currentSearchResultIndex -- ;
159
+ }
160
+ // 取消选择所有节点
161
+ for ( const node of StageManager . nodes ) {
162
+ node . isSelected = false ;
163
+ }
164
+ // 选择当前搜索结果节点
165
+ const currentNode =
166
+ Stage . searchResultNodes [ Stage . currentSearchResultIndex ] ;
167
+ currentNode . isSelected = true ;
168
+ // 摄像机对准现在的节点
169
+ Camera . location = currentNode . rectangle . center . clone ( ) ;
170
+ } }
171
+ >
172
+ Previous
173
+ </ button >
174
+ < button
175
+ className = "m-2 rounded-md bg-gray-500 text-white"
176
+ onClick = { ( ) => {
177
+ if ( Stage . currentSearchResultIndex < searchResultCount - 1 ) {
178
+ Stage . currentSearchResultIndex ++ ;
179
+ }
180
+ // 取消选择所有节点
181
+ for ( const node of StageManager . nodes ) {
182
+ node . isSelected = false ;
183
+ }
184
+ // 选择当前搜索结果节点
185
+ const currentNode =
186
+ Stage . searchResultNodes [ Stage . currentSearchResultIndex ] ;
187
+ currentNode . isSelected = true ;
188
+ // 摄像机对准现在的节点
189
+ Camera . location = currentNode . rectangle . center . clone ( ) ;
190
+ } }
191
+ >
192
+ Next
193
+ </ button >
194
+ < button
195
+ className = "m-2 rounded-md bg-gray-500 text-white"
196
+ onClick = { ( ) => {
197
+ setIsSearchingShow ( false ) ;
198
+ } }
199
+ >
200
+ 关闭
201
+ </ button >
202
+ </ div >
203
+ ) }
89
204
< span
90
205
className = "fixed bottom-0 left-0 cursor-pointer ring"
91
206
onClick = { ( ) => {
92
207
window . location . reload ( ) ;
93
- invoke < string > ( "save_json_by_path" ) ;
94
208
} }
95
209
>
96
210
FPS={ fps . toFixed ( ) }
0 commit comments