@@ -34,6 +34,7 @@ import com.lambda.threading.runSafe
3434import com.lambda.util.Communication.info
3535import com.lambda.util.Diagnostics.gatherDiagnostics
3636import com.lambda.util.FolderRegister
37+ import com.lambda.util.FolderRegister.minecraft
3738import com.mojang.blaze3d.platform.TextureUtil
3839import imgui.ImGui
3940import imgui.ImGui.closeCurrentPopup
@@ -42,8 +43,10 @@ import imgui.flag.ImGuiStyleVar
4243import imgui.flag.ImGuiWindowFlags
4344import imgui.type.ImString
4445import net.fabricmc.loader.api.FabricLoader
46+ import net.minecraft.client.Keyboard
4547import net.minecraft.util.Util
4648import net.minecraft.world.GameMode
49+ import java.nio.file.Path
4750import java.util.Locale
4851
4952object MenuBar {
@@ -96,7 +99,7 @@ object MenuBar {
9699 }
97100
98101 private fun ImGuiBuilder.buildLambdaMenu () {
99- menuItem(" New Profile..." ) {
102+ menuItem(" New Profile..." , enabled = false ) {
100103 // ToDo (New Profile):
101104 // - Open a modal "New Profile" with:
102105 // [Profile Name] text input
@@ -105,29 +108,50 @@ object MenuBar {
105108 // - On Create: instantiate and activate the profile, optionally copying values from current.
106109 // - On Cancel: close modal with no changes.
107110 }
108- menuItem(" Open Config Folder" ) {
109- Util .getOperatingSystem().open(FolderRegister .config)
111+ menu(" Open Folder" ) {
112+ menuItem(" Open Lambda Folder" ) {
113+ Util .getOperatingSystem().open(FolderRegister .lambda)
114+ }
115+ menuItem(" Open Config Folder" ) {
116+ Util .getOperatingSystem().open(FolderRegister .config)
117+ }
118+ menuItem(" Open Packet Logs Folder" ) {
119+ Util .getOperatingSystem().open(FolderRegister .packetLogs)
120+ }
121+ menuItem(" Open Replay Folder" ) {
122+ Util .getOperatingSystem().open(FolderRegister .replay)
123+ }
124+ menuItem(" Open Cache Folder" ) {
125+ Util .getOperatingSystem().open(FolderRegister .cache)
126+ }
127+ menuItem(" Open Capes Folder" ) {
128+ Util .getOperatingSystem().open(FolderRegister .capes)
129+ }
130+ menuItem(" Open Structures Folder" ) {
131+ Util .getOperatingSystem().open(FolderRegister .structure)
132+ }
133+ menuItem(" Open Maps Folder" ) {
134+ Util .getOperatingSystem().open(FolderRegister .maps)
135+ }
110136 }
111137 separator()
112- menuItem(" Save All Configs" , " Ctrl+S" ) {
113- // Save every configuration file and show a toast with the total count.
138+ menuItem(" Save Configs" ) {
114139 Configuration .configurations.forEach { it.trySave(true ) }
115- runSafe { info(" Saved ${Configuration .configurations.size} configuration files." ) }
140+ info(" Saved ${Configuration .configurations.size} configuration files." )
116141 }
117- menuItem(" Load All Configs" , " Ctrl+L" ) {
118- // Load every configuration file and show a toast with the total count.
142+ menuItem(" Load Configs" ) {
119143 Configuration .configurations.forEach { it.tryLoad() }
120- runSafe { info(" Loaded ${Configuration .configurations.size} configuration files." ) }
144+ info(" Loaded ${Configuration .configurations.size} configuration files." )
121145 }
122146 separator()
123- menuItem(" Import Profile..." ) {
147+ menuItem(" Import Profile..." , enabled = false ) {
124148 // ToDo (Import Profile):
125149 // - Show a file picker for profile file(s).
126150 // - Preview dialog: profile name, version, module count, settings count, includes HUD?
127151 // - Provide options: Merge into Current / Replace Current.
128152 // - Apply with progress/rollback on failure; toast result.
129153 }
130- menuItem(" Export Current Profile..." ) {
154+ menuItem(" Export Current Profile..." , enabled = false ) {
131155 // ToDo (Export Profile):
132156 // - File save modal with checkboxes:
133157 // [Include HUD Layout] [Include Keybinds] [Include Backups Metadata]
@@ -137,58 +161,29 @@ object MenuBar {
137161 // ToDo (MRU Profiles):
138162 // - Populate from a most-recently-used (MRU) list persisted in preferences.
139163 // - On click: switch active profile (confirm if unsaved changes).
140- menuItem(" Example Profile" ) {}
141- }
142- menuItem(" Save All" , " Ctrl+S" ) {
143- Configuration .configurations.forEach { it.trySave(true ) }
144- runSafe { info(" Saved ${Configuration .configurations.size} configuration files." ) }
145- }
146- menuItem(" Load All" , " Ctrl+L" ) {
147- Configuration .configurations.forEach { it.tryLoad() }
148- runSafe { info(" Loaded ${Configuration .configurations.size} configuration files." ) }
164+ menuItem(" Example Profile" , enabled = false ) {}
149165 }
150166 separator()
151167 menu(" Autosave Settings" ) {
152168 // ToDo:
153169 // - Toggle autosave, set interval (1..60s), backup rotation count (0..20).
154- menuItem(" Autosave on changes" , selected = true ) {}
155- menuItem(" Autosave Interval: 10s" ) {}
156- menuItem(" Rotate Backups: 5" ) {}
170+ menuItem(" Autosave on changes" , selected = true , enabled = false ) {}
171+ menuItem(" Autosave Interval: 10s" , enabled = false ) {}
172+ menuItem(" Rotate Backups: 5" , enabled = false ) {}
157173 }
158174 menu(" Backup & Restore" ) {
159175 // ToDo:
160176 // - “Create Backup Now” and “Manage/Restore Backups” UIs; list with timestamps/comments.
161- menuItem(" Create Backup Now" ) {}
162- menuItem(" Restore From Backup..." ) {}
163- menuItem(" Manage Backups..." ) {}
177+ menuItem(" Create Backup Now" , enabled = false ) {}
178+ menuItem(" Restore From Backup..." , enabled = false ) {}
179+ menuItem(" Manage Backups..." , enabled = false ) {}
164180 }
165- menuItem(" Profiles & Scopes..." ) {
181+ menuItem(" Profiles & Scopes..." , enabled = false ) {
166182 // ToDo (Profiles & Scopes Window):
167183 // - Active Profile dropdown.
168184 // - Scopes: Global / Per-Server / Per-World with enable overrides.
169185 // - Show overridden-only list, origin badges, and precedence explanation.
170186 }
171- menuItem(" Module Settings Inspector..." ) {
172- // ToDo (Settings Inspector Window):
173- // - Left: Tree (Tag → Module → Group).
174- // - Right: Settings editor with search; filters (Changed-only, Overridden-only, Advanced).
175- // - Reset group/module actions.
176- }
177- menuItem(" Placement/Build Settings..." ) {
178- // ToDo (Placement Panel):
179- // - Rotate For Place, Air Place Mode, Axis Rotate (conditional),
180- // - Place Stage Mask (multi-select), Place Confirmation Mode,
181- // - Max Pending Placements, Places Per Tick,
182- // - Swing On Place + Swing Type, Place Sounds.
183- // - Provide concise tooltips for trade-offs.
184- }
185- menuItem(" Inventory Settings..." ) {
186- // ToDo (Inventory Panel):
187- // - Container group: Disposables editor (list add/remove + defaults), Swap with Disposables,
188- // Provider/Store Priorities.
189- // - Access group: Access Shulkers/Ender/Chests/Stashes toggles.
190- // - “Test Access” helper to simulate lookups.
191- }
192187 separator()
193188 menuItem(" About..." ) {
194189 aboutRequested = true
@@ -198,51 +193,12 @@ object MenuBar {
198193 menuItem(" Exit Client" ) { mc.scheduleStop() }
199194 }
200195
201- private fun ImGuiBuilder.buildViewMenu () {
202-
203- separator()
204- menu(" UI Scale" ) {
205- // ToDo:
206- // - Apply selected scale (100/125/150/175/200%), update fonts via DearImGui.updateScale-like method.
207- listOf (" 100%" , " 125%" , " 150%" , " 175%" , " 200%" ).forEach { label ->
208- menuItem(label, selected = (label == " 125%" )) { /* set scale & rebuild fonts */ }
209- }
210- }
211- }
212-
213196 private fun ImGuiBuilder.buildHudMenu () {
214- menuItem(" Copy HUD Layout" ) {
215- // ToDo:
216- // - Serialize current HUD widget tree with positions/anchors/safe-margins to memory clipboard.
217- }
218- menuItem(" Paste HUD Layout" ) {
219- // ToDo:
220- // - Deserialize from clipboard and apply; if incompatible, show a non-blocking warning.
221- }
222- menuItem(" Reset to Defaults" ) {
223- // ToDo:
224- // - Reset the currently focused panel’s settings to defaults (confirmation modal).
225- }
226- separator()
227- menuItem(" Keybind Manager..." ) {
228- // ToDo (Keybind Manager Window):
229- // - Panel with search/filter; table columns: Action/Module | Current Key | Conflict | Change | Clear
230- // - Conflict detector with "Auto-resolve" suggestions.
231- }
232- menuItem(" Open Editor" , " Ctrl+Alt+C" ) {
197+ menuItem(" Open Editor" ) {
233198 // ToDo (HUD Editor Window):
234199 // - Full-screen canvas with grid; left "Elements" list; right "Properties" inspector.
235200 // - Drag & drop, snap grid, lock/unlock, safe margins, anchors, multi-select & alignment tools.
236201 }
237- menu(" Add Widget" ) {
238- // ToDo:
239- // - Populate from available HUD widgets. On click, add centered and select for property editing.
240- menuItem(" Stats" ) {}
241- menuItem(" Clock" ) {}
242- menuItem(" Ping" ) {}
243- menuItem(" Coordinates" ) {}
244- menuItem(" Module List" ) {}
245- }
246202 menu(" Layouts" ) {
247203 // ToDo:
248204 // - New/Save/Save As/Load/Import/Export layout actions; Toggle "Autosave on change".
@@ -255,10 +211,6 @@ object MenuBar {
255211 separator()
256212 menuItem(" Autosave on change" , selected = true ) {}
257213 }
258- menuItem(" Reset Layout" ) {
259- // ToDo:
260- // - Confirm and restore the default HUD layout.
261- }
262214 menuItem(" Toggle Edit Handles" , selected = true ) {
263215 // ToDo:
264216 // - Show/hide bounds, anchors, labels while in edit mode.
@@ -295,23 +247,17 @@ object MenuBar {
295247 menuItem(" Open Minecraft Folder" ) {
296248 Util .getOperatingSystem().open(FolderRegister .minecraft)
297249 }
298- menuItem(" Open Lambda Folder" ) {
299- Util .getOperatingSystem().open(FolderRegister .lambda )
250+ menuItem(" Open Saves Folder" ) {
251+ Util .getOperatingSystem().open(mc.runDirectory.toPath().toAbsolutePath().resolve( " saves " ).toFile() )
300252 }
301- menuItem(" Open Config Folder" ) {
302- Util .getOperatingSystem().open(FolderRegister .config )
253+ menuItem(" Open Screenshots Folder" ) {
254+ Util .getOperatingSystem().open(mc.runDirectory.toPath().toAbsolutePath().resolve( " screenshots " ).toFile() )
303255 }
304- menuItem(" Open Cache Folder" ) {
305- Util .getOperatingSystem().open(FolderRegister .cache )
256+ menuItem(" Open Resource Packs Folder" ) {
257+ Util .getOperatingSystem().open(mc.runDirectory.toPath().toAbsolutePath().resolve( " resourcepacks " ).toFile() )
306258 }
307- menuItem(" Open Capes Folder" ) {
308- Util .getOperatingSystem().open(FolderRegister .capes)
309- }
310- menuItem(" Open Structures Folder" ) {
311- Util .getOperatingSystem().open(FolderRegister .structure)
312- }
313- menuItem(" Open Maps Folder" ) {
314- Util .getOperatingSystem().open(FolderRegister .maps)
259+ menuItem(" Open Mods Folder" ) {
260+ Util .getOperatingSystem().open(mc.runDirectory.toPath().toAbsolutePath().resolve(" mods" ).toFile())
315261 }
316262 }
317263 separator()
@@ -331,40 +277,17 @@ object MenuBar {
331277 }
332278 }
333279 menu(" Debug Menu" ) {
334- menuItem(
335- " Show Debug Menu" , " F3" ,
336- mc.debugHud.showDebugHud
337- ) { mc.debugHud.toggleDebugHud() }
338- menuItem(
339- " Rendering Chart" , " F3+1" ,
340- mc.debugHud.renderingChartVisible
341- ) { mc.debugHud.toggleRenderingChart() }
342- menuItem(
343- " Rendering & Tick Charts" , " F3+2" ,
344- mc.debugHud.renderingAndTickChartsVisible
345- ) { mc.debugHud.toggleRenderingAndTickCharts() }
346- menuItem(
347- " Packet Size & Ping Charts" , " F3+3" ,
348- mc.debugHud.packetSizeAndPingChartsVisible
349- ) { mc.debugHud.togglePacketSizeAndPingCharts() }
350-
351- separator()
352-
353- menuItem(" Reload Chunks" , " F3+A" ) {
354- mc.worldRenderer.reload()
280+ menuItem(" Show Advanced Tooltips" , " F3+H" , mc.options.advancedItemTooltips) {
281+ mc.options.advancedItemTooltips = ! mc.options.advancedItemTooltips
282+ mc.options.write()
283+ }
284+ menuItem(" Show Chunk Borders" , " F3+G" , mc.debugRenderer.showChunkBorder) {
285+ mc.debugRenderer.toggleShowChunkBorder()
355286 }
356- menuItem(
357- " Show Chunk Borders" , " F3+G" ,
358- mc.debugRenderer.showChunkBorder
359- ) { mc.debugRenderer.toggleShowChunkBorder() }
360287 menuItem(" Show Octree" , selected = mc.debugRenderer.showOctree) {
361288 mc.debugRenderer.toggleShowOctree()
362289 }
363- menuItem(
364- label = " Show Hitboxes" ,
365- shortcut = " F3+B" ,
366- selected = mc.entityRenderDispatcher.shouldRenderHitboxes()
367- ) {
290+ menuItem(" Show Hitboxes" , " F3+B" , mc.entityRenderDispatcher.shouldRenderHitboxes()) {
368291 val now = ! mc.entityRenderDispatcher.shouldRenderHitboxes()
369292 mc.entityRenderDispatcher.setRenderHitboxes(now)
370293 }
@@ -385,49 +308,54 @@ object MenuBar {
385308 separator()
386309
387310 menuItem(
388- label = " Advanced Tooltips " ,
389- shortcut = " F3+H " ,
390- selected = mc.options.advancedItemTooltips
311+ label = " Pause On Lost Focus " ,
312+ shortcut = " F3+Esc " ,
313+ selected = mc.options.pauseOnLostFocus
391314 ) {
392- mc.options.advancedItemTooltips = ! mc.options.advancedItemTooltips
315+ mc.options.pauseOnLostFocus = ! mc.options.pauseOnLostFocus
393316 mc.options.write()
394- }
395- menuItem(" Inspect (Copy Look At)" , " F3+I" ) {
396- // TODO: Implement precise copyLookAt(hasOp = player.hasPermissionLevel(2), raycastBlocksIfNotShift = !Screen.hasShiftDown())
397- info(" Inspect: Not yet implemented." )
317+ info(" Pause on lost focus ${if (mc.options.pauseOnLostFocus) " enabled" else " disabled" } ." )
398318 }
399319
400320 separator()
401321
402- menuItem(" Start/Stop Profiler" , " F3+L" ) {
403- // TODO: Wire mc.toggleDebugProfiler with callback logging
404- info(" Profiler control: Not yet implemented." )
322+ menuItem(" Reload Resource Packs" , " F3+T" ) {
323+ info(" Reloading resource packs..." )
324+ mc.reloadResources()
325+ }
326+
327+ menuItem(" Reload Chunks" , " F3+A" ) {
328+ mc.worldRenderer.reload()
405329 }
406330
407331 separator()
408332
409- menuItem(
410- label = " Pause On Lost Focus" ,
411- shortcut = " F3+Esc" ,
412- selected = mc.options.pauseOnLostFocus
413- ) {
414- mc.options.pauseOnLostFocus = ! mc.options.pauseOnLostFocus
415- mc.options.write()
416- info(" Pause on lost focus ${if (mc.options.pauseOnLostFocus) " enabled" else " disabled" } ." )
333+ menuItem(" Show Debug Menu" , " F3" , mc.debugHud.showDebugHud) {
334+ mc.debugHud.toggleDebugHud()
335+ }
336+ menuItem(" Rendering Chart" , " F3+1" , mc.debugHud.renderingChartVisible) {
337+ mc.debugHud.toggleRenderingChart()
338+ }
339+ menuItem(" Rendering & Tick Charts" , " F3+2" , mc.debugHud.renderingAndTickChartsVisible) {
340+ mc.debugHud.toggleRenderingAndTickCharts()
341+ }
342+ menuItem(" Packet Size & Ping Charts" , " F3+3" , mc.debugHud.packetSizeAndPingChartsVisible) {
343+ mc.debugHud.togglePacketSizeAndPingCharts()
417344 }
418345
419346 separator()
420347
348+ menuItem(" Start/Stop Profiler" , " F3+L" ) {
349+ mc.toggleDebugProfiler { message ->
350+ info(message)
351+ }
352+ }
421353 menuItem(" Dump Dynamic Textures" , " F3+S" ) {
422354 val root = mc.runDirectory.toPath().toAbsolutePath()
423355 val output = TextureUtil .getDebugTexturePath(root)
424356 mc.textureManager.dumpDynamicTextures(output)
425357 info(" Dumped dynamic textures to: ${root.relativize(output)} " )
426358 }
427- menuItem(" Reload Resource Packs" , " F3+T" ) {
428- info(" Reloading resource packs..." )
429- mc.reloadResources()
430- }
431359 }
432360 } ? : menuItem(" Debug (only available ingame)" , enabled = false )
433361 }
0 commit comments