Skip to content

Commit

Permalink
Merge pull request #354 from Capsize-Games/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
w4ffl35 authored Jan 9, 2024
2 parents 2b796f6 + 7ae78be commit f2d0c5c
Show file tree
Hide file tree
Showing 12 changed files with 450 additions and 805 deletions.
2 changes: 1 addition & 1 deletion src/airunner/aihandler/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def error(cls, msg):
cls.logger.error(msg)


Logger.set_level(logging.DEBUG)
Logger.set_level(LOG_LEVEL)
Logger.stream_handler.setFormatter(Logger.formatter)
Logger.logger.addHandler(Logger.stream_handler)
logging.getLogger("lightning").setLevel(logging.WARNING)
Expand Down
3 changes: 1 addition & 2 deletions src/airunner/aihandler/offline_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
import queue
import time
import threading
from airunner.aihandler.engine import Engine

from airunner.aihandler.engine import Engine
from airunner.aihandler.logger import Logger as logger
from airunner.aihandler.runner import SDRunner


class OfflineClient:
Expand Down
4 changes: 2 additions & 2 deletions src/airunner/widgets/canvas_plus/canvas_plus_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from PyQt6.QtCore import Qt, QPoint, QPointF, QRect
from PyQt6.QtGui import QBrush, QColor, QPen, QPixmap, QPainter, QCursor
from PyQt6.QtWidgets import QGraphicsScene, QGraphicsItem, QGraphicsPixmapItem, QGraphicsLineItem
from airunner.aihandler.logger import Logger

from airunner.aihandler.logger import Logger
from airunner.aihandler.settings_manager import SettingsManager
from airunner.cursors.circle_brush import CircleCursor
from airunner.data.db import session
Expand Down Expand Up @@ -759,4 +759,4 @@ def rotate_90_clockwise(self):
def rotate_90_counterclockwise(self):
if self.current_active_image:
self.current_active_image = self.current_active_image.transpose(Image.ROTATE_90)
self.do_draw()
self.do_draw()
5 changes: 4 additions & 1 deletion src/airunner/widgets/generator_form/generator_form_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,4 +603,7 @@ def update_prompt(self, prompt):
self.ui.prompt.setPlainText(prompt)

def update_negative_prompt(self, prompt):
self.ui.negative_prompt.setPlainText(prompt)
self.ui.negative_prompt.setPlainText(prompt)

def handle_prompt_builder_button_toggled(self, val):
self.app.toggle_prompt_builder(val)
53 changes: 42 additions & 11 deletions src/airunner/widgets/generator_form/templates/generatorform.ui
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<item row="0" column="0">
<widget class="QTabWidget" name="generator_form_tabs">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
Expand Down Expand Up @@ -123,6 +123,20 @@
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="prompt_builder_button">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../resources_light.qrc">
<normaloff>:/icons/light/prompt-editor-icon.svg</normaloff>:/icons/light/prompt-editor-icon.svg</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
Expand Down Expand Up @@ -232,16 +246,16 @@
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<property name="leftMargin">
<number>8</number>
<number>0</number>
</property>
<property name="topMargin">
<number>8</number>
<number>0</number>
</property>
<property name="rightMargin">
<number>8</number>
<number>0</number>
</property>
<property name="bottomMargin">
<number>8</number>
<number>0</number>
</property>
<item row="0" column="0">
<widget class="ChatPromptWidget" name="widget" native="true"/>
Expand Down Expand Up @@ -288,8 +302,8 @@
<slot>handle_interrupt_button_clicked()</slot>
<hints>
<hint type="sourcelabel">
<x>350</x>
<y>1053</y>
<x>349</x>
<y>1052</y>
</hint>
<hint type="destinationlabel">
<x>0</x>
Expand All @@ -304,8 +318,8 @@
<slot>handle_generate_button_clicked()</slot>
<hints>
<hint type="sourcelabel">
<x>39</x>
<y>1053</y>
<x>41</x>
<y>1052</y>
</hint>
<hint type="destinationlabel">
<x>0</x>
Expand Down Expand Up @@ -336,15 +350,31 @@
<slot>handle_negative_prompt_changed()</slot>
<hints>
<hint type="sourcelabel">
<x>270</x>
<y>1024</y>
<x>272</x>
<y>1023</y>
</hint>
<hint type="destinationlabel">
<x>93</x>
<y>0</y>
</hint>
</hints>
</connection>
<connection>
<sender>prompt_builder_button</sender>
<signal>toggled(bool)</signal>
<receiver>generator_form</receiver>
<slot>handle_prompt_builder_button_toggled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>251</x>
<y>49</y>
</hint>
<hint type="destinationlabel">
<x>212</x>
<y>-12</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>handle_prompt_changed()</slot>
Expand All @@ -359,5 +389,6 @@
<slot>save_settings()</slot>
<slot>handle_pipeline_changed(QString)</slot>
<slot>handle_version_changed(QString)</slot>
<slot>handle_prompt_builder_button_toggled(bool)</slot>
</slots>
</ui>
13 changes: 11 additions & 2 deletions src/airunner/widgets/generator_form/templates/generatorform_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ def setupUi(self, generator_form):
self.horizontalLayout_6.setObjectName("horizontalLayout_6")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
self.horizontalLayout_6.addItem(spacerItem)
self.prompt_builder_button = QtWidgets.QPushButton(parent=self.layoutWidget)
self.prompt_builder_button.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/icons/light/prompt-editor-icon.svg"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
self.prompt_builder_button.setIcon(icon)
self.prompt_builder_button.setCheckable(True)
self.prompt_builder_button.setObjectName("prompt_builder_button")
self.horizontalLayout_6.addWidget(self.prompt_builder_button)
self.pushButton = QtWidgets.QPushButton(parent=self.layoutWidget)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout_6.addWidget(self.pushButton)
Expand Down Expand Up @@ -100,7 +108,7 @@ def setupUi(self, generator_form):
self.tab_2 = QtWidgets.QWidget()
self.tab_2.setObjectName("tab_2")
self.gridLayout_5 = QtWidgets.QGridLayout(self.tab_2)
self.gridLayout_5.setContentsMargins(8, 8, 8, 8)
self.gridLayout_5.setContentsMargins(0, 0, 0, 0)
self.gridLayout_5.setObjectName("gridLayout_5")
self.widget = ChatPromptWidget(parent=self.tab_2)
self.widget.setObjectName("widget")
Expand All @@ -109,12 +117,13 @@ def setupUi(self, generator_form):
self.gridLayout_4.addWidget(self.generator_form_tabs, 0, 0, 1, 1)

self.retranslateUi(generator_form)
self.generator_form_tabs.setCurrentIndex(0)
self.generator_form_tabs.setCurrentIndex(1)
self.pushButton.clicked.connect(generator_form.action_clicked_button_save_prompts) # type: ignore
self.interrupt_button.clicked.connect(generator_form.handle_interrupt_button_clicked) # type: ignore
self.generate_button.clicked.connect(generator_form.handle_generate_button_clicked) # type: ignore
self.prompt.textChanged.connect(generator_form.handle_prompt_changed) # type: ignore
self.negative_prompt.textChanged.connect(generator_form.handle_negative_prompt_changed) # type: ignore
self.prompt_builder_button.toggled['bool'].connect(generator_form.handle_prompt_builder_button_toggled) # type: ignore
QtCore.QMetaObject.connectSlotsByName(generator_form)

def retranslateUi(self, generator_form):
Expand Down
95 changes: 76 additions & 19 deletions src/airunner/widgets/image/image_panel_widget.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import threading

from PyQt6.QtCore import QFileSystemWatcher

Expand All @@ -14,29 +15,54 @@ class ImagePanelWidget(BaseWidget):
total_per_page = 50
page_step = 512
last_page = False
sorted_files = []
start = 0
end = 0


def __init__(self, *args, **kwargs):
"""
Initializes the ImagePanelWidget.
Args:
*args: Variable length argument list.
**kwargs: Arbitrary keyword arguments.
Returns:
None
"""
super().__init__(*args, **kwargs)
self.ui.scrollArea.verticalScrollBar().valueChanged.connect(self.handle_scroll)
flowLayout = QFlowLayout()
self.ui.scrollAreaWidgetContents.setLayout(flowLayout)
if self.settings_manager.path_settings.image_path != "":
self.show_files()

# watch the image directory for new files or delete files. if anything changes in the directory call show_files
self.initialize_watcher()
self.load_files()
self.show_files()
self.display_thread = threading.Thread(target=self.display_thumbnails)

def initialize_watcher(self):
"""
Initializes the file system watcher to monitor changes in the image directory.
This method adds the image directory and its subdirectories to the file system watcher,
and connects the directoryChanged and fileChanged signals to their respective handler methods.
"""
self.watcher = QFileSystemWatcher()
# recursively watch the image path
for root, dirs, files in os.walk(self.settings_manager.path_settings.image_path):
self.watcher.addPath(root)

self.watcher.directoryChanged.connect(self.handle_directory_changed)
self.watcher.fileChanged.connect(self.handle_files_changed)

def handle_directory_changed(self, event):
self.show_files()
#self.show_files()
pass

def handle_files_changed(self, event):
self.show_files()
#self.show_files()
pass

def clear_files(self):
self.page = 0
Expand All @@ -47,21 +73,31 @@ def clear_files(self):
widget.deleteLater()

def show_files(self, clear_images=True, reset_scroll_bar=True, show_folders=True):
if clear_images:
self.clear_files()
"""
Displays the files in the image panel widget.
Args:
clear_images (bool, optional): Whether to clear the existing images. Defaults to True.
reset_scroll_bar (bool, optional): Whether to reset the scroll bar position. Defaults to True.
show_folders (bool, optional): Whether to show folders in the file list. Defaults to True.
"""
if reset_scroll_bar:
self.ui.scrollArea.verticalScrollBar().setValue(0)

start = self.page * self.total_per_page
end = start + self.total_per_page

self.start = self.page * self.total_per_page
self.end = self.start + self.total_per_page

self.display_thumbnails()

# recursively crawl self.settings_manager.path_settings.image_path and build a directory of the files sorted by the first folder name within self.settings_manager.path_settings.image_path
# for example, self.settings_manager.path_settings.image_path will have several folders, those should be the key in a dictionary, and the value should be a list of files which is sorted by the most recent first
def load_files(self):
"""
Load files from the specified image path and sort them based on modification time.
Returns:
None
"""
files_in_image_path = os.listdir(self.settings_manager.path_settings.image_path)
sorted_files = {}
# recursively crawl the image path and build a dictionary of the files
for file in files_in_image_path:
if os.path.isdir(os.path.join(self.settings_manager.path_settings.image_path, file)):
sorted_files[file] = []
Expand All @@ -70,21 +106,42 @@ def show_files(self, clear_images=True, reset_scroll_bar=True, show_folders=True

section = "txt2img"
files = sorted_files[section]
# sort the files by the most recent first
files.sort(key=os.path.getmtime, reverse=True)
self.last_page = end >= len(files)
for file in files[start:end]:
self.sorted_files = files

def display_thumbnails(self):
"""
Display thumbnails of images from the sorted_files list within the specified range.
Args:
start (int): The starting index of the range.
end (int): The ending index of the range.
"""
for file in self.sorted_files[self.start:self.end]:
if file.endswith(".png"):
image_widget = ImageWidget(self)
image_widget = ImageWidget(self, is_thumbnail=True)
image_widget.set_image(os.path.join(self.settings_manager.path_settings.image_path, file))
self.ui.scrollAreaWidgetContents.layout().addWidget(image_widget)

def handle_folder_clicked(self, path):
"""
Handles the event when a folder is clicked.
Args:
path (str): The path of the clicked folder.
"""
self.show_files()

def handle_scroll(self, value):
if self.last_page:
return
"""
Handles the scroll event of the image panel widget.
Args:
value (int): The value of the scroll event.
Returns:
None
"""
if value >= self.ui.scrollArea.verticalScrollBar().maximum() - self.page_step + 1:
self.page += 1
self.show_files(clear_images=False, reset_scroll_bar=False, show_folders=False)
Loading

0 comments on commit f2d0c5c

Please sign in to comment.