From 480c2df23f7b16fbc2084e73e812fe839866a41e Mon Sep 17 00:00:00 2001 From: Iisakki Rotko Date: Wed, 11 Dec 2024 16:26:02 +0100 Subject: [PATCH] feat: add resize and focus timestamps to view_data This allows us to track what view is the active one, and resize figures based on that. --- bqplot_image_gl/viewlistener.py | 5 ++++- js/lib/ViewListener.js | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/bqplot_image_gl/viewlistener.py b/bqplot_image_gl/viewlistener.py index 1ba5608..7ce731c 100644 --- a/bqplot_image_gl/viewlistener.py +++ b/bqplot_image_gl/viewlistener.py @@ -2,7 +2,8 @@ from ipywidgets.widgets import widget_serialization from traitlets import Unicode, Dict, Instance from bqplot_image_gl._version import __version__ -from typing import TypedDict, cast, Dict as DictType +from typing import cast, Dict as DictType +from typing_extensions import TypedDict __all__ = ['ViewListener'] @@ -12,6 +13,8 @@ class ViewDataEntry(TypedDict): y: float width: float height: float + resized_at: str # ISO 8601 + focused_at: str # ISO 8601 @widgets.register diff --git a/js/lib/ViewListener.js b/js/lib/ViewListener.js index a1181a1..6cd945c 100644 --- a/js/lib/ViewListener.js +++ b/js/lib/ViewListener.js @@ -34,6 +34,9 @@ class ViewListenerModel extends base.DOMWidgetModel { } bind(this.get('widget')); window.lastViewListenerModel = this; + window.addEventListener('focus', () => { + this._updateAllViewData(); + }); } async _getViews() { const widgetModel = this.get('widget'); @@ -57,7 +60,7 @@ class ViewListenerModel extends base.DOMWidgetModel { // listen to element for resize events views.forEach((view) => { const resizeObserver = new ResizeObserver(entries => { - this._updateViewData(view); + this._updateViewData(view, true); }); let el = view.el; el = selector ? el.querySelector(selector) : el; @@ -70,12 +73,22 @@ class ViewListenerModel extends base.DOMWidgetModel { } }) } - async _updateViewData(view) { + async _updateViewData(view, resized=false, focused=false) { const selector = this.get('css_selector'); let el = view.el; el = selector ? el.querySelector(selector) : el; if(el) { const {x, y, width, height} = el.getBoundingClientRect(); + const previousData = this.get('view_data'); + let resized_at = previousData[view.cid]?.resized_at; + let focused_at = previousData[view.cid]?.focused_at; + const currentDateTimeJSISO = (new Date()).toISOString(); + // Javascripts toISOString and Python's datetime.fromisoformat implement different parts of + // the ISO 8601 standard, so we replace Z (indicating Zulu time) with +00:00 to make it compatible with python + const currentDateTime = currentDateTimeJSISO.replace('Z', '+00:00'); + + resized_at = (resized || resized_at === undefined) ? currentDateTime : resized_at; + focused_at = (focused || focused_at === undefined) ? currentDateTime : focused_at; this.send({ event: 'set_view_data', id: view.cid,