mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
wip autoresize
This commit is contained in:
@@ -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 () {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
Reference in New Issue
Block a user