diff --git a/src/ifcviewer-web/CMakeLists.txt b/src/ifcviewer-web/CMakeLists.txt index aa3301eb1c..e7dbb004f5 100644 --- a/src/ifcviewer-web/CMakeLists.txt +++ b/src/ifcviewer-web/CMakeLists.txt @@ -104,7 +104,7 @@ target_link_options(IfcViewerWeb PRIVATE # EMSCRIPTEN_KEEPALIVE alone keeps the symbols in the binary but doesn't # add them to Module. ccall lets shell.html pass a JS string (the ?model # URL) to load_sidecar_from_url_c without manual heap marshalling. - "-sEXPORTED_FUNCTIONS=['_main','_raf_tick_c','_load_sidecar_from_source_c','_clear_scene_c','_ifcv_on_range_done','_ifcv_chunks_resident_c','_ifcv_chunks_total_c','_ifcv_model_count_c','_ifcv_model_resident_c','_ifcv_model_total_c','_ifcv_bytes_total_c','_ifcv_bytes_needed_c','_ifcv_bytes_loaded_c','_view_all_c','_frame_selection_c','_toggle_projection_c','_projection_is_ortho_c','_standard_view_c','_toggle_fly_c','_fly_is_active_c']" + "-sEXPORTED_FUNCTIONS=['_main','_raf_tick_c','_load_sidecar_from_source_c','_clear_scene_c','_ifcv_on_range_done','_ifcv_chunks_resident_c','_ifcv_chunks_total_c','_ifcv_model_count_c','_ifcv_model_resident_c','_ifcv_model_total_c','_ifcv_bytes_total_c','_ifcv_bytes_needed_c','_ifcv_bytes_loaded_c','_view_all_c','_frame_selection_c','_toggle_projection_c','_projection_is_ortho_c','_standard_view_c','_toggle_fly_c','_fly_is_active_c','_hide_selected_c','_isolate_selected_c','_show_all_c','_toggle_xray_c','_xray_is_active_c']" # ccall: shell.html passes the ?model URL string to load_sidecar_from_url_c. # HEAPU8: lets tooling/tests read the wasm heap size (e.g. to verify a large # sidecar streams by range instead of loading whole). Standard, zero-cost. diff --git a/src/ifcviewer-web/main_web.cpp b/src/ifcviewer-web/main_web.cpp index af6b64ef93..4a0d02bde8 100644 --- a/src/ifcviewer-web/main_web.cpp +++ b/src/ifcviewer-web/main_web.cpp @@ -227,6 +227,16 @@ EM_BOOL onKeyDown(int, const EmscriptenKeyboardEvent* e, void* user) { // While flying, WASDQE/Shift are held-movement keys, not hotkeys. if (app->fly_mode) { if (setFlyKey(app, code, true)) return EM_TRUE; return EM_FALSE; } if (e->repeat) return EM_FALSE; + const bool alt = e->altKey; + // Visibility + X-ray, matching desktop: H hide selected · Shift+H isolate · + // Alt+H show all · Alt+X x-ray. + if (!std::strcmp(code, "KeyH")) { + if (alt) app->core.showAll(); + else if (shift) app->core.isolateSelected(); + else app->core.hideSelected(); + return EM_TRUE; + } + if (!std::strcmp(code, "KeyX") && alt) { app->core.toggleXray(); return EM_TRUE; } using SV = ViewportCore::StandardView; if (!std::strcmp(code, "Home")) app->core.viewAll(); else if (!std::strcmp(code, "KeyF") && !shift) app->core.frameSelection(); @@ -356,6 +366,13 @@ extern "C" EMSCRIPTEN_KEEPALIVE int fly_is_active_c() { return (g_app && g_app->ready && g_app->fly_mode) ? 1 : 0; } +// Visibility + X-ray, for the toolbar (same ops as the H/Shift+H/Alt+H/Alt+X keys). +extern "C" EMSCRIPTEN_KEEPALIVE void hide_selected_c() { if (g_app && g_app->ready) g_app->core.hideSelected(); } +extern "C" EMSCRIPTEN_KEEPALIVE void isolate_selected_c() { if (g_app && g_app->ready) g_app->core.isolateSelected(); } +extern "C" EMSCRIPTEN_KEEPALIVE void show_all_c() { if (g_app && g_app->ready) g_app->core.showAll(); } +extern "C" EMSCRIPTEN_KEEPALIVE void toggle_xray_c() { if (g_app && g_app->ready) g_app->core.toggleXray(); } +extern "C" EMSCRIPTEN_KEEPALIVE int xray_is_active_c() { return (g_app && g_app->ready && g_app->core.xrayActive()) ? 1 : 0; } + // id: 0 Front, 1 Back, 2 Left, 3 Right, 4 Top, 5 Bottom. extern "C" EMSCRIPTEN_KEEPALIVE void standard_view_c(int id) { if (!g_app || !g_app->ready || id < 0 || id > 5) return; diff --git a/src/ifcviewer-web/shell.html b/src/ifcviewer-web/shell.html index 846179b3b7..17ec6f082f 100644 --- a/src/ifcviewer-web/shell.html +++ b/src/ifcviewer-web/shell.html @@ -86,6 +86,11 @@ + + + + +
Starting…