feat(read-only-viewer): editor viewer mode + kicadSetReadOnly binding
Anonymous / non-member sessions open PUBLIC projects as read-only viewers.
- kicadSetReadOnly(bool) embind (merged kicad_editor + pcbnew/eeschema/
pl_editor TUs): sets the PCBJAM_READ_ONLY flag + Prj().SetReadOnly (greys
the setup dialogs). Polls until the frame exists.
- read-only-mode.ts: resolveReadOnly(access, win) — server `access:"read"` or
?readonly=1 (narrow-only; no ?readonly=0). ToolPage threads it in, omits
saveBytes (MEMFS-only saves).
- WasmTool: chrome force-hidden with a "View only" pill (toggle + Cmd+\
disabled), presence/cross-app/comments/drift skipped, save-driven room
writers unregistered, wasm frame locked via kicadSetReadOnly failing CLOSED
(stale bundle → boot error, never a writable frame).
- collab: bindKicadCollab {readOnly} — inert DOWN hook, never seeds a room;
UP observer + adopt stay live so peer edits render. index.ts / sheet-manager
thread readOnly + drop initial awareness (invisible observer).
- Reference backend emits access:"write".
Bumps kicad + web/pcbjam-shared to the read-only-viewer commits.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012DN9py5GuPdExaaFzE4k27
This commit is contained in:
parent
f07b9970d5
commit
bb01f5d9e6
16 changed files with 665 additions and 49 deletions
|
|
@ -22,6 +22,8 @@
|
|||
#include <nlohmann/json.hpp>
|
||||
#include <kiid.h>
|
||||
#include <layer_ids.h>
|
||||
#include <pcbjam_read_only.h>
|
||||
#include <project.h>
|
||||
#include <schematic.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <sch_io/kicad_sexpr/sch_io_kicad_sexpr.h>
|
||||
|
|
@ -91,6 +93,24 @@ bool kicadOpenFile( std::string path )
|
|||
return frame->OpenProjectFiles(
|
||||
std::vector<wxString>( 1, wxString::FromUTF8( path.c_str() ) ) );
|
||||
}
|
||||
|
||||
// Read-only viewer lock (read-only-viewer): flips the process-global
|
||||
// PCBJAM_READ_ONLY flag consumed by TOOL_MANAGER (view-only action allowlist)
|
||||
// and the selection tools (nothing selectable), and mirrors it onto the
|
||||
// project so the setup dialogs grey out. Returns false until the editor frame
|
||||
// exists so JS polls; the shell fails CLOSED if it never applies.
|
||||
bool kicadSetReadOnly( bool aReadOnly )
|
||||
{
|
||||
KIWAY_PLAYER* frame =
|
||||
wxTheApp ? dynamic_cast<KIWAY_PLAYER*>( wxTheApp->GetTopWindow() ) : nullptr;
|
||||
|
||||
if( !frame )
|
||||
return false;
|
||||
|
||||
PCBJAM_READ_ONLY::Set( aReadOnly );
|
||||
frame->Prj().SetReadOnly( aReadOnly );
|
||||
return true;
|
||||
}
|
||||
#endif // !KICAD_MERGED_EMBIND
|
||||
|
||||
// ───────────────────────────── Yjs collaborative bridge ─────────────────────────────
|
||||
|
|
@ -1714,6 +1734,8 @@ EMSCRIPTEN_BINDINGS(eeschema) {
|
|||
// registered once by kicad_editor_embind.cpp, dispatching on the active frame.
|
||||
// Programmatic file open (preferred over UI automation from the web app).
|
||||
function("kicadOpenFile", &kicadOpenFile);
|
||||
// Read-only viewer lock (read-only-viewer).
|
||||
function("kicadSetReadOnly", &kicadSetReadOnly);
|
||||
// Yjs collaborative bridge entry points (same contract as pl_editor).
|
||||
function("kicadCollabApply", &schCollabApply);
|
||||
function("kicadCollabSnapshot", &schCollabSnapshot);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
#include <wx/aui/framemanager.h>
|
||||
#include <kiway.h>
|
||||
#include <kiway_player.h>
|
||||
#include <pcbjam_read_only.h>
|
||||
#include <project.h>
|
||||
|
||||
#include "pcbjam_libs_reload.h"
|
||||
|
||||
|
|
@ -255,6 +257,27 @@ static bool kicadSetChrome( bool aShow )
|
|||
}
|
||||
|
||||
|
||||
// Read-only viewer lock (read-only-viewer): flips the process-global
|
||||
// PCBJAM_READ_ONLY flag consumed by TOOL_MANAGER (view-only action allowlist)
|
||||
// and the selection tools (nothing selectable), and mirrors it onto the
|
||||
// project so the setup dialogs grey out. Zoom/pan stay live (mouse/touch
|
||||
// bypass the tool system; keyboard zoom/pan is allowlisted). Returns false
|
||||
// until the editor frame exists — main() builds it after runtime init — so
|
||||
// JS polls this; the shell fails CLOSED if it never applies.
|
||||
static bool kicadSetReadOnly( bool aReadOnly )
|
||||
{
|
||||
KIWAY_PLAYER* frame =
|
||||
wxTheApp ? dynamic_cast<KIWAY_PLAYER*>( wxTheApp->GetTopWindow() ) : nullptr;
|
||||
|
||||
if( !frame )
|
||||
return false;
|
||||
|
||||
PCBJAM_READ_ONLY::Set( aReadOnly );
|
||||
frame->Prj().SetReadOnly( aReadOnly );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// C++ → JS save notification. Called from BOTH fork save chokepoints
|
||||
// (PCB_EDIT_FRAME::SavePcbFile and SCH_EDIT_FRAME::saveSchematicFile) — one shared
|
||||
// definition serves the merged image. No-op without a JS listener.
|
||||
|
|
@ -427,6 +450,9 @@ EMSCRIPTEN_BINDINGS(kicad_editor) {
|
|||
// Canvas-only mobile mode (features/mobile).
|
||||
function("kicadSetChrome", &kicadSetChrome);
|
||||
|
||||
// Read-only viewer lock (read-only-viewer).
|
||||
function("kicadSetReadOnly", &kicadSetReadOnly);
|
||||
|
||||
// Yjs collaborative bridge entry points — same JS contract as the standalone
|
||||
// bundles, dispatched on the active editor frame.
|
||||
function("kicadCollabApply", &collabApply);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@
|
|||
#include <tool/coroutine.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <pcbjam_remote_lock.h>
|
||||
#include <pcbjam_read_only.h>
|
||||
#include <project.h>
|
||||
#include <view/view.h>
|
||||
#include <view/view_overlay.h>
|
||||
#include <pcb_draw_panel_gal.h>
|
||||
|
|
@ -93,6 +95,24 @@ bool kicadOpenFile( std::string path )
|
|||
return frame->OpenProjectFiles(
|
||||
std::vector<wxString>( 1, wxString::FromUTF8( path.c_str() ) ) );
|
||||
}
|
||||
|
||||
// Read-only viewer lock (read-only-viewer): flips the process-global
|
||||
// PCBJAM_READ_ONLY flag consumed by TOOL_MANAGER (view-only action allowlist)
|
||||
// and the selection tools (nothing selectable), and mirrors it onto the
|
||||
// project so the setup dialogs grey out. Returns false until the editor frame
|
||||
// exists so JS polls; the shell fails CLOSED if it never applies.
|
||||
bool kicadSetReadOnly( bool aReadOnly )
|
||||
{
|
||||
KIWAY_PLAYER* frame =
|
||||
wxTheApp ? dynamic_cast<KIWAY_PLAYER*>( wxTheApp->GetTopWindow() ) : nullptr;
|
||||
|
||||
if( !frame )
|
||||
return false;
|
||||
|
||||
PCBJAM_READ_ONLY::Set( aReadOnly );
|
||||
frame->Prj().SetReadOnly( aReadOnly );
|
||||
return true;
|
||||
}
|
||||
#endif // !KICAD_MERGED_EMBIND
|
||||
|
||||
// ───────────────────────────── Yjs collaborative bridge ─────────────────────────────
|
||||
|
|
@ -1980,6 +2000,8 @@ EMSCRIPTEN_BINDINGS(pcbnew) {
|
|||
// registered once by kicad_editor_embind.cpp, dispatching on the active frame.
|
||||
// Programmatic file open (preferred over UI automation from the web app).
|
||||
function("kicadOpenFile", &kicadOpenFile);
|
||||
// Read-only viewer lock (read-only-viewer).
|
||||
function("kicadSetReadOnly", &kicadSetReadOnly);
|
||||
// Yjs collaborative bridge entry points (same contract as pl_editor / eeschema).
|
||||
function("kicadCollabApply", &pcbCollabApply);
|
||||
function("kicadCollabSnapshot", &pcbCollabSnapshot);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
#include <nlohmann/json.hpp>
|
||||
#include <eda_draw_frame.h>
|
||||
#include <kiid.h>
|
||||
#include <pcbjam_read_only.h>
|
||||
#include <project.h>
|
||||
#include <font/text_attributes.h>
|
||||
#include <drawing_sheet/ds_data_model.h>
|
||||
#include <drawing_sheet/ds_data_item.h>
|
||||
|
|
@ -48,6 +50,24 @@ bool kicadOpenFile( std::string path )
|
|||
std::vector<wxString>( 1, wxString::FromUTF8( path.c_str() ) ) );
|
||||
}
|
||||
|
||||
// Read-only viewer lock (read-only-viewer): flips the process-global
|
||||
// PCBJAM_READ_ONLY flag consumed by TOOL_MANAGER (view-only action allowlist)
|
||||
// and the selection tools (nothing selectable), and mirrors it onto the
|
||||
// project so the setup dialogs grey out. Returns false until the editor frame
|
||||
// exists so JS polls; the shell fails CLOSED if it never applies.
|
||||
bool kicadSetReadOnly( bool aReadOnly )
|
||||
{
|
||||
KIWAY_PLAYER* frame =
|
||||
wxTheApp ? dynamic_cast<KIWAY_PLAYER*>( wxTheApp->GetTopWindow() ) : nullptr;
|
||||
|
||||
if( !frame )
|
||||
return false;
|
||||
|
||||
PCBJAM_READ_ONLY::Set( aReadOnly );
|
||||
frame->Prj().SetReadOnly( aReadOnly );
|
||||
return true;
|
||||
}
|
||||
|
||||
// Programmatically save the in-memory drawing sheet to a .kicad_wks file, without
|
||||
// driving the Save As dialog. pl_editor edits the process-wide singleton
|
||||
// DS_DATA_MODEL::GetTheInstance(), so this serializes exactly what the editor has
|
||||
|
|
@ -553,6 +573,8 @@ std::string kicadCollabTestAddText( std::string aText, double aX, double aY )
|
|||
EMSCRIPTEN_BINDINGS(pl_editor) {
|
||||
// Programmatic file open (preferred over UI automation from the web app).
|
||||
function("kicadOpenFile", &kicadOpenFile);
|
||||
// Read-only viewer lock (read-only-viewer).
|
||||
function("kicadSetReadOnly", &kicadSetReadOnly);
|
||||
function("kicadSaveDrawingSheet", &kicadSaveDrawingSheet);
|
||||
// Yjs collaborative bridge entry points.
|
||||
function("kicadCollabApply", &kicadCollabApply);
|
||||
|
|
|
|||
Loading…
Reference in a new issue