resizeHandle.js 5.7 KB
Newer Older
1 2 3 4
(function() {
    const GRADIO_MIN_WIDTH = 320;
    const PAD = 16;
    const DEBOUNCE_TIME = 100;
A
Andray 已提交
5
    const DOUBLE_TAP_DELAY = 200; //ms
6 7 8 9 10 11 12 13

    const R = {
        tracking: false,
        parent: null,
        parentWidth: null,
        leftCol: null,
        leftColStartWidth: null,
        screenX: null,
A
Andray 已提交
14
        lastTapTime: null,
15 16 17 18 19 20 21 22 23 24 25 26
    };

    let resizeTimer;
    let parents = [];

    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';
A
Andray 已提交
27
            parent.resizeHandle.style.display = "none";
28 29 30
            return false;
        } else {
            parent.style.display = 'grid';
A
Andray 已提交
31
            parent.resizeHandle.style.display = "block";
32 33 34 35 36
            return true;
        }
    }

    function afterResize(parent) {
37
        if (displayResizeHandle(parent) && parent.style.gridTemplateColumns != parent.style.originalGridTemplateColumns) {
38 39 40 41 42 43 44 45 46 47 48 49 50 51
            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;
        }
    }

    function setup(parent) {
A
Andray 已提交
52 53 54 55 56 57 58 59

        function onDoubleClick(evt) {
            evt.preventDefault();
            evt.stopPropagation();

            parent.style.gridTemplateColumns = parent.style.originalGridTemplateColumns;
        }

60 61 62 63 64 65 66
        const leftCol = parent.firstElementChild;
        const rightCol = parent.lastElementChild;

        parents.push(parent);

        parent.style.display = 'grid';
        parent.style.gap = '0';
67 68 69
        const gridTemplateColumns = `${parent.children[0].style.flexGrow}fr ${PAD}px ${parent.children[1].style.flexGrow}fr`;
        parent.style.gridTemplateColumns = gridTemplateColumns;
        parent.style.originalGridTemplateColumns = gridTemplateColumns;
70 71 72 73

        const resizeHandle = document.createElement('div');
        resizeHandle.classList.add('resize-handle');
        parent.insertBefore(resizeHandle, rightCol);
A
Andray 已提交
74
        parent.resizeHandle = resizeHandle;
75

76 77
        ['mousedown', 'touchstart'].forEach((eventType) => {
            resizeHandle.addEventListener(eventType, (evt) => {
A
Andray 已提交
78
                if (eventType.startsWith('mouse')) {
79 80 81
                    if (evt.button !== 0) return;
                } else {
                    if (evt.changedTouches.length !== 1) return;
A
Andray 已提交
82 83 84 85 86 87 88 89

                    const currentTime = new Date().getTime();
                    if (R.lastTapTime && currentTime - R.lastTapTime <= DOUBLE_TAP_DELAY) {
                        onDoubleClick(evt);
                        return;
                    }

                    R.lastTapTime = currentTime;
90 91 92 93 94 95 96 97 98 99 100 101
                }

                evt.preventDefault();
                evt.stopPropagation();

                document.body.classList.add('resizing');

                R.tracking = true;
                R.parent = parent;
                R.parentWidth = parent.offsetWidth;
                R.leftCol = leftCol;
                R.leftColStartWidth = leftCol.offsetWidth;
A
Andray 已提交
102
                if (eventType.startsWith('mouse')) {
103 104 105 106 107
                    R.screenX = evt.screenX;
                } else {
                    R.screenX = evt.changedTouches[0].screenX;
                }
            });
108 109
        });

A
Andray 已提交
110
        resizeHandle.addEventListener('dblclick', onDoubleClick);
111

112 113 114
        afterResize(parent);
    }

115 116
    ['mousemove', 'touchmove'].forEach((eventType) => {
        window.addEventListener(eventType, (evt) => {
A
Andray 已提交
117
            if (eventType.startsWith('mouse')) {
118 119 120 121
                if (evt.button !== 0) return;
            } else {
                if (evt.changedTouches.length !== 1) return;
            }
M
MMP0 已提交
122

123
            if (R.tracking) {
A
Andray 已提交
124 125 126
                if (eventType.startsWith('mouse')) {
                    evt.preventDefault();
                }
127
                evt.stopPropagation();
A
Andray 已提交
128

A
Andray 已提交
129 130 131
                let delta = 0;
                if (eventType.startsWith('mouse')) {
                    delta = R.screenX - evt.screenX;
132
                } else {
A
Andray 已提交
133
                    delta = R.screenX - evt.changedTouches[0].screenX;
134 135 136 137 138
                }
                const leftColWidth = Math.max(Math.min(R.leftColStartWidth - delta, R.parent.offsetWidth - GRADIO_MIN_WIDTH - PAD), GRADIO_MIN_WIDTH);
                setLeftColGridTemplate(R.parent, leftColWidth);
            }
        });
139 140
    });

141 142
    ['mouseup', 'touchend'].forEach((eventType) => {
        window.addEventListener(eventType, (evt) => {
A
Andray 已提交
143
            if (eventType.startsWith('mouse')) {
144 145 146 147
                if (evt.button !== 0) return;
            } else {
                if (evt.changedTouches.length !== 1) return;
            }
148

149 150 151
            if (R.tracking) {
                evt.preventDefault();
                evt.stopPropagation();
M
MMP0 已提交
152

153
                R.tracking = false;
M
MMP0 已提交
154

155 156 157
                document.body.classList.remove('resizing');
            }
        });
M
MMP0 已提交
158
    });
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175


    window.addEventListener('resize', () => {
        clearTimeout(resizeTimer);

        resizeTimer = setTimeout(function() {
            for (const parent of parents) {
                afterResize(parent);
            }
        }, DEBOUNCE_TIME);
    });

    setupResizeHandle = setup;
})();

onUiLoaded(function() {
    for (var elem of gradioApp().querySelectorAll('.resize-handle-row')) {
C
catboxanon 已提交
176 177 178
        if (!elem.querySelector('.resize-handle')) {
            setupResizeHandle(elem);
        }
179 180
    }
});