mirror of
https://github.com/Sygil-Dev/sygil-webui.git
synced 2024-12-15 22:42:14 +03:00
updated webui_flet.py and added configs (#1677)
# Description added webui_flet_utils.py and webui_flet.yaml moved webui_flet_* to 'scripts/' and put .yaml in 'configs/webui/' added 'userconfig_flet.yaml' to .gitignore very much WIP. # Checklist: - [x] I have changed the base branch to `dev` - [x] I have performed a self-review of my own code - [x] I have commented my code in hard-to-understand areas - [ ] I have made corresponding changes to the documentation
This commit is contained in:
commit
43da4ec796
1
.gitignore
vendored
1
.gitignore
vendored
@ -54,6 +54,7 @@ condaenv.*.requirements.txt
|
|||||||
# Repo-specific
|
# Repo-specific
|
||||||
# =========================================================================== #
|
# =========================================================================== #
|
||||||
/configs/webui/userconfig_streamlit.yaml
|
/configs/webui/userconfig_streamlit.yaml
|
||||||
|
/configs/webui/userconfig_flet.yaml
|
||||||
/custom-conda-path.txt
|
/custom-conda-path.txt
|
||||||
!/src/components/*
|
!/src/components/*
|
||||||
!/src/pages/*
|
!/src/pages/*
|
||||||
|
87
configs/webui/webui_flet.yaml
Normal file
87
configs/webui/webui_flet.yaml
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
# This file is part of sygil-webui (https://github.com/Sygil-Dev/sygil-webui/).
|
||||||
|
|
||||||
|
# Copyright 2022 Sygil-Dev team.
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# UI defaults configuration file. It is automatically loaded if located at configs/webui/webui_flet.yaml.
|
||||||
|
# Any changes made here will be available automatically on the web app without having to stop it.
|
||||||
|
# You may add overrides in a file named "userconfig_flet.yaml" in this folder, which can contain any subset
|
||||||
|
# of the properties below.
|
||||||
|
|
||||||
|
webui:
|
||||||
|
default_border: 1
|
||||||
|
default_border_radius: 0
|
||||||
|
default_container_height: 200
|
||||||
|
default_container_width: 200
|
||||||
|
default_margin: 0
|
||||||
|
default_opacity: 1
|
||||||
|
default_padding: 0
|
||||||
|
default_scale: 1
|
||||||
|
default_text_size: 20
|
||||||
|
|
||||||
|
general:
|
||||||
|
default_theme: dark
|
||||||
|
huggingface_token: ''
|
||||||
|
stable_horde_api: '0000000000'
|
||||||
|
gpu: 0
|
||||||
|
outdir: outputs
|
||||||
|
default_model: "Stable Diffusion v1.5"
|
||||||
|
base_model: "Stable Diffusion v1.5"
|
||||||
|
default_model_config: "configs/stable-diffusion/v1-inference.yaml"
|
||||||
|
default_model_path: "models/ldm/stable-diffusion-v1/Stable Diffusion v1.5.ckpt"
|
||||||
|
use_sd_concepts_library: True
|
||||||
|
sd_concepts_library_folder: "models/custom/sd-concepts-library"
|
||||||
|
GFPGAN_dir: "./models/gfpgan"
|
||||||
|
GFPGAN_model: "GFPGANv1.4"
|
||||||
|
LDSR_dir: "./models/ldsr"
|
||||||
|
LDSR_model: "model"
|
||||||
|
RealESRGAN_dir: "./models/realesrgan"
|
||||||
|
RealESRGAN_model: "RealESRGAN_x4plus"
|
||||||
|
upscaling_method: "RealESRGAN"
|
||||||
|
outdir_txt2img: outputs/txt2img
|
||||||
|
outdir_img2img: outputs/img2img
|
||||||
|
outdir_img2txt: outputs/img2txt
|
||||||
|
gfpgan_cpu: False
|
||||||
|
esrgan_cpu: False
|
||||||
|
extra_models_cpu: False
|
||||||
|
extra_models_gpu: False
|
||||||
|
gfpgan_gpu: 0
|
||||||
|
esrgan_gpu: 0
|
||||||
|
keep_all_models_loaded: False
|
||||||
|
save_metadata: True
|
||||||
|
save_format: "png"
|
||||||
|
skip_grid: False
|
||||||
|
skip_save: False
|
||||||
|
grid_quality: 95
|
||||||
|
n_rows: -1
|
||||||
|
no_verify_input: False
|
||||||
|
no_half: False
|
||||||
|
use_float16: False
|
||||||
|
precision: "autocast"
|
||||||
|
optimized: False
|
||||||
|
optimized_turbo: False
|
||||||
|
optimized_config: "optimizedSD/v1-inference.yaml"
|
||||||
|
enable_attention_slicing: False
|
||||||
|
enable_minimal_memory_usage: False
|
||||||
|
update_preview: True
|
||||||
|
update_preview_frequency: 10
|
||||||
|
|
||||||
|
admin:
|
||||||
|
hide_server_setting: False
|
||||||
|
hide_browser_setting: False
|
||||||
|
global_negative_prompt: ""
|
||||||
|
|
||||||
|
textual_inversion:
|
||||||
|
pretrained_model_name_or_path: "models/diffusers/stable-diffusion-v1-5"
|
||||||
|
tokenizer_name: "models/clip-vit-large-patch14"
|
864
scripts/webui_flet.py
Normal file
864
scripts/webui_flet.py
Normal file
@ -0,0 +1,864 @@
|
|||||||
|
# Flet imports
|
||||||
|
import flet as ft
|
||||||
|
from flet.ref import Ref
|
||||||
|
|
||||||
|
# other imports
|
||||||
|
from math import pi
|
||||||
|
from typing import Optional
|
||||||
|
from loguru import logger
|
||||||
|
# utils imports
|
||||||
|
import webui_flet_utils
|
||||||
|
|
||||||
|
# for debugging
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
|
@logger.catch(reraise=True)
|
||||||
|
def main(page: ft.Page):
|
||||||
|
## main function defines
|
||||||
|
|
||||||
|
def load_settings():
|
||||||
|
settings = webui_flet_utils.get_user_settings_from_config()
|
||||||
|
page.session.set('settings',settings)
|
||||||
|
page.update()
|
||||||
|
|
||||||
|
def save_settings_to_config():
|
||||||
|
settings = page.session.get('settings')
|
||||||
|
webui_flet_utils.save_user_settings_to_config(settings)
|
||||||
|
|
||||||
|
def reset_settings_from_config():
|
||||||
|
settings = webui_flet_utils.get_default_settings_from_config()
|
||||||
|
page.session.remove('settings')
|
||||||
|
page.session.set('settings',settings)
|
||||||
|
save_settings_to_config()
|
||||||
|
|
||||||
|
|
||||||
|
def change_theme(e):
|
||||||
|
page.theme_mode = "dark" if page.theme_mode == "light" else "light"
|
||||||
|
|
||||||
|
if "(Light theme)" in theme_switcher.tooltip:
|
||||||
|
theme_switcher.tooltip = theme_switcher.tooltip.replace("(Light theme)", '')
|
||||||
|
|
||||||
|
if "(Dark theme)" in theme_switcher.tooltip:
|
||||||
|
theme_switcher.tooltip = theme_switcher.tooltip.replace("(Dark theme)", '')
|
||||||
|
|
||||||
|
theme_switcher.tooltip += "(Light theme)" if page.theme_mode == "light" else "(Dark theme)"
|
||||||
|
page.update()
|
||||||
|
|
||||||
|
|
||||||
|
###### init ############################################################
|
||||||
|
if not page.session.contains_key('settings'):
|
||||||
|
load_settings()
|
||||||
|
|
||||||
|
###### layouts #########################################################
|
||||||
|
def change_layout(e):
|
||||||
|
current_layout.value = e.control.data
|
||||||
|
set_current_layout_options(e.control.data)
|
||||||
|
set_current_layout_tools(e.control.data)
|
||||||
|
set_property_panel_options(e.control.data)
|
||||||
|
page.update()
|
||||||
|
|
||||||
|
def set_current_layout_options(layout):
|
||||||
|
for control in current_layout_options.controls:
|
||||||
|
current_layout_options.controls.pop()
|
||||||
|
if layout == 'Default':
|
||||||
|
current_layout_options.controls.append(default_layout_options)
|
||||||
|
elif layout == 'Textual Inversion':
|
||||||
|
current_layout_options.controls.append(textual_inversion_layout_options)
|
||||||
|
elif layout == 'Node Editor':
|
||||||
|
current_layout_options.controls.append(node_editor_layout_options)
|
||||||
|
|
||||||
|
def set_current_layout_tools(layout):
|
||||||
|
for control in current_layout_tools.controls:
|
||||||
|
current_layout_tools.controls.pop()
|
||||||
|
if layout == 'Default':
|
||||||
|
current_layout_tools.controls.append(default_layout_tools)
|
||||||
|
elif layout == 'Textual Inversion':
|
||||||
|
current_layout_tools.controls.append(textual_inversion_layout_tools)
|
||||||
|
elif layout == 'Node Editor':
|
||||||
|
current_layout_tools.controls.append(node_editor_layout_tools)
|
||||||
|
|
||||||
|
def set_property_panel_options(layout):
|
||||||
|
controls = property_panel.content.controls
|
||||||
|
for control in controls:
|
||||||
|
controls.pop()
|
||||||
|
if layout == 'Default':
|
||||||
|
controls.append(default_layout_properties)
|
||||||
|
elif layout == 'Textual Inversion':
|
||||||
|
controls.append(textual_inversion_layout_properties)
|
||||||
|
elif layout == 'Node Editor':
|
||||||
|
controls.append(node_editor_layout_properties)
|
||||||
|
|
||||||
|
|
||||||
|
###### settings window #################################################
|
||||||
|
def close_settings_window(e):
|
||||||
|
settings_window.open = False
|
||||||
|
page.update()
|
||||||
|
|
||||||
|
def open_settings_window(e):
|
||||||
|
page.dialog = settings_window
|
||||||
|
settings_window.open = True
|
||||||
|
page.update()
|
||||||
|
|
||||||
|
def update_settings():
|
||||||
|
ui_settings = get_ui_settings()
|
||||||
|
ui_settings_page.content = ui_settings
|
||||||
|
page.update()
|
||||||
|
|
||||||
|
def save_settings(e):
|
||||||
|
save_settings_to_config()
|
||||||
|
update_settings()
|
||||||
|
|
||||||
|
def reset_settings(e):
|
||||||
|
reset_settings_from_config()
|
||||||
|
update_settings()
|
||||||
|
|
||||||
|
def ui_setting_changed(e):
|
||||||
|
settings = page.session.get('settings')
|
||||||
|
settings['webui'][e.control.label] = e.control.value
|
||||||
|
update_settings()
|
||||||
|
|
||||||
|
def get_ui_settings():
|
||||||
|
settings = page.session.get('settings')
|
||||||
|
ui_settings = [ft.Divider(height=10, color="gray")]
|
||||||
|
for setting in settings['webui']:
|
||||||
|
value = ft.TextField(
|
||||||
|
label = setting,
|
||||||
|
value = settings['webui'][setting],
|
||||||
|
on_change = ui_setting_changed,
|
||||||
|
)
|
||||||
|
new_row = ft.Row(
|
||||||
|
controls = [
|
||||||
|
value,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
ui_settings.append(new_row)
|
||||||
|
return ui_settings
|
||||||
|
|
||||||
|
general_settings_page = ft.Column(
|
||||||
|
alignment = 'start',
|
||||||
|
scroll = 'auto',
|
||||||
|
controls = [
|
||||||
|
ft.Divider(height=10, color="gray"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
performance_settings_page = ft.Column(
|
||||||
|
alignment = 'start',
|
||||||
|
scroll = 'auto',
|
||||||
|
controls = [
|
||||||
|
ft.Divider(height=10, color="gray"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
server_settings_page = ft.Column(
|
||||||
|
alignment = 'start',
|
||||||
|
scroll = True,
|
||||||
|
controls = [
|
||||||
|
ft.Divider(height=10, color="gray"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
ui_settings = get_ui_settings()
|
||||||
|
ui_settings_page = ft.Column(
|
||||||
|
alignment = 'start',
|
||||||
|
scroll = True,
|
||||||
|
controls = ui_settings,
|
||||||
|
)
|
||||||
|
|
||||||
|
settings_window = ft.AlertDialog(
|
||||||
|
#modal = True,
|
||||||
|
title = ft.Text("Settings"),
|
||||||
|
content = ft.Container(
|
||||||
|
width = page.width * 0.50,
|
||||||
|
content = ft.Tabs(
|
||||||
|
selected_index = 0,
|
||||||
|
animation_duration = 300,
|
||||||
|
tabs = [
|
||||||
|
ft.Tab(
|
||||||
|
text = "General",
|
||||||
|
content = general_settings_page,
|
||||||
|
),
|
||||||
|
ft.Tab(
|
||||||
|
text = "Performance",
|
||||||
|
content = performance_settings_page,
|
||||||
|
),
|
||||||
|
ft.Tab(
|
||||||
|
text = "Server",
|
||||||
|
content = server_settings_page,
|
||||||
|
),
|
||||||
|
ft.Tab(
|
||||||
|
text = "Interface",
|
||||||
|
content = ui_settings_page,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions = [
|
||||||
|
ft.ElevatedButton(
|
||||||
|
text = "Save",
|
||||||
|
icon = ft.icons.SAVE,
|
||||||
|
on_click = save_settings,
|
||||||
|
),
|
||||||
|
ft.ElevatedButton(
|
||||||
|
text = "Restore Defaults",
|
||||||
|
icon = ft.icons.RESTORE_FROM_TRASH_ROUNDED,
|
||||||
|
on_click = reset_settings,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
actions_alignment="end",
|
||||||
|
#on_dismiss=lambda e: print("Modal dialog dismissed!"),
|
||||||
|
)
|
||||||
|
|
||||||
|
###### gallery window ##################################################
|
||||||
|
def close_gallery_window(e):
|
||||||
|
gallery_window.open = False
|
||||||
|
page.update()
|
||||||
|
|
||||||
|
def open_gallery_window(e):
|
||||||
|
page.dialog = gallery_window
|
||||||
|
gallery_window.open = True
|
||||||
|
page.update()
|
||||||
|
|
||||||
|
gallery_window = ft.AlertDialog(
|
||||||
|
title = ft.Text('Gallery'),
|
||||||
|
content = ft.Row(
|
||||||
|
controls = [
|
||||||
|
ft.Text('Working on it I swear...'),
|
||||||
|
ft.Container(
|
||||||
|
width = page.width * 0.75,
|
||||||
|
height = page.height * 0.75,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions = [
|
||||||
|
ft.ElevatedButton(
|
||||||
|
text = "Save",
|
||||||
|
icon = ft.icons.SAVE,
|
||||||
|
on_click = None,
|
||||||
|
),
|
||||||
|
ft.ElevatedButton(
|
||||||
|
text = "Discard",
|
||||||
|
icon = ft.icons.RESTORE_FROM_TRASH_ROUNDED,
|
||||||
|
on_click = None,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
actions_alignment="end",
|
||||||
|
)
|
||||||
|
|
||||||
|
###### app bar #########################################################
|
||||||
|
app_bar_title = ft.Text(
|
||||||
|
value = "Sygil",
|
||||||
|
size = 20,
|
||||||
|
text_align = 'center',
|
||||||
|
)
|
||||||
|
|
||||||
|
prompt = ft.TextField(
|
||||||
|
value = "",
|
||||||
|
min_lines = 1,
|
||||||
|
max_lines = 1,
|
||||||
|
shift_enter = True,
|
||||||
|
tooltip = "Prompt to use for generation.",
|
||||||
|
autofocus = True,
|
||||||
|
hint_text = "A corgi wearing a top hat as an oil painting.",
|
||||||
|
height = 50,
|
||||||
|
text_size = 20,
|
||||||
|
)
|
||||||
|
|
||||||
|
generate_button = ft.ElevatedButton(
|
||||||
|
text = "Generate",
|
||||||
|
on_click=None,
|
||||||
|
height = 50,
|
||||||
|
)
|
||||||
|
|
||||||
|
layouts = ft.PopupMenuButton(
|
||||||
|
items = [
|
||||||
|
ft.PopupMenuItem(text="Default", on_click=change_layout, data="Default"),
|
||||||
|
ft.PopupMenuItem(text="Textual Inversion", on_click=change_layout, data="Textual Inversion"),
|
||||||
|
ft.PopupMenuItem(text="Node Editor", on_click=change_layout, data="Node Editor"),
|
||||||
|
],
|
||||||
|
tooltip = "Switch between different workspaces",
|
||||||
|
height = 50,
|
||||||
|
)
|
||||||
|
|
||||||
|
current_layout = ft.Text(
|
||||||
|
value = 'Default',
|
||||||
|
size = 20,
|
||||||
|
tooltip = "Current Workspace",
|
||||||
|
)
|
||||||
|
|
||||||
|
layout_menu = ft.Row(
|
||||||
|
alignment = 'start',
|
||||||
|
controls = [
|
||||||
|
ft.Container(content = layouts),
|
||||||
|
ft.Container(content = current_layout),
|
||||||
|
],
|
||||||
|
height = 50,
|
||||||
|
)
|
||||||
|
|
||||||
|
default_layout_options = ft.Row(
|
||||||
|
alignment = 'start',
|
||||||
|
controls = [
|
||||||
|
ft.Container(ft.IconButton(content = ft.Text(value = 'Canvas'), tooltip ='Canvas Options', on_click = None, disabled=True)),
|
||||||
|
ft.Container(ft.IconButton(content = ft.Text(value = 'Layers'), tooltip ='Layer Options', on_click = None, disabled=True)),
|
||||||
|
ft.Container(ft.IconButton(content = ft.Text(value = 'Tools'), tooltip ='Toolbox', on_click = None, disabled=True)),
|
||||||
|
ft.Container(ft.IconButton(content = ft.Text(value = 'Preferences'), tooltip ='Set Editor Preferences', on_click = None, disabled=True)),
|
||||||
|
],
|
||||||
|
height = 50,
|
||||||
|
)
|
||||||
|
|
||||||
|
textual_inversion_layout_options = ft.Row(
|
||||||
|
alignment = 'start',
|
||||||
|
controls = [
|
||||||
|
ft.Container(ft.IconButton(content = ft.Icon(ft.icons.ADD_OUTLINED), tooltip ='textual_inversion options 1', on_click = None, disabled=True)),
|
||||||
|
ft.Container(ft.IconButton(content = ft.Icon(ft.icons.ADD_OUTLINED), tooltip = 'textual_inversion options 2', on_click = None, disabled=True)),
|
||||||
|
ft.Container(ft.IconButton(content = ft.Icon(ft.icons.ADD_OUTLINED), tooltip = 'textual_inversion options 3', on_click = None, disabled=True)),
|
||||||
|
],
|
||||||
|
height = 50,
|
||||||
|
)
|
||||||
|
|
||||||
|
node_editor_layout_options = ft.Row(
|
||||||
|
alignment = 'start',
|
||||||
|
controls = [
|
||||||
|
ft.Container(ft.IconButton(content = ft.Icon(ft.icons.ADD_OUTLINED), tooltip ='node_editor options 1', on_click = None, disabled=True)),
|
||||||
|
ft.Container(ft.IconButton(content = ft.Icon(ft.icons.ADD_OUTLINED), tooltip = 'node_editor options 2', on_click = None, disabled=True)),
|
||||||
|
ft.Container(ft.IconButton(content = ft.Icon(ft.icons.ADD_OUTLINED), tooltip = 'node_editor options 3', on_click = None, disabled=True)),
|
||||||
|
],
|
||||||
|
height = 50,
|
||||||
|
)
|
||||||
|
|
||||||
|
current_layout_options = ft.Row(
|
||||||
|
alignment = 'start',
|
||||||
|
controls = [
|
||||||
|
ft.Container(content = default_layout_options),
|
||||||
|
],
|
||||||
|
height = 50,
|
||||||
|
)
|
||||||
|
|
||||||
|
theme_switcher = ft.IconButton(
|
||||||
|
ft.icons.WB_SUNNY_OUTLINED,
|
||||||
|
on_click = change_theme,
|
||||||
|
expand = 1,
|
||||||
|
tooltip = f"Click to change between the light and dark themes. Current {'(Light theme)' if page.theme_mode == 'light' else '(Dark theme)'}",
|
||||||
|
height = 50,
|
||||||
|
)
|
||||||
|
|
||||||
|
settings_button = ft.IconButton(
|
||||||
|
icon = ft.icons.SETTINGS,
|
||||||
|
on_click = open_settings_window,
|
||||||
|
height = 50,
|
||||||
|
)
|
||||||
|
|
||||||
|
menu_button = ft.PopupMenuButton(
|
||||||
|
items = [
|
||||||
|
#ft.PopupMenuItem(text="Settings", on_click=open_settings_modal),
|
||||||
|
ft.PopupMenuItem(), # divider
|
||||||
|
#ft.PopupMenuItem(text="Checked item", checked=False, on_click=check_item_clicked),
|
||||||
|
],
|
||||||
|
height = 50,
|
||||||
|
)
|
||||||
|
|
||||||
|
option_bar = ft.Row(
|
||||||
|
controls = [
|
||||||
|
# ft.Container(expand=True, content = current_layout_options),
|
||||||
|
ft.Container(expand = 2, content = layout_menu),
|
||||||
|
ft.Container(expand = 1, content = theme_switcher),
|
||||||
|
ft.Container(expand = 1, content = settings_button),
|
||||||
|
ft.Container(expand = 1, content = menu_button),
|
||||||
|
],
|
||||||
|
height = 50,
|
||||||
|
)
|
||||||
|
|
||||||
|
appbar = ft.Row(
|
||||||
|
width = page.width,
|
||||||
|
controls = [
|
||||||
|
ft.Container(content = app_bar_title),
|
||||||
|
ft.VerticalDivider(width = 20, opacity = 0),
|
||||||
|
ft.Container(expand = 6, content = prompt),
|
||||||
|
# ft.Container(expand = 1, content = generate_button),
|
||||||
|
ft.Container(expand = 4, content = option_bar),
|
||||||
|
],
|
||||||
|
height = 50,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
###### toolbar #########################################################
|
||||||
|
open_gallery_button = ft.IconButton(width = 50, content = ft.Icon(ft.icons.DASHBOARD_OUTLINED), tooltip = 'Gallery', on_click = open_gallery_window)
|
||||||
|
import_image_button = ft.IconButton(width = 50, content = ft.Icon(ft.icons.ADD_OUTLINED), tooltip = 'Import image as new layer', on_click = None)
|
||||||
|
|
||||||
|
universal_tools = ft.Row(
|
||||||
|
alignment = 'start',
|
||||||
|
width = 50,
|
||||||
|
wrap = True,
|
||||||
|
controls = [
|
||||||
|
open_gallery_button,
|
||||||
|
import_image_button,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
## default layout tools
|
||||||
|
default_layout_tools = ft.Row(
|
||||||
|
alignment = 'start',
|
||||||
|
wrap = True,
|
||||||
|
controls = [
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
## textual inversion tools
|
||||||
|
textual_inversion_layout_tools = ft.Row(
|
||||||
|
alignment = 'start',
|
||||||
|
wrap = True,
|
||||||
|
controls = [
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
## node editor tools
|
||||||
|
node_editor_layout_tools = ft.Row(
|
||||||
|
alignment = 'start',
|
||||||
|
wrap = True,
|
||||||
|
controls = [
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
current_layout_tools = ft.Column(
|
||||||
|
controls = [
|
||||||
|
default_layout_tools,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
toolbar = ft.Column(
|
||||||
|
controls = [
|
||||||
|
ft.Container(content = universal_tools),
|
||||||
|
ft.Container(content = current_layout_tools),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
###### layers panel ####################################################
|
||||||
|
def show_hide_layer(e):
|
||||||
|
parent = e.control.data['parent']
|
||||||
|
if parent.data['hidden']:
|
||||||
|
parent.data['hidden'] = False
|
||||||
|
parent.opacity = 1.0
|
||||||
|
else:
|
||||||
|
parent.data['hidden'] = True
|
||||||
|
parent.opacity = 0.5
|
||||||
|
page.update()
|
||||||
|
|
||||||
|
def get_layers():
|
||||||
|
layers = [ft.Divider(height=10, opacity = 0)]
|
||||||
|
count = 0
|
||||||
|
for i in range(10):
|
||||||
|
count += 1
|
||||||
|
layer_icon = ft.IconButton(
|
||||||
|
icon = ft.icons.HIGHLIGHT_ALT_OUTLINED,
|
||||||
|
tooltip = 'show/hide',
|
||||||
|
on_click = show_hide_layer,
|
||||||
|
data = {'parent':None},
|
||||||
|
)
|
||||||
|
layer_label = ft.Text(value = ("layer_" + str(count)))
|
||||||
|
layer_button = ft.Row(
|
||||||
|
controls = [
|
||||||
|
layer_icon,
|
||||||
|
layer_label,
|
||||||
|
],
|
||||||
|
data = {'hidden':False},
|
||||||
|
)
|
||||||
|
layer_icon.data.update({'parent':layer_button}) ## <--see what i did there? :)
|
||||||
|
layers.append(layer_button)
|
||||||
|
return layers
|
||||||
|
|
||||||
|
layer_list = get_layers()
|
||||||
|
|
||||||
|
layer_manager = ft.Container(
|
||||||
|
content = ft.Column(
|
||||||
|
controls = layer_list,
|
||||||
|
),
|
||||||
|
bgcolor = ft.colors.WHITE10,
|
||||||
|
)
|
||||||
|
|
||||||
|
asset_manager = ft.Container(
|
||||||
|
content = ft.Column(
|
||||||
|
controls = [
|
||||||
|
ft.Divider(height=10, opacity = 0),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
bgcolor = ft.colors.WHITE10,
|
||||||
|
)
|
||||||
|
|
||||||
|
layers = ft.Container(
|
||||||
|
width = 200,
|
||||||
|
content = ft.Tabs(
|
||||||
|
selected_index = 0,
|
||||||
|
animation_duration = 300,
|
||||||
|
tabs = [
|
||||||
|
ft.Tab(
|
||||||
|
text = "Layers",
|
||||||
|
content = layer_manager,
|
||||||
|
),
|
||||||
|
ft.Tab(
|
||||||
|
text = "Assets",
|
||||||
|
content = asset_manager,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
###### canvas ##########################################################
|
||||||
|
canvas = ft.Container(
|
||||||
|
content = ft.Stack(
|
||||||
|
[
|
||||||
|
ft.Image(
|
||||||
|
src=f"https://i.redd.it/qdxksbar05o31.jpg",
|
||||||
|
#width=300,
|
||||||
|
#height=300,
|
||||||
|
#fit="contain",
|
||||||
|
gapless_playback=True,
|
||||||
|
expand=True,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
clip_behavior = None,
|
||||||
|
),
|
||||||
|
alignment = ft.alignment.center,
|
||||||
|
expand = True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
###### text editor #####################################################
|
||||||
|
text_editor = ft.Container(
|
||||||
|
content = ft.Text('WIP'),
|
||||||
|
expand = True,
|
||||||
|
)
|
||||||
|
|
||||||
|
###### top panel #######################################################
|
||||||
|
top_panel = ft.Container(
|
||||||
|
content = ft.Tabs(
|
||||||
|
selected_index = 0,
|
||||||
|
animation_duration = 300,
|
||||||
|
tabs = [
|
||||||
|
ft.Tab(
|
||||||
|
text = 'Canvas',
|
||||||
|
content = canvas,
|
||||||
|
),
|
||||||
|
ft.Tab(
|
||||||
|
text = 'Text Editor',
|
||||||
|
content = text_editor,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
expand = True,
|
||||||
|
)
|
||||||
|
|
||||||
|
###### bottom_panel ####################################################
|
||||||
|
video_editor_window = ft.Container(bgcolor=ft.colors.BLACK12, height=250)
|
||||||
|
messages_window = ft.Container(bgcolor=ft.colors.BLACK12, height=250)
|
||||||
|
|
||||||
|
bottom_panel = ft.Row(
|
||||||
|
height = 150,
|
||||||
|
controls = [
|
||||||
|
ft.Tabs(
|
||||||
|
selected_index = 0,
|
||||||
|
animation_duration = 300,
|
||||||
|
tabs = [
|
||||||
|
ft.Tab(
|
||||||
|
text = "Messages",
|
||||||
|
content = messages_window,
|
||||||
|
),
|
||||||
|
ft.Tab(
|
||||||
|
text = "Video Editor",
|
||||||
|
content = video_editor_window,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
###### center panel ####################################################
|
||||||
|
|
||||||
|
center_panel = ft.Container(
|
||||||
|
content = ft.Column(
|
||||||
|
controls = [
|
||||||
|
top_panel,
|
||||||
|
bottom_panel,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
expand = True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
###### property panel ##################################################
|
||||||
|
## canvas layout properties
|
||||||
|
model_menu = ft.Dropdown(
|
||||||
|
label = "Custom Models",
|
||||||
|
options = [
|
||||||
|
ft.dropdown.Option("Stable Diffusion 1.5"),
|
||||||
|
ft.dropdown.Option("Waifu Diffusion 1.3"),
|
||||||
|
ft.dropdown.Option("MM-27 Merged Pruned"),
|
||||||
|
],
|
||||||
|
height = 70,
|
||||||
|
expand = 1,
|
||||||
|
value = "Stable Diffusion 1.5",
|
||||||
|
tooltip = "Custom models located in your `models/custom` folder including the default stable diffusion model.",
|
||||||
|
)
|
||||||
|
|
||||||
|
sampling_menu = ft.Dropdown(
|
||||||
|
label = "Sampling method",
|
||||||
|
options = [ #["k_lms", "k_euler", "k_euler_a", "k_dpm_2", "k_dpm_2_a", "k_heun", "PLMS", "DDIM"]
|
||||||
|
ft.dropdown.Option("k_lms"),
|
||||||
|
ft.dropdown.Option("k_euler"),
|
||||||
|
ft.dropdown.Option("k_euler_a"),
|
||||||
|
ft.dropdown.Option("k_dpm_2"),
|
||||||
|
ft.dropdown.Option("k_dpm_2_a"),
|
||||||
|
ft.dropdown.Option("k_heun"),
|
||||||
|
ft.dropdown.Option("PLMS"),
|
||||||
|
ft.dropdown.Option("DDIM"),
|
||||||
|
],
|
||||||
|
height = 70,
|
||||||
|
expand = 1,
|
||||||
|
value = "k_lms",
|
||||||
|
tooltip = "Sampling method or scheduler to use, different sampling method"
|
||||||
|
" or schedulers behave differently giving better or worst performance in more or less steps."
|
||||||
|
"Try to find the best one for your needs and hardware.",
|
||||||
|
)
|
||||||
|
|
||||||
|
default_layout_properties = ft.Container(
|
||||||
|
content = ft.Column(
|
||||||
|
controls = [
|
||||||
|
ft.Row(
|
||||||
|
controls = [
|
||||||
|
model_menu,
|
||||||
|
],
|
||||||
|
spacing = 4,
|
||||||
|
alignment = 'spaceAround',
|
||||||
|
),
|
||||||
|
ft.Row(
|
||||||
|
controls = [
|
||||||
|
sampling_menu,
|
||||||
|
],
|
||||||
|
spacing = 4,
|
||||||
|
alignment = 'spaceAround',
|
||||||
|
),
|
||||||
|
ft.Row(
|
||||||
|
controls = [
|
||||||
|
ft.TextField(label="Width", value=512, height=50, expand=1, suffix_text="W", text_align='center', tooltip="Widgth in pixels.", keyboard_type="number"),
|
||||||
|
ft.TextField(label="Height", value=512, height=50, expand=1, suffix_text="H", text_align='center', tooltip="Height in pixels.",keyboard_type="number"),
|
||||||
|
],
|
||||||
|
spacing = 4,
|
||||||
|
alignment = 'spaceAround',
|
||||||
|
),
|
||||||
|
ft.Row(
|
||||||
|
controls = [
|
||||||
|
ft.TextField(label="CFG", value=7.5, height=50, expand=1, text_align='center', #suffix_text="CFG",
|
||||||
|
tooltip="Classifier Free Guidance Scale.", keyboard_type="number"),
|
||||||
|
ft.TextField(label="Sampling Steps", value=30, height=50, expand=1, text_align='center', tooltip="Sampling steps.", keyboard_type="number"),
|
||||||
|
],
|
||||||
|
spacing = 4,
|
||||||
|
alignment = 'spaceAround',
|
||||||
|
),
|
||||||
|
ft.Row(
|
||||||
|
controls = [
|
||||||
|
ft.TextField(
|
||||||
|
label = "Seed",
|
||||||
|
hint_text = "blank=random seed",
|
||||||
|
height = 60,
|
||||||
|
expand = 1,
|
||||||
|
text_align = 'start',
|
||||||
|
#suffix_text = "seed",
|
||||||
|
tooltip = "Seed used for the generation, leave empty or use -1 for a random seed. You can also use word as seeds.",
|
||||||
|
keyboard_type = "number"
|
||||||
|
),
|
||||||
|
],
|
||||||
|
spacing = 4,
|
||||||
|
alignment = 'spaceAround',
|
||||||
|
),
|
||||||
|
ft.Draggable(content=ft.Divider(height=10, color="gray")),
|
||||||
|
# ft.Switch(label="Stable Horde", value=False, disabled=True, tooltip="Option disabled for now."),
|
||||||
|
# ft.Draggable(content=ft.Divider(height=10, color="gray")),
|
||||||
|
# ft.Switch(label="Batch Options", value=False, disabled=True, tooltip="Option disabled for now."),
|
||||||
|
# ft.Draggable(content=ft.Divider(height=10, color="gray")),
|
||||||
|
# ft.Switch(label="Upscaling", value=False, disabled=True, tooltip="Option disabled for now."),
|
||||||
|
# ft.Draggable(content=ft.Divider(height=10, color="gray")),
|
||||||
|
# ft.Switch(label="Preview Image Settings", value=False, disabled=True, tooltip="Option disabled for now."),
|
||||||
|
# ft.Draggable(content=ft.Divider(height=10, color="gray")),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
expand = True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
## textual inversion layout properties
|
||||||
|
clip_model_menu_label = ft.Text(value='Clip Models', tooltip = "Select Clip model(s) to use.")
|
||||||
|
clip_model_menu = ft.PopupMenuButton(
|
||||||
|
items = [
|
||||||
|
ft.PopupMenuItem(text="Vit-L/14", checked=False, data='Vit-L/14', on_click=None),
|
||||||
|
ft.PopupMenuItem(text="Vit-H-14", checked=False, data='Vit-H-14', on_click=None),
|
||||||
|
ft.PopupMenuItem(text="Vit-g-14", checked=False, data='Vit-g-14', on_click=None),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
other_model_menu_label = ft.Text(value='Other Models', tooltip = "For DiscoDiffusion and JAX enable all the same models here as you intend to use when generating your images.")
|
||||||
|
other_model_menu = ft.PopupMenuButton(
|
||||||
|
items = [
|
||||||
|
ft.PopupMenuItem(text="VitL14_336px", checked=False, data='VitL14_336px', on_click=None),
|
||||||
|
ft.PopupMenuItem(text="VitB16", checked=False, data='VitB16', on_click=None),
|
||||||
|
ft.PopupMenuItem(text="VitB32", checked=False, data='VitB32', on_click=None),
|
||||||
|
ft.PopupMenuItem(text="RN50", checked=False, data='RN50', on_click=None),
|
||||||
|
ft.PopupMenuItem(text="RN50x4", checked=False, data='RN50x4', on_click=None),
|
||||||
|
ft.PopupMenuItem(text="RN50x16", checked=False, data='RN50x16', on_click=None),
|
||||||
|
ft.PopupMenuItem(text="RN50x64", checked=False, data='RN50x64', on_click=None),
|
||||||
|
ft.PopupMenuItem(text="RN101", checked=False, data='RN101', on_click=None),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_textual_inversion_settings():
|
||||||
|
settings = {
|
||||||
|
'selected_models' : [],
|
||||||
|
'selected_images' : [],
|
||||||
|
'results' : [],
|
||||||
|
}
|
||||||
|
return settings
|
||||||
|
|
||||||
|
def get_textual_inversion_grid_row(row_name):
|
||||||
|
row_items = []
|
||||||
|
row_items.append(ft.Text(value = row_name))
|
||||||
|
row_items.append(ft.Text(value = webui_flet_utils.get_textual_inversion_row_value(row_name)))
|
||||||
|
return row_items
|
||||||
|
|
||||||
|
def get_textual_inversion_results_grid():
|
||||||
|
grid_rows = []
|
||||||
|
for item in webui_flet_utils.textual_inversion_grid_row_list:
|
||||||
|
grid_rows.append(
|
||||||
|
ft.Row(
|
||||||
|
controls = get_textual_inversion_grid_row(item),
|
||||||
|
height = 50,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return ft.Column(controls = grid_rows)
|
||||||
|
|
||||||
|
def get_textual_inversion_results(e):
|
||||||
|
e.control.data = get_textual_inversion_settings()
|
||||||
|
webui_flet_utils.run_textual_inversion(e.control.data)
|
||||||
|
textual_inversion_results.content = get_textual_inversion_results_grid()
|
||||||
|
page.update()
|
||||||
|
|
||||||
|
run_textual_inversion_button = ft.ElevatedButton("Get Text from Image(s)", on_click=get_textual_inversion_results, data = {})
|
||||||
|
|
||||||
|
textual_inversion_results = ft.Container(content = None)
|
||||||
|
|
||||||
|
textual_inversion_layout_properties = ft.Container(
|
||||||
|
content = ft.Column(
|
||||||
|
controls = [
|
||||||
|
ft.Row(
|
||||||
|
controls = [
|
||||||
|
clip_model_menu_label,
|
||||||
|
clip_model_menu,
|
||||||
|
],
|
||||||
|
spacing = 4,
|
||||||
|
alignment = 'spaceAround',
|
||||||
|
),
|
||||||
|
ft.Row(
|
||||||
|
controls = [
|
||||||
|
other_model_menu_label,
|
||||||
|
other_model_menu,
|
||||||
|
],
|
||||||
|
spacing = 4,
|
||||||
|
alignment = 'spaceAround',
|
||||||
|
),
|
||||||
|
ft.Row(
|
||||||
|
controls = [
|
||||||
|
run_textual_inversion_button,
|
||||||
|
],
|
||||||
|
alignment = 'spaceAround',
|
||||||
|
),
|
||||||
|
ft.Draggable(content=ft.Divider(height=10, color="gray")),
|
||||||
|
ft.Row(
|
||||||
|
controls = [
|
||||||
|
textual_inversion_results,
|
||||||
|
],
|
||||||
|
wrap = True,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
expand = True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
## node editor layout properties
|
||||||
|
node_editor_layout_properties = ft.Container(
|
||||||
|
content = ft.Column(
|
||||||
|
controls = [
|
||||||
|
]
|
||||||
|
),
|
||||||
|
expand = True
|
||||||
|
)
|
||||||
|
|
||||||
|
## property panel
|
||||||
|
property_panel = ft.Container(
|
||||||
|
bgcolor = ft.colors.WHITE10,
|
||||||
|
content = ft.Column(
|
||||||
|
controls = [
|
||||||
|
ft.Divider(height=10, opacity = 0),
|
||||||
|
default_layout_properties,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
## advanced panel
|
||||||
|
advanced_panel = ft.Container(
|
||||||
|
bgcolor = ft.colors.WHITE10,
|
||||||
|
content = ft.Column(
|
||||||
|
controls = [
|
||||||
|
ft.Divider(height=10, opacity = 0),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
right_panel = ft.Container(
|
||||||
|
content = ft.Tabs(
|
||||||
|
selected_index = 0,
|
||||||
|
animation_duration = 300,
|
||||||
|
tabs = [
|
||||||
|
ft.Tab(
|
||||||
|
text = 'Properties',
|
||||||
|
content = property_panel,
|
||||||
|
),
|
||||||
|
ft.Tab(
|
||||||
|
text = 'Advanced',
|
||||||
|
content = advanced_panel,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
width = 250,
|
||||||
|
)
|
||||||
|
|
||||||
|
###### workspace #######################################################
|
||||||
|
workspace = ft.Row(
|
||||||
|
controls = [
|
||||||
|
toolbar,
|
||||||
|
ft.VerticalDivider(width=2, color="gray", opacity = 0),
|
||||||
|
layers,
|
||||||
|
ft.VerticalDivider(width=2, color="gray", opacity = 0),
|
||||||
|
center_panel,
|
||||||
|
ft.VerticalDivider(width=2, color="gray", opacity = 0),
|
||||||
|
right_panel,
|
||||||
|
],
|
||||||
|
expand=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
###### make page #######################################################
|
||||||
|
page.title = "Stable Diffusion Playground"
|
||||||
|
page.theme_mode = "dark"
|
||||||
|
page.appbar = ft.AppBar(
|
||||||
|
#leading=leading,
|
||||||
|
#leading_width=leading_width,
|
||||||
|
automatically_imply_leading=True,
|
||||||
|
#elevation=5,
|
||||||
|
bgcolor=ft.colors.BLACK26,
|
||||||
|
actions=[appbar]
|
||||||
|
)
|
||||||
|
page.add(workspace)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ft.app(target=main, port=8505, view=ft.WEB_BROWSER)
|
34
scripts/webui_flet_utils.py
Normal file
34
scripts/webui_flet_utils.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
## webui_utils.py
|
||||||
|
|
||||||
|
## imports
|
||||||
|
import os, yaml
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
|
|
||||||
|
###### Settings ########################################################
|
||||||
|
path_to_default_config = 'configs/webui/webui_flet.yaml'
|
||||||
|
path_to_user_config = 'configs/webui/userconfig_flet.yaml'
|
||||||
|
|
||||||
|
def get_default_settings_from_config():
|
||||||
|
with open(path_to_default_config) as f:
|
||||||
|
default_settings = yaml.safe_load(f)
|
||||||
|
return default_settings
|
||||||
|
|
||||||
|
def get_user_settings_from_config():
|
||||||
|
settings = get_default_settings_from_config()
|
||||||
|
if os.path.exists(path_to_user_config):
|
||||||
|
with open(path_to_user_config) as f:
|
||||||
|
user_settings = yaml.safe_load(f)
|
||||||
|
settings.update(user_settings)
|
||||||
|
return settings
|
||||||
|
|
||||||
|
def save_user_settings_to_config(settings):
|
||||||
|
with open(path_to_user_config, 'w+') as f:
|
||||||
|
yaml.dump(settings, f, default_flow_style=False)
|
||||||
|
|
||||||
|
|
||||||
|
###### Textual Inversion ###############################################
|
||||||
|
textual_inversion_grid_row_list = [
|
||||||
|
'model', 'medium', 'artist', 'trending', 'movement', 'flavors', 'techniques', 'tags',
|
||||||
|
]
|
||||||
|
|
391
webui_flet.py
391
webui_flet.py
@ -1,391 +0,0 @@
|
|||||||
# Flet imports
|
|
||||||
import flet as ft
|
|
||||||
|
|
||||||
# other imports
|
|
||||||
from math import pi
|
|
||||||
from typing import Optional
|
|
||||||
from loguru import logger
|
|
||||||
|
|
||||||
class MenuButton(ft.Container):
|
|
||||||
def __init__(
|
|
||||||
self, title: str, icon: Optional[ft.Control] = None, selected: bool = False
|
|
||||||
):
|
|
||||||
super().__init__()
|
|
||||||
self.icon = icon
|
|
||||||
self.title = title
|
|
||||||
self._selected = selected
|
|
||||||
self.padding = ft.padding.only(left=43)
|
|
||||||
self.height = 38
|
|
||||||
self.border_radius = 4
|
|
||||||
self.ink = True
|
|
||||||
self.on_click = self.item_click
|
|
||||||
|
|
||||||
def item_click(self, _):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _build(self):
|
|
||||||
row = ft.Row()
|
|
||||||
if self.icon != None:
|
|
||||||
row.controls.append(self.icon)
|
|
||||||
row.controls.append(ft.Text(self.title))
|
|
||||||
self.content = row
|
|
||||||
|
|
||||||
def _before_build_command(self):
|
|
||||||
self.bgcolor = "surfacevariant" if self._selected else None
|
|
||||||
super()._before_build_command()
|
|
||||||
|
|
||||||
class Collapsible(ft.Column):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
title: str,
|
|
||||||
content: ft.Control,
|
|
||||||
icon: Optional[ft.Control] = None,
|
|
||||||
spacing: float = 3,
|
|
||||||
):
|
|
||||||
super().__init__()
|
|
||||||
self.icon = icon
|
|
||||||
self.title = title
|
|
||||||
self.shevron = ft.Icon(
|
|
||||||
ft.icons.KEYBOARD_ARROW_DOWN_ROUNDED,
|
|
||||||
animate_rotation=100,
|
|
||||||
rotate=0,
|
|
||||||
)
|
|
||||||
self.content = ft.Column(
|
|
||||||
[Container(height=spacing), content],
|
|
||||||
height=0,
|
|
||||||
spacing=0,
|
|
||||||
animate_size=100,
|
|
||||||
opacity=0,
|
|
||||||
animate_opacity=100,
|
|
||||||
)
|
|
||||||
self.spacing = 0
|
|
||||||
|
|
||||||
def header_click(self, e):
|
|
||||||
self.content.height = None if self.content.height == 0 else 0
|
|
||||||
self.content.opacity = 0 if self.content.height == 0 else 1
|
|
||||||
self.shevron.rotate = pi if self.shevron.rotate == 0 else 0
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
def _build(self):
|
|
||||||
title_row = ft.Row()
|
|
||||||
if self.icon != None:
|
|
||||||
title_row.controls.append(self.icon)
|
|
||||||
title_row.controls.append(ft.Text(self.title))
|
|
||||||
self.controls.extend(
|
|
||||||
[
|
|
||||||
Container(
|
|
||||||
ft.Row([title_row, self.shevron], alignment="spaceBetween"),
|
|
||||||
padding=ft.padding.only(left=8, right=8),
|
|
||||||
height=38,
|
|
||||||
border_radius=4,
|
|
||||||
ink=True,
|
|
||||||
on_click=self.header_click,
|
|
||||||
),
|
|
||||||
self.content,
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
@logger.catch(reraise=True)
|
|
||||||
def main(page: ft.Page):
|
|
||||||
## function defines
|
|
||||||
|
|
||||||
#def check_item_clicked(e):
|
|
||||||
#e.control.checked = not e.control.checked
|
|
||||||
#page.update()
|
|
||||||
|
|
||||||
def change_theme(e):
|
|
||||||
page.theme_mode = "dark" if page.theme_mode == "light" else "light"
|
|
||||||
|
|
||||||
if "(Light theme)" in theme_switcher.tooltip:
|
|
||||||
theme_switcher.tooltip = theme_switcher.tooltip.replace("(Light theme)", '')
|
|
||||||
|
|
||||||
if "(Dark theme)" in theme_switcher.tooltip:
|
|
||||||
theme_switcher.tooltip = theme_switcher.tooltip.replace("(Dark theme)", '')
|
|
||||||
|
|
||||||
theme_switcher.tooltip += "(Light theme)" if page.theme_mode == "light" else "(Dark theme)"
|
|
||||||
page.update()
|
|
||||||
|
|
||||||
def close_settings_window(e):
|
|
||||||
settings.open = False
|
|
||||||
page.update()
|
|
||||||
|
|
||||||
def open_settings_window(e):
|
|
||||||
page.dialog = settings
|
|
||||||
settings.open = True
|
|
||||||
page.update()
|
|
||||||
|
|
||||||
## page defines
|
|
||||||
page.title = "Stable Diffusion Playground"
|
|
||||||
page.theme_mode = "dark"
|
|
||||||
|
|
||||||
## header defines
|
|
||||||
app_bar_title = ft.Text("Sygil", selectable=True)
|
|
||||||
|
|
||||||
settings = ft.AlertDialog(
|
|
||||||
#modal = True,
|
|
||||||
title = ft.Text("Settings"),
|
|
||||||
content = ft.Row(
|
|
||||||
controls = [
|
|
||||||
ft.Text("Nothing here yet."),
|
|
||||||
ft.Container(
|
|
||||||
width=500,
|
|
||||||
height=500,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
actions = [
|
|
||||||
# should save options when clicked
|
|
||||||
ft.ElevatedButton("Save", icon=ft.icons.SAVE, on_click=close_settings_window),
|
|
||||||
|
|
||||||
# Should allow you to discard changed made to the settings.
|
|
||||||
ft.ElevatedButton("Discard", icon=ft.icons.RESTORE_FROM_TRASH_ROUNDED, on_click=close_settings_window),
|
|
||||||
],
|
|
||||||
actions_alignment="end",
|
|
||||||
#on_dismiss=lambda e: print("Modal dialog dismissed!"),
|
|
||||||
)
|
|
||||||
|
|
||||||
prompt = ft.TextField(
|
|
||||||
#label="Prompt",
|
|
||||||
value="",
|
|
||||||
min_lines=1,
|
|
||||||
max_lines=1,
|
|
||||||
shift_enter=True,
|
|
||||||
#width=1000,
|
|
||||||
tooltip="Prompt to use for generation.",
|
|
||||||
#autofocus=True,
|
|
||||||
hint_text="A corgi wearing a top hat as an oil paiting.",
|
|
||||||
)
|
|
||||||
|
|
||||||
generate_button = ft.ElevatedButton("Generate", on_click=None)
|
|
||||||
|
|
||||||
theme_switcher = ft.IconButton(
|
|
||||||
ft.icons.WB_SUNNY_OUTLINED,
|
|
||||||
on_click = change_theme,
|
|
||||||
expand = 1,
|
|
||||||
tooltip = f"Click to change between the light and dark themes. Current {'(Light theme)' if page.theme_mode == 'light' else '(Dark theme)'}"
|
|
||||||
)
|
|
||||||
|
|
||||||
settings_button = ft.IconButton(icon=ft.icons.SETTINGS, on_click=open_settings_window)
|
|
||||||
|
|
||||||
menu_button = ft.PopupMenuButton(
|
|
||||||
expand = 1,
|
|
||||||
items = [
|
|
||||||
#ft.PopupMenuItem(text="Settings", on_click=open_settings_modal),
|
|
||||||
ft.PopupMenuItem(), # divider
|
|
||||||
#ft.PopupMenuItem(text="Checked item", checked=False, on_click=check_item_clicked),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
option_bar = ft.Row(
|
|
||||||
controls = [
|
|
||||||
#ft.Container(expand = 1, content = dropdown),
|
|
||||||
ft.Container(expand = 1, content = theme_switcher),
|
|
||||||
ft.Container(expand = 1, content = settings_button),
|
|
||||||
ft.Container(expand = 1, content = menu_button),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
appbar = ft.Row(
|
|
||||||
width = page.width,
|
|
||||||
controls = [
|
|
||||||
ft.Container(width = 60, content = app_bar_title),
|
|
||||||
ft.VerticalDivider(width=10, color="gray"),
|
|
||||||
ft.Container(expand = 4, content = prompt),
|
|
||||||
ft.Container(expand = 1, content = generate_button),
|
|
||||||
ft.VerticalDivider(width=10, color="gray"),
|
|
||||||
ft.Container(width = 410, content = option_bar),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
## main panel defines
|
|
||||||
|
|
||||||
## left panel
|
|
||||||
left_panel = ft.Column(
|
|
||||||
width = 50,
|
|
||||||
controls = [
|
|
||||||
# Create a container so we can group buttons, change bgcolor and drag it around later.
|
|
||||||
# add some buttons inside containers so we can rearrange them if needed and drop things in them.
|
|
||||||
#ft.Container(ft.IconButton(icon=ft.icons.MENU_OUTLINED, tooltip='')),
|
|
||||||
ft.Container(ft.IconButton(width=50, content = ft.Icon(ft.icons.ADD_OUTLINED), tooltip ='Import Image', on_click = None, disabled=True)),
|
|
||||||
ft.Container(ft.IconButton(width=50, content = ft.Icon(ft.icons.DASHBOARD_OUTLINED), tooltip = 'Gallery', on_click = None, disabled=True)),
|
|
||||||
ft.Draggable(content=ft.Divider(height=10, color="white")),
|
|
||||||
#)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
## canvas
|
|
||||||
canvas = ft.Container(
|
|
||||||
content = ft.Stack(
|
|
||||||
[
|
|
||||||
#ft.Row([
|
|
||||||
#ft.Image(
|
|
||||||
#src=f"https://static.wixstatic.com/media/ac4dba_13be94c39c804e8aa2131a51036a0244~mv2.png",
|
|
||||||
#width=300,
|
|
||||||
#height=30,
|
|
||||||
#fit="contain",
|
|
||||||
#expand=True,
|
|
||||||
#),
|
|
||||||
#]),
|
|
||||||
ft.Stack(
|
|
||||||
[
|
|
||||||
ft.Image(
|
|
||||||
src=f"https://i.redd.it/qdxksbar05o31.jpg",
|
|
||||||
#width=300,
|
|
||||||
#height=300,
|
|
||||||
#fit="contain",
|
|
||||||
gapless_playback=True,
|
|
||||||
expand=True,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
#width=40,
|
|
||||||
#height=40,
|
|
||||||
clip_behavior=None,
|
|
||||||
),
|
|
||||||
alignment=ft.alignment.center, #type: ignore
|
|
||||||
bgcolor=ft.colors.WHITE10,
|
|
||||||
expand=True
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
## right panel
|
|
||||||
model_menu = ft.Dropdown(
|
|
||||||
label = "Custom Models",
|
|
||||||
options = [
|
|
||||||
ft.dropdown.Option("Stable Diffusion 1.5"),
|
|
||||||
ft.dropdown.Option("Waifu Diffusion 1.3"),
|
|
||||||
ft.dropdown.Option("MM-27 Merged Pruned"),
|
|
||||||
],
|
|
||||||
height = 70,
|
|
||||||
expand = 1,
|
|
||||||
value = "Stable Diffusion 1.5",
|
|
||||||
tooltip = "Custom models located in your `models/custom` folder including the default stable diffusion model.",
|
|
||||||
)
|
|
||||||
|
|
||||||
sampling_menu = ft.Dropdown(
|
|
||||||
label = "Sampling method",
|
|
||||||
options = [ #["k_lms", "k_euler", "k_euler_a", "k_dpm_2", "k_dpm_2_a", "k_heun", "PLMS", "DDIM"]
|
|
||||||
ft.dropdown.Option("k_lms"),
|
|
||||||
ft.dropdown.Option("k_euler"),
|
|
||||||
ft.dropdown.Option("k_euler_a"),
|
|
||||||
ft.dropdown.Option("k_dpm_2"),
|
|
||||||
ft.dropdown.Option("k_dpm_2_a"),
|
|
||||||
ft.dropdown.Option("k_heun"),
|
|
||||||
ft.dropdown.Option("PLMS"),
|
|
||||||
ft.dropdown.Option("DDIM"),
|
|
||||||
],
|
|
||||||
height = 70,
|
|
||||||
expand = 1,
|
|
||||||
value = "k_lms",
|
|
||||||
tooltip = "Sampling method or scheduler to use, different sampling method"
|
|
||||||
" or schedulers behave differently giving better or worst performance in more or less steps."
|
|
||||||
"Try to find the best one for your needs and hardware.",
|
|
||||||
)
|
|
||||||
|
|
||||||
options = ft.Container(
|
|
||||||
content = ft.Column(
|
|
||||||
controls = [
|
|
||||||
ft.Row(
|
|
||||||
controls = [
|
|
||||||
model_menu,
|
|
||||||
],
|
|
||||||
spacing = 4,
|
|
||||||
alignment = 'spaceAround',
|
|
||||||
),
|
|
||||||
ft.Row(
|
|
||||||
controls = [
|
|
||||||
sampling_menu,
|
|
||||||
],
|
|
||||||
spacing = 4,
|
|
||||||
alignment = 'spaceAround',
|
|
||||||
),
|
|
||||||
ft.Row(
|
|
||||||
controls = [
|
|
||||||
ft.TextField(label="Width", value=512, height=50, expand=1, suffix_text="W", text_align='center', tooltip="Widgth in pixels.", keyboard_type="number"),
|
|
||||||
ft.TextField(label="Height", value=512, height=50, expand=1, suffix_text="H", text_align='center', tooltip="Height in pixels.",keyboard_type="number"),
|
|
||||||
ft.TextField(label="CFG", value=7.5, height=50, expand=1, text_align='center', #suffix_text="CFG",
|
|
||||||
tooltip="Classifier Free Guidance Scale.", keyboard_type="number"),
|
|
||||||
],
|
|
||||||
spacing = 4,
|
|
||||||
alignment = 'spaceAround',
|
|
||||||
),
|
|
||||||
ft.Row(
|
|
||||||
controls = [
|
|
||||||
ft.TextField(label="Seed", hint_text="blank=random seed", height=60, expand=2, text_align='start', #suffix_text="seed",
|
|
||||||
tooltip="Seed used for the generation, leave empty or use -1 for a random seed. You can also use word as seeds.",
|
|
||||||
keyboard_type="number"
|
|
||||||
),
|
|
||||||
ft.TextField(label="Sampling Steps", value=30, height=60, expand=1, text_align='center', tooltip="Sampling steps.", keyboard_type="number"),
|
|
||||||
],
|
|
||||||
spacing = 4,
|
|
||||||
alignment = 'spaceAround',
|
|
||||||
),
|
|
||||||
ft.Draggable(content=ft.Divider(height=10, color="gray")),
|
|
||||||
ft.Switch(label="Stable Horde", value=False, disabled=True, tooltip="Option disabled for now."),
|
|
||||||
ft.Draggable(content=ft.Divider(height=10, color="gray")),
|
|
||||||
ft.Switch(label="Batch Options", value=False, disabled=True, tooltip="Option disabled for now."),
|
|
||||||
ft.Draggable(content=ft.Divider(height=10, color="gray")),
|
|
||||||
ft.Switch(label="Upscaling", value=False, disabled=True, tooltip="Option disabled for now."),
|
|
||||||
ft.Draggable(content=ft.Divider(height=10, color="gray")),
|
|
||||||
ft.Switch(label="Preview Image Settings", value=False, disabled=True, tooltip="Option disabled for now."),
|
|
||||||
ft.Draggable(content=ft.Divider(height=10, color="gray")),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
expand = True
|
|
||||||
)
|
|
||||||
|
|
||||||
right_panel = ft.Column(
|
|
||||||
width=400,
|
|
||||||
controls = [
|
|
||||||
options,
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
main_panel = ft.Row(
|
|
||||||
controls = [
|
|
||||||
left_panel,
|
|
||||||
ft.Draggable(content=ft.VerticalDivider(width=10, color="gray")),
|
|
||||||
canvas,
|
|
||||||
ft.Draggable(content=ft.VerticalDivider(width=10, color="gray")),
|
|
||||||
right_panel,
|
|
||||||
],
|
|
||||||
expand=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
## bottom_panel defines
|
|
||||||
bottom_panel = ft.Container(
|
|
||||||
content = ft.Stack(
|
|
||||||
[
|
|
||||||
ft.Tooltip(
|
|
||||||
message="Nothing to see here as this panel is not yet implemented.",
|
|
||||||
content = ft.Container(bgcolor=ft.colors.BLACK12, height=150)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
## add appbar to page
|
|
||||||
page.appbar = ft.AppBar(
|
|
||||||
#leading=leading,
|
|
||||||
#leading_width=leading_width,
|
|
||||||
automatically_imply_leading=True,
|
|
||||||
#elevation=5,
|
|
||||||
bgcolor=ft.colors.BLACK26,
|
|
||||||
actions=[appbar]
|
|
||||||
)
|
|
||||||
|
|
||||||
## add main body to page
|
|
||||||
page.add(main_panel)
|
|
||||||
|
|
||||||
## add bottom_panel to page
|
|
||||||
page.add(bottom_panel)
|
|
||||||
|
|
||||||
|
|
||||||
#page.add(ft.Container(ft.Text("test", selectable=True),height=500))
|
|
||||||
|
|
||||||
|
|
||||||
ft.app(target=main, port=8505)
|
|
Loading…
Reference in New Issue
Block a user