Repository navigation
Custom Sheet Views ‐ Tutorial
c-g-dev edited this page Oct 11, 2024
·
1 revision
// SheetView is an abstraction for an object which creates/manages the custom sheet view element
interface SheetView {
function getElement(): Element;
}
//row-level information passed to the handler
typedef SheetViewContext = {
var sheet: Sheet; //this sheet
var rowIndex: Dynamic; //index of the row in the sheet
var row: Dynamic; //the row object in the database
var sheetView: SheetView; //this SheetView
var handler: SheetViewHandler; //this handler
}
typedef SheetViewHandler = {
var definition: {
name: String, //sheet type name, e.g "Level"
schema: Array<{n: String, t: ColumnType}> //the columns which are prepopulated
};
function render(context: SheetViewContext): SheetView; //create and return the SheetView
function toRowObject(context: SheetViewContext): Promise<Dynamic>; //write the information in the GUI control back to a database row
var ?onClose: (SheetViewContext) -> Promise<Void>; //optional clean-up
}// SheetView
var DrawingCanvasSheetView: SheetView = (context) -> {
var iframe: IFrameElement = Browser.document.createElement('iframe');
iframe.style.border = 'none';
iframe.width = '800';
iframe.height = '600';
// Set the iframe content
iframe.srcdoc = '''
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.0/fabric.min.js"></script>
</head>
<body>
<canvas id="canvas" width="800" height="600"></canvas>
<script>
var canvas = new fabric.Canvas('canvas');
// Expose canvas to the parent window
window.canvas = canvas;
</script>
</body>
</html>
''';
return {
getElement: () -> iframe,
getCanvas: () -> new Promise((resolve, reject) -> {
iframe.onload = () -> {
var canvas = iframe.contentWindow.canvas;
if (canvas != null) {
resolve(canvas);
} else {
reject('Canvas not found');
}
};
})
};
};
// SheetViewHandler
var DrawingCanvasSheetHandler: SheetViewHandler = {
definition: {
name: "Drawing Canvas Sheet",
schema: [
{ n: "id", t: ColumnType.TString },
{ n: "drawingData", t: ColumnType.TString },
]
},
render: (context) -> {
return DrawingCanvasSheetView(context);
},
toRowObject: (context) -> {
return context.sheetView.getCanvas().then((canvas) -> {
var data = canvas.toJSON();
var rowData = {
id: context.row.id,
drawingData: Json.stringify(data)
};
return rowData;
});
},
onClose: (context) -> {
// Any cleanup if necessary
return Promise.resolve();
}
};You can wrap a SheetViewHandler as an hscript plugin which can be directly dropped in the /plugins folder:
typedef Plugin = {
var type:String;
var ?name:String;
}
typedef SheetViewPlugin = Plugin & SheetViewHandler;Then, inside your plugin file:
// SheetViewPlugin
var DrawingCanvasSheetPlugin: SheetViewPlugin = {
//...everything from the above example
type: "SheetViewPlugin",
name: "FabricJSSheetPlugin"
};
var export = DrawingCanvasSheetPlugin;
Alternatively, if you are building from source, you can directly register your custom sheet handler with the SheetViewManager at compilation time.
SheetViewManager.register(MyCustomSheetHandler);