Skip to content

Commit

Permalink
WIP: new GUI and trying to intercept logs to display in window
Browse files Browse the repository at this point in the history
  • Loading branch information
fe-art committed Sep 10, 2024
1 parent 5c044d0 commit e5f654b
Show file tree
Hide file tree
Showing 2 changed files with 354 additions and 2 deletions.
339 changes: 339 additions & 0 deletions clashroyalebuildabot/gui/new_gui.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,339 @@
import logging

from PyQt6.QtWidgets import (
QApplication,
QMainWindow,
QWidget,
QVBoxLayout,
QHBoxLayout,
QPushButton,
QLabel,
QTextEdit,
QFrame,
QTabWidget,
QCheckBox,
QLineEdit,
QComboBox,
QFormLayout,
QDoubleSpinBox,
QGroupBox,
QGridLayout,
)
from PyQt6.QtGui import QFont
from PyQt6.QtCore import Qt, QMetaObject, Q_ARG
from threading import Thread


from clashroyalebuildabot import Bot
from clashroyalebuildabot.actions.generic.action import Action
import sys

class QTextEditLogger(logging.Handler):
def __init__(self, text_edit):
super().__init__()
self.text_edit = text_edit

def emit(self, record):
log_entry = self.format(record)
QMetaObject.invokeMethod(
self.text_edit,
"append",
Qt.ConnectionType.QueuedConnection,
Q_ARG(str, log_entry)
)

class MainWindow(QMainWindow):
def __init__(self, config, actions):
super().__init__()

self.config = config
self.actions = actions
self.bot = None
self.bot_thread = None
self.is_running = False



self.setWindowTitle("Clash Royale Build-A-Bot")
self.setGeometry(100, 100, 900, 600)

main_widget = QWidget(self)
self.setCentralWidget(main_widget)
main_layout = QVBoxLayout(main_widget)

top_bar = QFrame()
top_bar.setStyleSheet("background-color: #1E272E;")
top_bar_layout = QHBoxLayout(top_bar)

left_layout = QVBoxLayout()
left_layout.setAlignment(Qt.AlignmentFlag.AlignTop)

server_name = QLabel("Clash Royale Build-A-Bot")
server_name.setStyleSheet("font-weight: bold; font-size: 16pt; color: white;")
left_layout.addWidget(server_name)

server_details = QLabel('<a href="https://github.com/Pbatch/ClashRoyaleBuildABot">https://github.com/Pbatch/ClashRoyaleBuildABot</a>')
server_details.setOpenExternalLinks(True)
server_details.setStyleSheet("color: #57A6FF;")
left_layout.addWidget(server_details)

self.server_id_label = QLabel("Status")
self.server_id_label.setStyleSheet("color: #999;")
left_layout.addWidget(self.server_id_label)

port_link = QLabel('<a href="http://localhost:5555" style="color: #57A6FF;">127.0.0.1:5555</a>')
port_link.setOpenExternalLinks(True)
left_layout.addWidget(port_link)

top_bar_layout.addLayout(left_layout)

right_layout = QVBoxLayout()
right_layout.setAlignment(Qt.AlignmentFlag.AlignRight)

button_layout = QHBoxLayout()
button_layout.setAlignment(Qt.AlignmentFlag.AlignRight)

self.start_stop_button = QPushButton("▶")
self.start_stop_button.setFont(QFont("Arial", 18))
self.start_stop_button.setStyleSheet("""
QPushButton {
background-color: #4B6EAF;
color: white;
min-width: 32px;
max-width: 32px;
min-height: 32px;
max-height: 32px;
border-radius: 5px;
}
QPushButton:hover {
background-color: #5C7EBF;
}
""")
self.start_stop_button.clicked.connect(self.toggle_start_stop)

restart_button = QPushButton("↻")
restart_button.setFont(QFont("Arial", 18))
restart_button.setStyleSheet("""
QPushButton {
background-color: #4B6EAF;
color: white;
min-width: 32px;
max-width: 32px;
min-height: 32px;
max-height: 32px;
border-radius: 5px;
}
QPushButton:hover {
background-color: #5C7EBF;
}
""")
restart_button.clicked.connect(self.restart_bot)

delete_button = QPushButton("🗑")
delete_button.setFont(QFont("Arial", 18))
delete_button.setStyleSheet("""
QPushButton {
background-color: #e04f5f;
color: white;
min-width: 32px;
max-width: 32px;
min-height: 32px;
max-height: 32px;
border-radius: 5px;
}
QPushButton:hover {
background-color: #F06F6F;
}
""")

button_layout.addWidget(self.start_stop_button)
button_layout.addWidget(restart_button)
button_layout.addWidget(delete_button)

top_bar_layout.addStretch()
top_bar_layout.addLayout(right_layout)
top_bar_layout.addLayout(button_layout)

main_layout.addWidget(top_bar)

tab_widget = QTabWidget()
tab_widget.setStyleSheet("""
QTabWidget::pane { border: 0; }
QTabBar::tab {
background: #333;
color: white;
padding: 8px;
margin-bottom: -1px;
}
QTabBar::tab:selected {
background: #1E272E;
border-bottom: 2px solid #57A6FF;
}
""")

logs_tab = QWidget()
logs_layout = QVBoxLayout(logs_tab)
self.log_display = QTextEdit()
self.log_display.setReadOnly(True)
self.log_display.setText("Lorem Ipsum - Press Start for Text")
self.log_display.setStyleSheet("background-color: #1e1e1e; color: lightgrey; font-family: monospace;")
logs_layout.addWidget(self.log_display)
tab_widget.addTab(logs_tab, "Logs")

settings_tab = QWidget()
settings_layout = QGridLayout(settings_tab)

bot_group = QGroupBox("Bot ")
bot_layout = QFormLayout()
self.log_level_dropdown = QComboBox()
self.log_level_dropdown.addItems(["INFO", "DEBUG", "WARNING", "ERROR", "CRITICAL"])
bot_layout.addRow("Log Level:", self.log_level_dropdown)

self.adb_ip_input = QLineEdit()
self.adb_ip_input.setPlaceholderText("127.0.0.1")
self.device_serial_input = QLineEdit()
self.device_serial_input.setPlaceholderText("emulator-5554")
bot_layout.addRow("ADB IP Address:", self.adb_ip_input)
bot_layout.addRow("Device Serial:", self.device_serial_input)

bot_group.setLayout(bot_layout)

visuals_group = QGroupBox("Visuals Settings")
visuals_layout = QFormLayout()
self.save_labels_checkbox = QCheckBox("Save labels")
self.save_images_checkbox = QCheckBox("Save images")
self.show_images_checkbox = QCheckBox("Show images")
visuals_layout.addRow(self.save_labels_checkbox)
visuals_layout.addRow(self.save_images_checkbox)
visuals_layout.addRow(self.show_images_checkbox)
visuals_group.setLayout(visuals_layout)

ingame_group = QGroupBox("Ingame Settings")
ingame_layout = QFormLayout()

self.play_action_delay_input = QDoubleSpinBox()
self.play_action_delay_input.setRange(0.1, 5.0)
self.play_action_delay_input.setSingleStep(0.1)
self.play_action_delay_input.setValue(0.5)
ingame_layout.addRow("Action Delay (sec):", self.play_action_delay_input)

self.load_deck_checkbox = QCheckBox("Create deck code on game start")
ingame_layout.addRow(self.load_deck_checkbox)

self.auto_start_game_checkbox = QCheckBox("Auto start game")
ingame_layout.addRow(self.auto_start_game_checkbox)

ingame_group.setLayout(ingame_layout)



settings_layout.addWidget(bot_group, 0, 0)
settings_layout.addWidget(visuals_group, 1, 0)
settings_layout.addWidget(ingame_group, 0, 1, 2, 1)

tab_widget.addTab(settings_tab, "Settings")

stats_tab = QWidget()
tab_widget.addTab(stats_tab, "Stats")

main_layout.addWidget(tab_widget)

self.setStyleSheet("""
QMainWindow {
background-color: #0D1117;
}
QLabel {
color: white;
padding: 2px;
}
QPushButton {
border: none;
padding: 8px;
}
QFrame {
background-color: #1E272E;
}
""")



def toggle_start_stop(self):
if self.is_running:
self.stop_bot()
else:
self.start_bot()

def start_bot(self):
if self.is_running:
return
self.update_config()
self.is_running = True
self.bot_thread = Thread(target=self.bot_task)
self.bot_thread.daemon = True
self.bot_thread.start()
self.start_stop_button.setText("■")
self.start_stop_button.setFont(QFont("Arial", 18))
self.start_stop_button.setStyleSheet("""
QPushButton {
background-color: #e04f5f;
color: white;
min-width: 32px;
max-width: 32px;
min-height: 32px;
max-height: 32px;
border-radius: 5px;
}
QPushButton:hover {
background-color: #F06F6F;
}
""")
self.server_id_label.setText("Status - Running")
self.append_log("Bot started")

def stop_bot(self):
if not self.bot:
return
self.bot.stop()
self.is_running = False
self.start_stop_button.setText("▶")
self.start_stop_button.setFont(QFont("Arial", 18))
self.start_stop_button.setStyleSheet("""
QPushButton {
background-color: #4B6EAF;
color: white;
min-width: 32px;
max-width: 32px;
min-height: 32px;
max-height: 32px;
border-radius: 5px;
}
QPushButton:hover {
background-color: #5C7EBF;
}
""")
self.server_id_label.setText("Status - Stopped")
self.append_log("Bot stopped")

def restart_bot(self):
if self.is_running:
self.stop_bot()
self.update_config()
self.start_bot()

def update_config(self):
self.config["visuals"]["save_labels"] = self.save_labels_checkbox.isChecked()
self.config["visuals"]["save_images"] = self.save_images_checkbox.isChecked()
self.config["visuals"]["show_images"] = self.show_images_checkbox.isChecked()
self.config["bot"]["load_deck"] = self.load_deck_checkbox.isChecked()
self.config["bot"]["auto_start_game"] = self.auto_start_game_checkbox.isChecked()
self.config["bot"]["log_level"] = self.log_level_dropdown.currentText()
self.config["ingame"]["play_action"] = float(self.play_action_delay_input.value())
self.config["adb"]["ip"] = self.adb_ip_input.text()
self.config["adb"]["device_serial"] = self.device_serial_input.text()

def bot_task(self):
self.bot = Bot(actions=self.actions, config=self.config)
self.bot.run()

def append_log(self, message):
self.log_display.append(message)
17 changes: 15 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
import os
from datetime import datetime
import signal
Expand All @@ -6,6 +7,7 @@
import time

import yaml
from PyQt6.QtWidgets import QApplication
from loguru import logger

from clashroyalebuildabot.actions import ArchersAction
Expand All @@ -19,6 +21,7 @@
from clashroyalebuildabot.bot import Bot
from clashroyalebuildabot.constants import SRC_DIR
from clashroyalebuildabot.gui.gui import Gui
from clashroyalebuildabot.gui.new_gui import MainWindow, QTextEditLogger

start_time = datetime.now()

Expand Down Expand Up @@ -65,8 +68,18 @@ def main():

# GUI MODE
if config["bot"]["enable_gui"]:
gui = Gui(config=config, actions=actions)
gui.run()
# gui = Gui(config=config, actions=actions)
# gui.run()
app = QApplication(sys.argv)
window = MainWindow(config, actions)

# Create and add the custom logging handler
log_handler = QTextEditLogger(window.log_display)
log_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
logger.add(log_handler)

window.show()
sys.exit(app.exec())
else:
# REGULAR MODE
bot = Bot(actions=actions, config=config)
Expand Down

0 comments on commit e5f654b

Please sign in to comment.