mirror of
https://github.com/dortania/OpenCore-Legacy-Patcher.git
synced 2026-04-14 20:58:21 +10:00
161 lines
5.9 KiB
Python
161 lines
5.9 KiB
Python
# Generate UI for Building OpenCore
|
|
import wx
|
|
import logging
|
|
import threading
|
|
import traceback
|
|
|
|
from resources import constants
|
|
from resources.build import build
|
|
from resources.wx_gui import (
|
|
gui_main_menu,
|
|
gui_install_oc,
|
|
gui_support
|
|
)
|
|
|
|
|
|
class BuildFrame(wx.Frame):
|
|
"""
|
|
Create a frame for building OpenCore
|
|
Uses a Modal Dialog for smoother transition from other frames
|
|
"""
|
|
def __init__(self, parent: wx.Frame, title: str, global_constants: constants.Constants, screen_location: tuple = None) -> None:
|
|
logging.info("Initializing Build Frame")
|
|
super(BuildFrame, self).__init__(parent, title=title, size=(350, 200), style=wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX))
|
|
gui_support.GenerateMenubar(self, global_constants).generate()
|
|
|
|
self.install_button: wx.Button = None
|
|
self.text_box: wx.TextCtrl = None
|
|
self.frame_modal: wx.Dialog = None
|
|
|
|
self.constants: constants.Constants = global_constants
|
|
self.title: str = title
|
|
self.stock_output = logging.getLogger().handlers[0].stream
|
|
|
|
self.frame_modal = wx.Dialog(self, title=title, size=(400, 200))
|
|
|
|
self._generate_elements(self.frame_modal)
|
|
|
|
if self.constants.update_stage != gui_support.AutoUpdateStages.INACTIVE:
|
|
self.constants.update_stage = gui_support.AutoUpdateStages.BUILDING
|
|
|
|
self.Centre()
|
|
self.frame_modal.ShowWindowModal()
|
|
|
|
self._invoke_build()
|
|
|
|
|
|
def _generate_elements(self, frame: wx.Frame = None) -> None:
|
|
"""
|
|
Generate UI elements for build frame
|
|
|
|
Format:
|
|
- Title label: Build and Install OpenCore
|
|
- Text: Model: {Build or Host Model}
|
|
- Button: Install OpenCore
|
|
- Read-only text box: {empty}
|
|
- Button: Return to Main Menu
|
|
"""
|
|
frame = self if not frame else frame
|
|
|
|
title_label = wx.StaticText(frame, label="Build and Install OpenCore", pos=(-1,5))
|
|
title_label.SetFont(wx.Font(19, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont"))
|
|
title_label.Centre(wx.HORIZONTAL)
|
|
|
|
model_label = wx.StaticText(frame, label=f"Model: {self.constants.custom_model or self.constants.computer.real_model}", pos=(-1,30))
|
|
model_label.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont"))
|
|
model_label.Centre(wx.HORIZONTAL)
|
|
|
|
# Button: Install OpenCore
|
|
install_button = wx.Button(frame, label="🔩 Install OpenCore", pos=(-1, model_label.GetPosition()[1] + model_label.GetSize()[1]), size=(150, 30))
|
|
install_button.Bind(wx.EVT_BUTTON, self.on_install)
|
|
install_button.Centre(wx.HORIZONTAL)
|
|
install_button.Disable()
|
|
self.install_button = install_button
|
|
|
|
# Read-only text box: {empty}
|
|
text_box = wx.TextCtrl(frame, value="", pos=(-1, install_button.GetPosition()[1] + install_button.GetSize()[1] + 10), size=(400, 350), style=wx.TE_READONLY | wx.TE_MULTILINE | wx.TE_RICH2)
|
|
text_box.Centre(wx.HORIZONTAL)
|
|
self.text_box = text_box
|
|
|
|
# Button: Return to Main Menu
|
|
return_button = wx.Button(frame, label="Return to Main Menu", pos=(-1, text_box.GetPosition()[1] + text_box.GetSize()[1] + 5), size=(200, 30))
|
|
return_button.Bind(wx.EVT_BUTTON, self.on_return_to_main_menu)
|
|
return_button.Centre(wx.HORIZONTAL)
|
|
return_button.Disable()
|
|
self.return_button = return_button
|
|
|
|
# Adjust window size to fit all elements
|
|
frame.SetSize((-1, return_button.GetPosition()[1] + return_button.GetSize()[1] + 40))
|
|
|
|
|
|
def _invoke_build(self) -> None:
|
|
"""
|
|
Invokes build function and waits for it to finish
|
|
"""
|
|
while gui_support.PayloadMount(self.constants, self).is_unpack_finished() is False:
|
|
wx.Yield()
|
|
|
|
thread = threading.Thread(target=self._build)
|
|
thread.start()
|
|
|
|
while thread.is_alive():
|
|
wx.Yield()
|
|
|
|
self.return_button.Enable()
|
|
dialog = wx.MessageDialog(
|
|
parent=self,
|
|
message=f"Would you like to install OpenCore now?",
|
|
caption="Finished building your OpenCore configuration!",
|
|
style=wx.YES_NO | wx.ICON_QUESTION
|
|
)
|
|
dialog.SetYesNoLabels("Install to disk", "View build log")
|
|
|
|
self.on_install() if dialog.ShowModal() == wx.ID_YES else self.install_button.Enable()
|
|
|
|
|
|
def _build(self) -> None:
|
|
"""
|
|
Calls build function and redirects stdout to the text box
|
|
"""
|
|
logger = logging.getLogger()
|
|
logger.addHandler(gui_support.ThreadHandler(self.text_box))
|
|
try:
|
|
build.BuildOpenCore(self.constants.custom_model or self.constants.computer.real_model, self.constants)
|
|
except:
|
|
logging.error("An internal error occurred while building:\n")
|
|
logging.error(traceback.format_exc())
|
|
logger.removeHandler(logger.handlers[2])
|
|
|
|
|
|
def on_return_to_main_menu(self, event: wx.Event = None) -> None:
|
|
"""
|
|
Return to main menu
|
|
"""
|
|
self.frame_modal.Hide()
|
|
main_menu_frame = gui_main_menu.MainFrame(
|
|
None,
|
|
title=self.title,
|
|
global_constants=self.constants,
|
|
screen_location=self.GetScreenPosition()
|
|
)
|
|
main_menu_frame.Show()
|
|
self.frame_modal.Destroy()
|
|
self.Destroy()
|
|
|
|
|
|
def on_install(self, event: wx.Event = None) -> None:
|
|
"""
|
|
Launch install frame
|
|
"""
|
|
self.frame_modal.Destroy()
|
|
self.Destroy()
|
|
install_oc_frame = gui_install_oc.InstallOCFrame(
|
|
None,
|
|
title=self.title,
|
|
global_constants=self.constants,
|
|
screen_location=self.GetScreenPosition()
|
|
)
|
|
install_oc_frame.Show()
|
|
|
|
|