From a3c8510c053b4f5f09f4230949271054591814df Mon Sep 17 00:00:00 2001 From: catboxanon <122327233+catboxanon@users.noreply.github.com> Date: Sun, 20 Aug 2023 00:37:39 -0400 Subject: Add resize-handler extension --- .../resize-handle/javascript/resize-handle.js | 106 +++++++++++++++++++++ extensions-builtin/resize-handle/style.css | 10 ++ 2 files changed, 116 insertions(+) create mode 100644 extensions-builtin/resize-handle/javascript/resize-handle.js create mode 100644 extensions-builtin/resize-handle/style.css diff --git a/extensions-builtin/resize-handle/javascript/resize-handle.js b/extensions-builtin/resize-handle/javascript/resize-handle.js new file mode 100644 index 00000000..a07a01d2 --- /dev/null +++ b/extensions-builtin/resize-handle/javascript/resize-handle.js @@ -0,0 +1,106 @@ +onUiLoaded(async() => { + const GRADIO_MIN_WIDTH = 320; + const GRID_TEMPLATE_COLUMNS = '1fr 16px 1fr'; + const PAD = 16; + const DEBOUNCE_TIME = 100; + + const R = { + tracking: false, + parent: null, + parentWidth: null, + leftCol: null, + leftColStartWidth: null, + screenX: null, + }; + + let resizeTimer; + + const leftCols = [ + gradioApp().querySelector('#txt2img_settings'), + gradioApp().querySelector('#img2img_settings'), + ]; + + function setLeftColGridTemplate(el, width) { + el.style.gridTemplateColumns = `${width}px 16px 1fr`; + } + + function displayResizeHandle(parent) { + if (window.innerWidth < GRADIO_MIN_WIDTH * 2 + PAD * 4) { + parent.style.display = 'flex'; + if (R.handle != null) { + R.handle.style.opacity = '0'; + } + return false; + } else { + parent.style.display = 'grid'; + if (R.handle != null) { + R.handle.style.opacity = '100'; + } + return true; + } + } + + function setup() { + for (const leftCol of leftCols) { + const parent = leftCol.parentElement; + const rightCol = parent.lastElementChild; + + if (!displayResizeHandle(parent)) { + return; + } + + parent.style.display = 'grid'; + parent.style.gap = '0'; + parent.style.gridTemplateColumns = GRID_TEMPLATE_COLUMNS; + + const resizeHandle = document.createElement('div'); + resizeHandle.classList.add('resize-handle'); + parent.insertBefore(resizeHandle, rightCol); + + resizeHandle.addEventListener('mousedown', (evt) => { + R.tracking = true; + R.parent = parent; + R.parentWidth = parent.offsetWidth; + R.handle = resizeHandle; + R.leftCol = leftCol; + R.leftColStartWidth = leftCol.offsetWidth; + R.screenX = evt.screenX; + }); + } + } + + window.addEventListener('mousemove', (evt) => { + if (R.tracking) { + const delta = R.screenX - evt.screenX; + const leftColWidth = Math.max(Math.min(R.leftColStartWidth - delta, R.parent.offsetWidth - GRADIO_MIN_WIDTH - PAD), GRADIO_MIN_WIDTH); + setLeftColGridTemplate(R.parent, leftColWidth); + } + }); + + window.addEventListener('mouseup', () => R.tracking = false); + + window.addEventListener('resize', () => { + clearTimeout(resizeTimer); + + resizeTimer = setTimeout(() => { + for (const leftCol of leftCols) { + const parent = leftCol.parentElement; + + if (displayResizeHandle(parent) && parent.style.gridTemplateColumns != GRID_TEMPLATE_COLUMNS) { + const oldParentWidth = R.parentWidth; + const newParentWidth = parent.offsetWidth; + const widthL = parseInt(parent.style.gridTemplateColumns.split(' ')[0]); + + const ratio = newParentWidth / oldParentWidth; + + const newWidthL = Math.max(Math.floor(ratio * widthL), GRADIO_MIN_WIDTH); + setLeftColGridTemplate(parent, newWidthL); + + R.parentWidth = newParentWidth; + } + } + }, DEBOUNCE_TIME); + }); + + setup(); +}); diff --git a/extensions-builtin/resize-handle/style.css b/extensions-builtin/resize-handle/style.css new file mode 100644 index 00000000..0e18267a --- /dev/null +++ b/extensions-builtin/resize-handle/style.css @@ -0,0 +1,10 @@ +.resize-handle{ + cursor: col-resize; + grid-column: 2 / 3; + min-width: 8px !important; + max-width: 8px !important; + height: 100%; + border-left: 1px dashed var(--border-color-primary); + user-select: none; + margin-left: 8px; +} \ No newline at end of file -- cgit v1.2.1