Drop the modules/threads tabs; show both as collapsible sidebar groups mirroring the hooks UX: a handful of top picks plus a browse popover for the rest. Default threads to collapsed. Revert the eager re-analysis of persisted modules on attach; keep disassembly analysis lazy and add a per-module Analyze action and status indicator instead. Share one sidebar-row and one browser-popover component across hooks, modules, and threads in both the SwiftUI and GTK frontends.
44 lines
1.3 KiB
Swift
44 lines
1.3 KiB
Swift
import Foundation
|
|
import LumaCore
|
|
|
|
extension Engine {
|
|
var selectedSidebarItem: SidebarItemID? {
|
|
get { decodedSidebarItem(from: projectUIState.selectedItemJSON) }
|
|
set { setSelectedItemJSON(encodedSidebarItem(newValue)) }
|
|
}
|
|
|
|
private func decodedSidebarItem(from json: String?) -> SidebarItemID? {
|
|
guard let json,
|
|
let data = json.data(using: .utf8)
|
|
else { return nil }
|
|
return try? JSONDecoder().decode(SidebarItemID.self, from: data)
|
|
}
|
|
|
|
private func encodedSidebarItem(_ item: SidebarItemID?) -> String? {
|
|
guard let item,
|
|
let data = try? JSONEncoder().encode(item),
|
|
let json = String(data: data, encoding: .utf8)
|
|
else { return nil }
|
|
return json
|
|
}
|
|
|
|
func lastSelectedModuleID(for sessionID: UUID) -> String? {
|
|
lastSelectedModuleID(forSessionID: sessionID)
|
|
}
|
|
|
|
func lastSelectedThreadID(for sessionID: UUID) -> UInt? {
|
|
lastSelectedThreadID(forSessionID: sessionID)
|
|
}
|
|
}
|
|
|
|
extension SidebarItemID {
|
|
init(navigationTarget target: NavigationTarget) {
|
|
switch target {
|
|
case .instrumentComponent(let sid, let iid, let cid):
|
|
self = .instrumentComponent(sid, iid, cid)
|
|
case .itrace(let sid, let tid):
|
|
self = .itrace(sid, tid)
|
|
}
|
|
}
|
|
}
|