Integrate supported ops into the UI
This commit is contained in:
6
api.cpp
6
api.cpp
@@ -185,12 +185,6 @@ class Context {
|
||||
});
|
||||
}
|
||||
|
||||
void triggerCapture() {
|
||||
gpp_rethrow([=]() {
|
||||
gpp_try(gp_camera_trigger_capture(camera.get(), context.get()));
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
gpp_unique_ptr<Camera, gp_camera_unref> camera;
|
||||
gpp_unique_ptr<GPContext, gp_context_unref> context;
|
||||
|
||||
10
libapi.mjs.d.ts
vendored
10
libapi.mjs.d.ts
vendored
@@ -13,6 +13,15 @@ export type Config = {
|
||||
| { type: 'datetime'; value: number }
|
||||
);
|
||||
|
||||
declare interface SupportedOps {
|
||||
captureImage: boolean;
|
||||
captureVideo: boolean;
|
||||
captureAudio: boolean;
|
||||
capturePreview: boolean;
|
||||
config: boolean;
|
||||
triggerCapture: boolean;
|
||||
}
|
||||
|
||||
declare class Context {
|
||||
configToJS(): Promise<Config & { type: 'window' }>;
|
||||
setConfigValue(
|
||||
@@ -22,6 +31,7 @@ declare class Context {
|
||||
capturePreviewAsBlob(): Promise<Blob>;
|
||||
captureImageAsFile(): Promise<File>;
|
||||
hasPendingEvent(): Promise<boolean>;
|
||||
supportedOps(): SupportedOps;
|
||||
|
||||
delete(): void;
|
||||
isDeleted(): boolean;
|
||||
|
||||
@@ -143,7 +143,9 @@ class App extends Component {
|
||||
'div',
|
||||
{ class: 'pure-u-2-3' },
|
||||
h(Preview, {
|
||||
getPreview: this.capturePreview
|
||||
getPreview: this.connection.supportedOps.capturePreview
|
||||
? this.capturePreview
|
||||
: undefined
|
||||
})
|
||||
),
|
||||
h(
|
||||
@@ -152,7 +154,9 @@ class App extends Component {
|
||||
h(
|
||||
'form',
|
||||
{ class: 'pure-form pure-form-aligned' },
|
||||
h(CaptureButton, { getFile: this.captureImage }),
|
||||
this.connection.supportedOps.triggerCapture
|
||||
? h(CaptureButton, { getFile: this.captureImage })
|
||||
: undefined,
|
||||
h(Widget, { config: state.config, setValue: this.setValue })
|
||||
)
|
||||
)
|
||||
|
||||
@@ -2,12 +2,13 @@ import initModule from '../libapi.mjs';
|
||||
|
||||
/** @typedef {import('../libapi.mjs').Context} Context */
|
||||
|
||||
const ContextPromise = initModule().then(Module => Module.Context);
|
||||
const ModulePromise = initModule();
|
||||
|
||||
export async function connect() {
|
||||
let Context = await ContextPromise;
|
||||
const Module = await ModulePromise;
|
||||
|
||||
let context = await new Context();
|
||||
let context = await new Module.Context();
|
||||
let supportedOps = await context.supportedOps();
|
||||
|
||||
let queue = Promise.resolve();
|
||||
|
||||
@@ -30,6 +31,7 @@ export async function connect() {
|
||||
}
|
||||
|
||||
return {
|
||||
supportedOps,
|
||||
schedule,
|
||||
disconnect() {
|
||||
context.delete();
|
||||
|
||||
@@ -8,7 +8,7 @@ const Stats = isDebug
|
||||
)
|
||||
: null;
|
||||
|
||||
/** @extends Component<{ getPreview: () => Promise<Blob> }, { error?: string }> */
|
||||
/** @extends Component<{ getPreview?: () => Promise<Blob> }, { error?: string }> */
|
||||
export class Preview extends Component {
|
||||
canvasHolderRef = createRef();
|
||||
canvasRef = createRef();
|
||||
@@ -20,17 +20,15 @@ export class Preview extends Component {
|
||||
return h(
|
||||
'div',
|
||||
{ class: 'center-parent', ref: this.canvasHolderRef },
|
||||
this.state.error
|
||||
? h(
|
||||
'div',
|
||||
{ class: 'center' },
|
||||
`Could not retrieve preview: ${this.state.error}`
|
||||
)
|
||||
!this.props.getPreview
|
||||
? h('div', { class: 'center' }, `Preview is unsupported`)
|
||||
: h('canvas', { class: 'center', ref: this.canvasRef })
|
||||
);
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
if (!this.props.getPreview) return;
|
||||
|
||||
let canvas = /** @type {HTMLCanvasElement} */ (this.canvasRef.current);
|
||||
let canvasHolder = this.canvasHolderRef.current;
|
||||
|
||||
@@ -70,13 +68,8 @@ export class Preview extends Component {
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
while (this.canvasRef.current) {
|
||||
let blob;
|
||||
try {
|
||||
blob = await this.props.getPreview();
|
||||
} catch (error) {
|
||||
this.setState({ error: error.message });
|
||||
return;
|
||||
}
|
||||
let blob = await this.props.getPreview();
|
||||
|
||||
// If ratio is known; decode resized image right away - it's a bit faster.
|
||||
// If it isn't known, retrieve entire image to calculate ratio from its dimensions.
|
||||
@@ -94,15 +87,15 @@ export class Preview extends Component {
|
||||
updateCanvasSize();
|
||||
}
|
||||
canvasCtx.transferFromImageBitmap(img);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(resolve));
|
||||
this.stats?.update();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.resizeObserver.disconnect();
|
||||
if (isDebug) {
|
||||
this.canvasHolderRef.current.removeChild(this.stats.dom);
|
||||
}
|
||||
this.resizeObserver?.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,11 +68,13 @@ export class Widget extends Component {
|
||||
let { label, name } = config;
|
||||
let id = `config-${name}`;
|
||||
if (config.type === 'window' || config.type === 'section') {
|
||||
let children = Object.values(config.children);
|
||||
if (!children.length) return;
|
||||
return h(
|
||||
'fieldset',
|
||||
{ id },
|
||||
h('legend', {}, label),
|
||||
Object.values(config.children).map(config =>
|
||||
children.map(config =>
|
||||
h(Widget, { key: config.name, config, setValue })
|
||||
)
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user