aboutsummaryrefslogtreecommitdiff
path: root/extensions-builtin/resize-handle/javascript/resize-handle.js
blob: a07a01d2f3f65501f307ef13b9027ab0efe73a49 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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();
});