wip autoresize

This commit is contained in:
Jeremy Rose
2022-09-26 11:01:54 -07:00
parent c26f8701b4
commit 5ffe8672a3
3 changed files with 73 additions and 2 deletions

View File

@@ -5,6 +5,11 @@ const v8Util = process._linkedBinding('electron_common_v8_util');
export default class BrowserView {
#webContentsView: WebContentsView
// AutoResize state
#resizeListener: ((...args: any[]) => void) | null = null
#lastWindowSize: {width: number, height: number} = { width: 0, height: 0 }
#autoResizeFlags: AutoResizeOptions = {}
constructor (options?: WebPreferences) {
if (options && 'webContents' in options) {
v8Util.setHiddenValue(options, 'webContents', (options as any).webContents);
@@ -18,6 +23,8 @@ export default class BrowserView {
setBounds (bounds: Rectangle) {
this.#webContentsView.setBounds(bounds);
this.#autoHorizontalProportion = null;
this.#autoVerticalProportion = null;
}
getBounds () {
@@ -26,7 +33,15 @@ export default class BrowserView {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
setAutoResize (options: AutoResizeOptions) {
throw new Error('not implemented');
if (options == null || typeof options !== 'object') { throw new Error('Invalid auto resize options'); }
this.#autoResizeFlags = {
width: !!options.width,
height: !!options.height,
horizontal: !!options.horizontal,
vertical: !!options.vertical
};
this.#autoHorizontalProportion = null;
this.#autoVerticalProportion = null;
}
setBackgroundColor (color: string) {
@@ -39,7 +54,62 @@ export default class BrowserView {
}
set ownerWindow (w: BrowserWindow | null) {
const oldWindow = this.webContents.getOwnerBrowserWindow();
if (oldWindow && this.#resizeListener) {
oldWindow.off('resize', this.#resizeListener);
this.#resizeListener = null;
}
this.webContents._setOwnerWindow(w);
if (w) {
this.#lastWindowSize = w.getBounds();
w.on('resize', this.#resizeListener = this.#autoResize.bind(this));
}
}
#autoHorizontalProportion: {width: number, left: number} | null = null
#autoVerticalProportion: {height: number, top: number} | null = null
#autoResize () {
if (!this.ownerWindow) throw new Error('Electron bug: #autoResize called without owner window');
if (this.#autoResizeFlags.horizontal && this.#autoHorizontalProportion == null) {
const viewBounds = this.#webContentsView.getBounds();
this.#autoHorizontalProportion = {
width: this.#lastWindowSize.width / viewBounds.width,
left: this.#lastWindowSize.width / viewBounds.x
};
}
if (this.#autoResizeFlags.vertical && this.#autoVerticalProportion == null) {
const viewBounds = this.#webContentsView.getBounds();
this.#autoVerticalProportion = {
height: this.#lastWindowSize.height / viewBounds.height,
top: this.#lastWindowSize.height / viewBounds.y
};
}
const newBounds = this.ownerWindow.getBounds();
let widthDelta = newBounds.width - this.#lastWindowSize.width;
let heightDelta = newBounds.height - this.#lastWindowSize.height;
if (!this.#autoResizeFlags.width) widthDelta = 0;
if (!this.#autoResizeFlags.height) heightDelta = 0;
const newViewBounds = this.#webContentsView.getBounds();
if (widthDelta || heightDelta) {
this.#webContentsView.setBounds({
...newViewBounds,
width: newViewBounds.width + widthDelta,
height: newViewBounds.height + heightDelta
});
}
if (this.#autoHorizontalProportion) {
newViewBounds.width = newBounds.width / this.#autoHorizontalProportion.width;
newViewBounds.x = newBounds.width / this.#autoHorizontalProportion.left;
}
if (this.#autoVerticalProportion) {
newViewBounds.height = newBounds.height / this.#autoVerticalProportion.height;
newViewBounds.y = newBounds.y / this.#autoVerticalProportion.top;
}
if (this.#autoHorizontalProportion || this.#autoVerticalProportion) {
this.#webContentsView.setBounds(newViewBounds);
}
}
get webContentsView () {

View File

@@ -306,6 +306,7 @@ void View::BuildPrototype(v8::Isolate* isolate,
.SetProperty("children", &View::GetChildren)
.SetMethod("setBounds", &View::SetBounds)
.SetMethod("getBounds", &View::GetBounds)
.SetMethod("setBackgroundColor", &View::SetBackgroundColor)
.SetMethod("setLayout", &View::SetLayout);
#endif
}

View File

@@ -125,7 +125,7 @@ describe('BrowserView module', () => {
view = new BrowserView();
expect(() => {
view.setAutoResize(null as any);
}).to.throw(/conversion failure/);
}).to.throw(/Invalid auto resize options/);
});
it('resizes horizontally when the window is resized horizontally', () => {