From 972aecc4c5bda024f2b6bb2d0c1231135fb87bc3 Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Tue, 21 Feb 2023 21:33:44 -0500 Subject: [PATCH] fix responsive resizing --- ldm/invoke/config/invokeai_configure.py | 16 ++++--- ldm/invoke/config/model_install.py | 59 ++++++++++++++++++------- ldm/invoke/config/widgets.py | 32 ++++++++++++++ 3 files changed, 85 insertions(+), 22 deletions(-) diff --git a/ldm/invoke/config/invokeai_configure.py b/ldm/invoke/config/invokeai_configure.py index 168ebf849b..6810cbffee 100755 --- a/ldm/invoke/config/invokeai_configure.py +++ b/ldm/invoke/config/invokeai_configure.py @@ -39,7 +39,6 @@ import invokeai.configs as configs from ..args import PRECISION_CHOICES, Args from ..globals import Globals, global_config_dir, global_config_file, global_cache_dir -from ..readline import generic_completer from .model_install import addModelsForm, process_and_execute from .model_install_backend import ( default_dataset, @@ -47,7 +46,7 @@ from .model_install_backend import ( recommended_datasets, hf_download_with_resume, ) -from .widgets import IntTitleSlider +from .widgets import IntTitleSlider, CenteredButtonPress warnings.filterwarnings("ignore") @@ -64,7 +63,6 @@ Default_config_file = Path(global_config_dir()) / "models.yaml" SD_Configs = Path(global_config_dir()) / "stable-diffusion" Datasets = OmegaConf.load(Dataset_path) -completer = generic_completer(["yes", "no"]) INIT_FILE_PREAMBLE = """# InvokeAI initialization file # This is the InvokeAI initialization file, which contains command-line default values. @@ -79,7 +77,6 @@ INIT_FILE_PREAMBLE = """# InvokeAI initialization file # -Ak_euler_a -C10.0 """ - # -------------------------------------------- def postscript(errors: None): if not any(errors): @@ -325,7 +322,10 @@ def get_root(root: str = None) -> str: return Globals.root +# ------------------------------------- class editOptsForm(npyscreen.FormMultiPage): + FIX_MINIMUM_SIZE_WHEN_CREATED = False + def create(self): program_opts = self.parentApp.program_opts old_opts = self.parentApp.invokeai_opts @@ -401,7 +401,7 @@ class editOptsForm(npyscreen.FormMultiPage): self.hf_token = self.add_widget_intelligent( npyscreen.TitlePassword, - name="Access Token (use shift-ctrl-V to paste):", + name="Access Token (ctrl-shift-V pastes):", value=access_token, begin_entry_at=42, use_two_lines=False, @@ -528,7 +528,7 @@ class editOptsForm(npyscreen.FormMultiPage): else "NEXT" ) self.ok_button = self.add_widget_intelligent( - npyscreen.ButtonPress, + CenteredButtonPress, name=label, relx=(window_width - len(label)) // 2, rely=-3, @@ -570,6 +570,10 @@ class editOptsForm(npyscreen.FormMultiPage): else: return True + def resize(self): + super().resize() + self.ok_button.relx=5 + def marshall_arguments(self): new_opts = Namespace() diff --git a/ldm/invoke/config/model_install.py b/ldm/invoke/config/model_install.py index 5bd7ea55d0..b91d732f8c 100644 --- a/ldm/invoke/config/model_install.py +++ b/ldm/invoke/config/model_install.py @@ -29,10 +29,12 @@ from .model_install_backend import (Dataset_path, default_config_file, default_dataset, get_root, install_requested_models, recommended_datasets) -from .widgets import MultiSelectColumns, TextBox - +from .widgets import (MultiSelectColumns, TextBox, + OffsetButtonPress, CenteredTitleText) class addModelsForm(npyscreen.FormMultiPage): + FIX_MINIMUM_SIZE_WHEN_CREATED = False + def __init__(self, parentApp, name, multipage=False, *args, **keywords): self.multipage = multipage self.initial_models = OmegaConf.load(Dataset_path) @@ -62,22 +64,30 @@ class addModelsForm(npyscreen.FormMultiPage): npyscreen.FixedText, value="Use ctrl-N and ctrl-P to move to the ext and

revious fields,", editable=False, + color='CAUTION', ) self.add_widget_intelligent( npyscreen.FixedText, - value="cursor arrows to make a selection, and space to toggle checkboxes.", + value="Use cursor arrows to make a selection, and space to toggle checkboxes.", editable=False, + color='CAUTION' ) self.nextrely += 1 if len(self.installed_models) > 0: self.add_widget_intelligent( - npyscreen.TitleFixedText, + CenteredTitleText, name="== INSTALLED STARTER MODELS ==", - value="Currently installed starter models. Uncheck to delete:", - begin_entry_at=2, editable=False, color="CONTROL", ) + self.nextrely -= 1 + self.add_widget_intelligent( + CenteredTitleText, + name="Currently installed starter models. Uncheck to delete:", + editable=False, + labelColor="CAUTION", + ) + self.nextrely -= 1 columns = self._get_columns() self.previously_installed_models = self.add_widget_intelligent( MultiSelectColumns, @@ -94,16 +104,23 @@ class addModelsForm(npyscreen.FormMultiPage): name="Purge deleted models from disk", value=False, scroll_exit=True, + relx=4, ) self.nextrely += 1 self.add_widget_intelligent( - npyscreen.TitleFixedText, + CenteredTitleText, name="== STARTER MODELS (recommended ones selected) ==", - value="Select from a starter set of Stable Diffusion models from HuggingFace:", - begin_entry_at=2, editable=False, color="CONTROL", ) + self.nextrely -= 1 + self.add_widget_intelligent( + CenteredTitleText, + name="Select from a starter set of Stable Diffusion models from HuggingFace:", + editable=False, + labelColor="CAUTION", + ) + self.nextrely -= 1 # if user has already installed some initial models, then don't patronize them # by showing more recommendations @@ -121,16 +138,24 @@ class addModelsForm(npyscreen.FormMultiPage): relx=4, scroll_exit=True, ) + self.add_widget_intelligent( + CenteredTitleText, + name='== IMPORT LOCAL AND REMOTE MODELS ==', + editable=False, + color="CONTROL", + ) + self.nextrely -= 1 + for line in [ - "== IMPORT LOCAL AND REMOTE MODELS ==", - "Enter URLs, file paths, or HuggingFace diffusers repository IDs separated by spaces.", - "Use control-V or shift-control-V to paste:", + "In the box below, enter URLs, file paths, or HuggingFace repository IDs.", + "Separate model names by lines or whitespace (Use shift-control-V to paste):", ]: self.add_widget_intelligent( - npyscreen.TitleText, + CenteredTitleText, name=line, editable=False, - color="CONTROL", + labelColor="CONTROL", + relx = 4, ) self.nextrely -= 1 self.import_model_paths = self.add_widget_intelligent( @@ -184,15 +209,17 @@ class addModelsForm(npyscreen.FormMultiPage): button_length += len(back_label) + 1 button_offset += len(back_label) + 1 self.back_button = self.add_widget_intelligent( - npyscreen.ButtonPress, + OffsetButtonPress, name=back_label, relx=(window_width - button_length) // 2, + offset=-3, rely=-3, when_pressed_function=self.on_back, ) self.ok_button = self.add_widget_intelligent( - npyscreen.ButtonPress, + OffsetButtonPress, name=done_label, + offset=+3, relx=button_offset + 1 + (window_width - button_length) // 2, rely=-3, when_pressed_function=self.on_ok, diff --git a/ldm/invoke/config/widgets.py b/ldm/invoke/config/widgets.py index b48ea875df..1fbb5fbce0 100644 --- a/ldm/invoke/config/widgets.py +++ b/ldm/invoke/config/widgets.py @@ -12,6 +12,38 @@ class IntSlider(npyscreen.Slider): stri = stri.rjust(l) return stri +# ------------------------------------- +class CenteredTitleText(npyscreen.TitleText): + def __init__(self,*args,**keywords): + super().__init__(*args,**keywords) + self.resize() + + def resize(self): + super().resize() + maxy, maxx = self.parent.curses_pad.getmaxyx() + label = self.name + self.relx = (maxx - len(label)) // 2 + begin_entry_at = -self.relx + 2 + +# ------------------------------------- +class CenteredButtonPress(npyscreen.ButtonPress): + def resize(self): + super().resize() + maxy, maxx = self.parent.curses_pad.getmaxyx() + label = self.name + self.relx = (maxx - len(label)) // 2 + +# ------------------------------------- +class OffsetButtonPress(npyscreen.ButtonPress): + def __init__(self, screen, offset=0, *args, **keywords): + super().__init__(screen, *args, **keywords) + self.offset = offset + + def resize(self): + maxy, maxx = self.parent.curses_pad.getmaxyx() + width = len(self.name) + self.relx = self.offset + (maxx - width) // 2 + class IntTitleSlider(npyscreen.TitleText): _entry_type = IntSlider