Add option to toggle between default options (#45)
* Add option to toggle between default options - Fix img2img red overlay not updating with changes - Add min-width of 2.5em to select so it's not thinpull/47/head
parent
c4274cb84f
commit
ab303d6e97
|
|
@ -6,6 +6,7 @@ MIN_DIMENSION = 64
|
|||
ARH_EXPAND_BY_DEFAULT_KEY = 'arh_expand_by_default'
|
||||
ARH_HIDE_ACCORDION_BY_DEFAULT_KEY = 'arh_hide_accordion_by_default'
|
||||
ARH_UI_COMPONENT_ORDER_KEY = 'arh_ui_component_order_key'
|
||||
ARH_UI_JAVASCRIPT_SELECTION_METHOD = 'arh_ui_javascript_selection_method'
|
||||
ARH_JAVASCRIPT_ASPECT_RATIO_SHOW_KEY = 'arh_javascript_aspect_ratio_show'
|
||||
ARH_JAVASCRIPT_ASPECT_RATIOS_KEY = 'arh_javascript_aspect_ratio'
|
||||
ARH_SHOW_MAX_WIDTH_OR_HEIGHT_KEY = 'arh_show_max_width_or_height'
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ OPT_KEY_TO_DEFAULT_MAP = {
|
|||
_constants.ARH_HIDE_ACCORDION_BY_DEFAULT_KEY: True,
|
||||
_constants.ARH_UI_COMPONENT_ORDER_KEY:
|
||||
DEFAULT_UI_COMPONENT_ORDER_KEY,
|
||||
_constants.ARH_UI_JAVASCRIPT_SELECTION_METHOD: 'Aspect Ratios Dropdown',
|
||||
_constants.ARH_JAVASCRIPT_ASPECT_RATIO_SHOW_KEY: True,
|
||||
_constants.ARH_JAVASCRIPT_ASPECT_RATIOS_KEY:
|
||||
'1:1, 3:2, 4:3, 5:4, 16:9, 1.85:1, 2.35:1, 2.39:1, 2.40:1, '
|
||||
'21:9, 1.375:1, 1.66:1, 1.75:1',
|
||||
'1:1, 3:2, 4:3, 5:4, 16:9',
|
||||
_constants.ARH_SHOW_MAX_WIDTH_OR_HEIGHT_KEY: False,
|
||||
_constants.ARH_MAX_WIDTH_OR_HEIGHT_KEY:
|
||||
_constants.MAX_DIMENSION / 2,
|
||||
|
|
@ -110,6 +110,23 @@ def on_ui_settings():
|
|||
section=_constants.SECTION,
|
||||
),
|
||||
)
|
||||
shared.opts.add_option(
|
||||
key=_constants.ARH_UI_JAVASCRIPT_SELECTION_METHOD,
|
||||
info=shared.OptionInfo(
|
||||
default=OPT_KEY_TO_DEFAULT_MAP.get(
|
||||
_constants.ARH_UI_JAVASCRIPT_SELECTION_METHOD,
|
||||
),
|
||||
label='JavaScript selection method',
|
||||
component=gr.Dropdown,
|
||||
component_args=lambda: {
|
||||
'choices': [
|
||||
'Aspect Ratios Dropdown',
|
||||
'Default Options Button',
|
||||
],
|
||||
},
|
||||
section=_constants.SECTION,
|
||||
),
|
||||
)
|
||||
|
||||
# accordion options
|
||||
shared.opts.add_option(
|
||||
|
|
|
|||
|
|
@ -26,13 +26,11 @@ const getCurrentImage = () => {
|
|||
return document.getElementById(currentTabImageId).querySelector('img');
|
||||
}
|
||||
|
||||
// utility functions
|
||||
const roundToClosestMultiple = (num, multiple) => {
|
||||
const rounded = Math.round(Number(num) / multiple) * multiple;
|
||||
const rounded = Math.round(Number(num) / multiple) * multiple;
|
||||
return rounded;
|
||||
}
|
||||
|
||||
|
||||
const aspectRatioFromStr = (ar) => {
|
||||
if (!ar.includes(':')) return;
|
||||
return ar.split(':').map(x => Number(x));
|
||||
|
|
@ -80,34 +78,35 @@ const reverseAllOptions = () => {
|
|||
});
|
||||
}
|
||||
|
||||
class SelectController {
|
||||
class OptionPickingController {
|
||||
constructor(page, defaultOptions, controller) {
|
||||
this.page = page;
|
||||
this.options = [...new Set([...defaultOptions, ...getOptions()])];
|
||||
this.options = this.getOptions(defaultOptions);
|
||||
this.switchButton = gradioApp().getElementById(page + '_res_switch_btn');
|
||||
|
||||
const wrapperDiv = document.createElement('div');
|
||||
wrapperDiv.setAttribute("id", `${this.page}_size_toolbox`);
|
||||
wrapperDiv.setAttribute("class", "flex flex-col relative col gap-4");
|
||||
wrapperDiv.setAttribute("style", "min-width: min(320px, 100%); flex-grow: 0");
|
||||
wrapperDiv.innerHTML = `
|
||||
<div id="${this.page}_ratio" class="gr-block gr-box relative w-full border-solid border border-gray-200 gr-padded">
|
||||
<select id="${this.page}_select_aspect_ratio" class="gr-box gr-input w-full disabled:cursor-not-allowed">
|
||||
${this.options.map(r => {
|
||||
return '<option class="ar-option">' + r + '</option>'
|
||||
}).join('\n')}
|
||||
</select>
|
||||
</div>
|
||||
`;
|
||||
wrapperDiv.innerHTML = this.getElementInnerHTML();
|
||||
|
||||
const parent = this.switchButton.parentNode;
|
||||
parent.removeChild(this.switchButton);
|
||||
wrapperDiv.appendChild(this.switchButton);
|
||||
parent.insertBefore(wrapperDiv, parent.lastChild.previousElementSibling);
|
||||
|
||||
this.getPickerElement().onchange = this.pickerChanged(controller);
|
||||
this.switchButton.onclick = this.switchButtonOnclick(controller);
|
||||
}
|
||||
|
||||
getOptions(defaultOptions) {
|
||||
return [...new Set([...defaultOptions, ...getOptions()])];
|
||||
}
|
||||
|
||||
pickerChanged(controller) {
|
||||
const originalBGC = this.switchButton.style.backgroundColor;
|
||||
this.getSelectElement().onchange = () => {
|
||||
const picked = this.getCurrentOption();
|
||||
return () => {
|
||||
const picked = this.getCurrentOption();
|
||||
if (_IMAGE === picked) {
|
||||
this.switchButton.disabled = true;
|
||||
this.switchButton.style.backgroundColor = 'black';
|
||||
|
|
@ -118,8 +117,10 @@ class SelectController {
|
|||
|
||||
controller.setAspectRatio(picked);
|
||||
};
|
||||
}
|
||||
|
||||
this.switchButton.onclick = () => {
|
||||
switchButtonOnclick(controller) {
|
||||
return () => {
|
||||
reverseAllOptions();
|
||||
const picked = this.getCurrentOption();
|
||||
if (_LOCK === picked) {
|
||||
|
|
@ -130,17 +131,88 @@ class SelectController {
|
|||
};
|
||||
}
|
||||
|
||||
getSelectElement() {
|
||||
getElementInnerHTML() {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
getPickerElement() {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
getCurrentOption() {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SelectOptionPickingController extends OptionPickingController {
|
||||
constructor(page, defaultOptions, controller) {
|
||||
super(page, defaultOptions, controller);
|
||||
}
|
||||
|
||||
getElementInnerHTML() {
|
||||
return `
|
||||
<div id="${this.page}_ratio" class="gr-block gr-box relative w-full border-solid border border-gray-200 gr-padded">
|
||||
<select id="${this.page}_select_aspect_ratio" class="gr-box gr-input w-full disabled:cursor-not-allowed">
|
||||
${this.options.map(r => {
|
||||
return '<option class="ar-option">' + r + '</option>'
|
||||
}).join('\n')}
|
||||
</select>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
getPickerElement() {
|
||||
return gradioApp().getElementById(`${this.page}_select_aspect_ratio`);
|
||||
}
|
||||
|
||||
getCurrentOption() {
|
||||
const selectElement = this.getSelectElement();
|
||||
const selectElement = this.getPickerElement();
|
||||
const options = Array.from(selectElement);
|
||||
return options[selectElement.selectedIndex].value;
|
||||
}
|
||||
}
|
||||
|
||||
class DefaultOptionsButtonOptionPickingController extends OptionPickingController {
|
||||
constructor(page, defaultOptions, controller) {
|
||||
super(page, defaultOptions, controller);
|
||||
this.currentIndex = 0;
|
||||
this.getPickerElement().onclick = this.pickerChanged(controller);
|
||||
}
|
||||
|
||||
pickerChanged(controller) {
|
||||
return () => {
|
||||
this.currentIndex = (this.currentIndex + 1) % this.options.length;
|
||||
this.getPickerElement().querySelector('button').textContent = this.getCurrentOption();
|
||||
super.pickerChanged(controller)();
|
||||
}
|
||||
}
|
||||
|
||||
getElementInnerHTML() {
|
||||
const classes = Array.from(this.switchButton.classList);
|
||||
return `
|
||||
<div id="${this.page}_ar_default_options_button" style="margin-bottom: 10px;">
|
||||
<button class="${classes.join(' ')}">
|
||||
${this.getCurrentOption()}
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
getPickerElement() {
|
||||
return gradioApp().getElementById(`${this.page}_ar_default_options_button`);
|
||||
}
|
||||
|
||||
getOptions(defaultOptions) {
|
||||
return defaultOptions;
|
||||
}
|
||||
|
||||
getCurrentOption() {
|
||||
return this.options[this.currentIndex || 0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SliderController {
|
||||
constructor(element) {
|
||||
this.element = element
|
||||
|
|
@ -201,7 +273,12 @@ class AspectRatioController {
|
|||
});
|
||||
})
|
||||
|
||||
this.selectController = new SelectController(page, defaultOptions, this);
|
||||
if (window.opts.arh_ui_javascript_selection_method === 'Default Options Button') {
|
||||
this.optionPickingControler = new DefaultOptionsButtonOptionPickingController(page, defaultOptions, this);
|
||||
} else {
|
||||
this.optionPickingControler = new SelectOptionPickingController(page, defaultOptions, this);
|
||||
}
|
||||
|
||||
this.setAspectRatio(_OFF);
|
||||
}
|
||||
|
||||
|
|
@ -278,11 +355,17 @@ class AspectRatioController {
|
|||
|
||||
const [width, height] = clampToBoundaries(w, h)
|
||||
|
||||
const inputEvent = new Event("input", { bubbles: true});
|
||||
const inputEvent = new Event("input", {bubbles: true});
|
||||
this.widthContainer.setVal(width);
|
||||
this.widthContainer.triggerEvent(inputEvent);
|
||||
this.heightContainer.setVal(height);
|
||||
this.heightContainer.triggerEvent(inputEvent);
|
||||
this.heightContainer.inputs.forEach(input => {
|
||||
dimensionChange({target: input}, false, true);
|
||||
});
|
||||
this.widthContainer.inputs.forEach(input => {
|
||||
dimensionChange({target: input}, true, false);
|
||||
});
|
||||
}
|
||||
|
||||
static observeStartup(key, page, defaultOptions, postSetup = (_) => {}) {
|
||||
|
|
@ -291,7 +374,7 @@ class AspectRatioController {
|
|||
const heightContainer = gradioApp().querySelector(`#${page}_height`);
|
||||
|
||||
// wait for width and height containers to exist.
|
||||
if (widthContainer && heightContainer) {
|
||||
if (widthContainer && heightContainer) {
|
||||
observer.disconnect();
|
||||
if (!window.opts.arh_javascript_aspect_ratio_show) {
|
||||
return;
|
||||
|
|
@ -319,7 +402,7 @@ const addImg2ImgTabSwitchClickListeners = (controller) => {
|
|||
img2imgTabButtons.forEach(button => {
|
||||
button.addEventListener('click', (_) => {
|
||||
// set aspect ratio is RECALLED to change to the image specific to the newly selected tab.
|
||||
if (controller.selectController.getCurrentOption() === _IMAGE) {
|
||||
if (controller.optionPickingControler.getCurrentOption() === _IMAGE) {
|
||||
controller.setAspectRatio(_IMAGE);
|
||||
}
|
||||
|
||||
|
|
@ -332,7 +415,7 @@ const addImg2ImgTabSwitchClickListeners = (controller) => {
|
|||
|
||||
const postImageControllerSetupFunction = (controller) => {
|
||||
const scaleToImg2ImgImage = (e) => {
|
||||
const picked = controller.selectController.getCurrentOption();
|
||||
const picked = controller.optionPickingControler.getCurrentOption();
|
||||
if (picked !== _IMAGE) return;
|
||||
const files = e.dataTransfer ? e.dataTransfer.files : e.target.files;
|
||||
const img = new Image();
|
||||
|
|
@ -361,7 +444,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||
AspectRatioController.observeStartup(
|
||||
"__img2imgAspectRatioController",
|
||||
"img2img",
|
||||
[_OFF, _IMAGE, _LOCK],
|
||||
[_OFF, _LOCK, _IMAGE],
|
||||
postImageControllerSetupFunction
|
||||
);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue