Skip to content

Commit

Permalink
added compact prompt option
Browse files Browse the repository at this point in the history
  • Loading branch information
AUTOMATIC1111 committed Nov 5, 2023
1 parent d9499f4 commit 4d4a9e7
Show file tree
Hide file tree
Showing 10 changed files with 314 additions and 168 deletions.
2 changes: 2 additions & 0 deletions extensions-builtin/mobile/javascript/mobile.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ function isMobile() {
}

function reportWindowSize() {
if (gradioApp().querySelector('.toprow-compact-tools')) return; // not applicable for compact prompt layout

var currentlyMobile = isMobile();
if (currentlyMobile == isSetupForMobile) return;
isSetupForMobile = currentlyMobile;
Expand Down
33 changes: 33 additions & 0 deletions javascript/extraNetworks.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ function setupExtraNetworksForTab(tabname) {
var refresh = gradioApp().getElementById(tabname + '_extra_refresh');
var showDirsDiv = gradioApp().getElementById(tabname + '_extra_show_dirs');
var showDirs = gradioApp().querySelector('#' + tabname + '_extra_show_dirs input');
var promptContainer = gradioApp().querySelector('.prompt-container-compact#' + tabname + '_prompt_container');
var negativePrompt = gradioApp().querySelector('#' + tabname + '_neg_prompt');

tabs.appendChild(searchDiv);
tabs.appendChild(sort);
Expand Down Expand Up @@ -109,6 +111,37 @@ function setupExtraNetworksForTab(tabname) {
showDirsUpdate();
}

function extraNetworksMovePromptToTab(tabname, id, showPrompt, showNegativePrompt) {
if (!gradioApp().querySelector('.toprow-compact-tools')) return; // only applicable for compact prompt layout

var promptContainer = gradioApp().getElementById(tabname + '_prompt_container');
var prompt = gradioApp().getElementById(tabname + '_prompt_row');
var negPrompt = gradioApp().getElementById(tabname + '_neg_prompt_row');
var elem = id ? gradioApp().getElementById(id) : null;

if (showNegativePrompt && elem) {
elem.insertBefore(negPrompt, elem.firstChild);
} else {
promptContainer.insertBefore(negPrompt, promptContainer.firstChild);
}

if (showPrompt && elem) {
elem.insertBefore(prompt, elem.firstChild);
} else {
promptContainer.insertBefore(prompt, promptContainer.firstChild);
}
}


function extraNetworksUrelatedTabSelected(tabname) { // called from python when user selects an unrelated tab (generate)
extraNetworksMovePromptToTab(tabname, '', false, false);
}

function extraNetworksTabSelected(tabname, id, showPrompt, showNegativePrompt) { // called from python when user selects an extra networks tab
extraNetworksMovePromptToTab(tabname, id, showPrompt, showNegativePrompt);

}

function applyExtraNetworkFilter(tabname) {
setTimeout(extraNetworksApplyFilter[tabname], 1);
}
Expand Down
2 changes: 2 additions & 0 deletions modules/shared_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ def reload_hypernetworks():


ui_reorder_categories_builtin_items = [
"prompt",
"image",
"inpaint",
"sampler",
"accordions",
Expand Down
1 change: 1 addition & 0 deletions modules/shared_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@
"hires_fix_show_sampler": OptionInfo(False, "Hires fix: show hires checkpoint and sampler selection").needs_reload_ui(),
"hires_fix_show_prompts": OptionInfo(False, "Hires fix: show hires prompt and negative prompt").needs_reload_ui(),
"disable_token_counters": OptionInfo(False, "Disable prompt token counters").needs_reload_ui(),
"compact_prompt_box": OptionInfo(True, "Compact prompt layout").info("puts prompt and negative prompt inside the Generate tab, leaving more vertical space for the image on the right").needs_reload_ui(),
}))


Expand Down
247 changes: 90 additions & 157 deletions modules/ui.py

Large diffs are not rendered by default.

15 changes: 9 additions & 6 deletions modules/ui_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def __init__(self, d=None):
return gr.File.update(value=fullfns, visible=True), plaintext_to_html(f"Saved: {filenames[0]}")


def create_output_panel(tabname, outdir):
def create_output_panel(tabname, outdir, toprow=None):

def open_folder(f):
if not os.path.exists(f):
Expand All @@ -130,12 +130,15 @@ def open_folder(f):
else:
sp.Popen(["xdg-open", path])

with gr.Column(variant='panel', elem_id=f"{tabname}_results"):
with gr.Group(elem_id=f"{tabname}_gallery_container"):
result_gallery = gr.Gallery(label='Output', show_label=False, elem_id=f"{tabname}_gallery", columns=4, preview=True, height=shared.opts.gallery_height or None)
with gr.Column(elem_id=f"{tabname}_results"):
if toprow:
toprow.create_inline_toprow_image()

generation_info = None
with gr.Column():
with gr.Column(variant='panel', elem_id=f"{tabname}_results_panel"):
with gr.Group(elem_id=f"{tabname}_gallery_container"):
result_gallery = gr.Gallery(label='Output', show_label=False, elem_id=f"{tabname}_gallery", columns=4, preview=True, height=shared.opts.gallery_height or None)

generation_info = None
with gr.Row(elem_id=f"image_buttons_{tabname}", elem_classes="image-buttons"):
open_folder_button = ToolButton(folder_symbol, elem_id=f'{tabname}_open_folder', visible=not shared.cmd_opts.hide_ui_dir_config, tooltip="Open images output directory.")

Expand Down
16 changes: 12 additions & 4 deletions modules/ui_extra_networks.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ def __init__(self, title):
self.name = title.lower()
self.id_page = self.name.replace(" ", "_")
self.card_page = shared.html("extra-networks-card.html")
self.allow_prompt = True
self.allow_negative_prompt = False
self.metadata = {}
self.items = {}
Expand Down Expand Up @@ -367,7 +368,7 @@ def create_ui(interface: gr.Blocks, unrelated_tabs, tabname):
related_tabs = []

for page in ui.stored_extra_pages:
with gr.Tab(page.title, id=page.id_page) as tab:
with gr.Tab(page.title, elem_id=f"{tabname}_{page.id_page}", elem_classes=["extra-page"]) as tab:
elem_id = f"{tabname}_{page.id_page}_cards_html"
page_elem = gr.HTML('Loading...', elem_id=elem_id)
ui.pages.append(page_elem)
Expand All @@ -389,11 +390,18 @@ def create_ui(interface: gr.Blocks, unrelated_tabs, tabname):
ui.button_save_preview = gr.Button('Save preview', elem_id=tabname+"_save_preview", visible=False)
ui.preview_target_filename = gr.Textbox('Preview save filename', elem_id=tabname+"_preview_filename", visible=False)

tab_controls = [edit_search, dropdown_sort, button_sortorder, button_refresh, checkbox_show_dirs]

for tab in unrelated_tabs:
tab.select(fn=lambda: [gr.update(visible=False) for _ in range(5)], inputs=[], outputs=[edit_search, dropdown_sort, button_sortorder, button_refresh, checkbox_show_dirs], show_progress=False)
tab.select(fn=lambda: [gr.update(visible=False) for _ in tab_controls], _js='function(){ extraNetworksUrelatedTabSelected("' + tabname + '"); }', inputs=[], outputs=tab_controls, show_progress=False)

for page, tab in zip(ui.stored_extra_pages, related_tabs):
allow_prompt = "true" if page.allow_prompt else "false"
allow_negative_prompt = "true" if page.allow_negative_prompt else "false"

jscode = 'extraNetworksTabSelected("' + tabname + '", "' + f"{tabname}_{page.id_page}" + '", ' + allow_prompt + ', ' + allow_negative_prompt + ');'

for tab in related_tabs:
tab.select(fn=lambda: [gr.update(visible=True) for _ in range(5)], inputs=[], outputs=[edit_search, dropdown_sort, button_sortorder, button_refresh, checkbox_show_dirs], show_progress=False)
tab.select(fn=lambda: [gr.update(visible=True) for _ in tab_controls], _js='function(){ ' + jscode + ' }', inputs=[], outputs=tab_controls, show_progress=False)

dropdown_sort.change(fn=lambda: None, _js="function(){ applyExtraNetworkSort('" + tabname + "'); }")

Expand Down
2 changes: 2 additions & 0 deletions modules/ui_extra_networks_checkpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ class ExtraNetworksPageCheckpoints(ui_extra_networks.ExtraNetworksPage):
def __init__(self):
super().__init__('Checkpoints')

self.allow_prompt = False

def refresh(self):
shared.refresh_checkpoints()

Expand Down
141 changes: 141 additions & 0 deletions modules/ui_toprow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import gradio as gr

from modules import shared, ui_prompt_styles
import modules.images

from modules.ui_components import ToolButton


class Toprow:
"""Creates a top row UI with prompts, generate button, styles, extra little buttons for things, and enables some functionality related to their operation"""

prompt = None
prompt_img = None
negative_prompt = None

button_interrogate = None
button_deepbooru = None

interrupt = None
skip = None
submit = None

paste = None
clear_prompt_button = None
apply_styles = None
restore_progress_button = None

token_counter = None
token_button = None
negative_token_counter = None
negative_token_button = None

ui_styles = None

submit_box = None

def __init__(self, is_img2img, is_compact=False):
id_part = "img2img" if is_img2img else "txt2img"
self.id_part = id_part
self.is_img2img = is_img2img
self.is_compact = is_compact

if not is_compact:
with gr.Row(elem_id=f"{id_part}_toprow", variant="compact"):
self.create_classic_toprow()
else:
self.create_submit_box()

def create_classic_toprow(self):
self.create_prompts()

with gr.Column(scale=1, elem_id=f"{self.id_part}_actions_column"):
self.create_submit_box()

self.create_tools_row()

self.create_styles_ui()

def create_inline_toprow_prompts(self):
if not self.is_compact:
return

self.create_prompts()

with gr.Row(elem_classes=["toprow-compact-stylerow"]):
with gr.Column(elem_classes=["toprow-compact-tools"]):
self.create_tools_row()
with gr.Column():
self.create_styles_ui()

def create_inline_toprow_image(self):
if not self.is_compact:
return

self.submit_box.render()

def create_prompts(self):
with gr.Column(elem_id=f"{self.id_part}_prompt_container", elem_classes=["prompt-container-compact"] if self.is_compact else [], scale=6):
with gr.Row(elem_id=f"{self.id_part}_prompt_row", elem_classes=["prompt-row"]):
self.prompt = gr.Textbox(label="Prompt", elem_id=f"{self.id_part}_prompt", show_label=False, lines=3, placeholder="Prompt (press Ctrl+Enter or Alt+Enter to generate)", elem_classes=["prompt"])
self.prompt_img = gr.File(label="", elem_id=f"{self.id_part}_prompt_image", file_count="single", type="binary", visible=False)

with gr.Row(elem_id=f"{self.id_part}_neg_prompt_row", elem_classes=["prompt-row"]):
self.negative_prompt = gr.Textbox(label="Negative prompt", elem_id=f"{self.id_part}_neg_prompt", show_label=False, lines=3, placeholder="Negative prompt (press Ctrl+Enter or Alt+Enter to generate)", elem_classes=["prompt"])

self.prompt_img.change(
fn=modules.images.image_data,
inputs=[self.prompt_img],
outputs=[self.prompt, self.prompt_img],
show_progress=False,
)

def create_submit_box(self):
with gr.Row(elem_id=f"{self.id_part}_generate_box", elem_classes=["generate-box"] + (["generate-box-compact"] if self.is_compact else []), render=not self.is_compact) as submit_box:
self.submit_box = submit_box

self.interrupt = gr.Button('Interrupt', elem_id=f"{self.id_part}_interrupt", elem_classes="generate-box-interrupt")
self.skip = gr.Button('Skip', elem_id=f"{self.id_part}_skip", elem_classes="generate-box-skip")
self.submit = gr.Button('Generate', elem_id=f"{self.id_part}_generate", variant='primary')

self.skip.click(
fn=lambda: shared.state.skip(),
inputs=[],
outputs=[],
)

self.interrupt.click(
fn=lambda: shared.state.interrupt(),
inputs=[],
outputs=[],
)

def create_tools_row(self):
with gr.Row(elem_id=f"{self.id_part}_tools"):
from modules.ui import paste_symbol, clear_prompt_symbol, restore_progress_symbol

self.paste = ToolButton(value=paste_symbol, elem_id="paste", tooltip="Read generation parameters from prompt or last generation if prompt is empty into user interface.")
self.clear_prompt_button = ToolButton(value=clear_prompt_symbol, elem_id=f"{self.id_part}_clear_prompt", tooltip="Clear prompt")
self.apply_styles = ToolButton(value=ui_prompt_styles.styles_materialize_symbol, elem_id=f"{self.id_part}_style_apply", tooltip="Apply all selected styles to prompts.")

if self.is_img2img:
self.button_interrogate = ToolButton('📎', tooltip='Interrogate CLIP - use CLIP neural network to create a text describing the image, and put it into the prompt field', elem_id="interrogate")
self.button_deepbooru = ToolButton('📦', tooltip='Interrogate DeepBooru - use DeepBooru neural network to create a text describing the image, and put it into the prompt field', elem_id="deepbooru")

self.restore_progress_button = ToolButton(value=restore_progress_symbol, elem_id=f"{self.id_part}_restore_progress", visible=False, tooltip="Restore progress")

self.token_counter = gr.HTML(value="<span>0/75</span>", elem_id=f"{self.id_part}_token_counter", elem_classes=["token-counter"])
self.token_button = gr.Button(visible=False, elem_id=f"{self.id_part}_token_button")
self.negative_token_counter = gr.HTML(value="<span>0/75</span>", elem_id=f"{self.id_part}_negative_token_counter", elem_classes=["token-counter"])
self.negative_token_button = gr.Button(visible=False, elem_id=f"{self.id_part}_negative_token_button")

self.clear_prompt_button.click(
fn=lambda *x: x,
_js="confirm_clear_prompt",
inputs=[self.prompt, self.negative_prompt],
outputs=[self.prompt, self.negative_prompt],
)

def create_styles_ui(self):
self.ui_styles = ui_prompt_styles.UiPromptStyles(self.id_part, self.prompt, self.negative_prompt)
self.ui_styles.setup_apply_button(self.apply_styles)
23 changes: 22 additions & 1 deletion style.css
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,13 @@ input[type="checkbox"].input-accordion-checkbox{
min-height: 4.5em;
}

#txt2img_generate, #img2img_generate {
min-height: 4.5em;
}
.generate-box-compact #txt2img_generate, .generate-box-compact #img2img_generate {
min-height: 3em;
}

@media screen and (min-width: 2500px) {
#txt2img_gallery, #img2img_gallery {
min-height: 768px;
Expand Down Expand Up @@ -403,6 +410,15 @@ div#extras_scale_to_tab div.form{
min-width: 0.5em;
}

div.toprow-compact-stylerow{
margin: 0.5em 0;
}

div.toprow-compact-tools{
min-width: fit-content !important;
max-width: fit-content;
}

/* settings */
#quicksettings {
align-items: end;
Expand Down Expand Up @@ -525,7 +541,8 @@ table.popup-table .link{
height: 20px;
background: #b4c0cc;
border-radius: 3px !important;
top: -20px;
top: -14px;
left: 0px;
width: 100%;
}

Expand Down Expand Up @@ -823,6 +840,10 @@ footer {

/* extra networks UI */

.extra-page .prompt{
margin: 0 0 0.5em 0;
}

.extra-network-cards{
height: calc(100vh - 24rem);
overflow: clip scroll;
Expand Down

0 comments on commit 4d4a9e7

Please sign in to comment.