101 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Python
		
	
	
| from PySide6 import QtWidgets, QtCore, QtGui
 | |
| import util
 | |
| 
 | |
| app = QtWidgets.QApplication([])
 | |
| 
 | |
| #TODO: Implement separate editor, terminal and main_window classes using Window as a parent
 | |
| 
 | |
| class Window(QtWidgets.QMainWindow):
 | |
|     def __init__(self, size=(640, 480), title="Concorde", on_resize=lambda event: None):
 | |
|         super().__init__()
 | |
|         self.setWindowTitle(title)
 | |
|         self.resize(size[0], size[1])
 | |
|         self.__on_resize = on_resize
 | |
| 
 | |
|     def __del__(self):
 | |
|         #TODO: whatever needs to be done here
 | |
|         pass
 | |
| 
 | |
|     def set_title(self, title):
 | |
|         self.setWindowTitle(title)
 | |
| 
 | |
|     def get_size(self):
 | |
|         #TODO: implement
 | |
|         util.warn("Not implemented!")
 | |
|         return None
 | |
| 
 | |
|     def set_size(self, size_x, size_y):
 | |
|         self.resize(size_x, size_y)
 | |
| 
 | |
|     def on_resize(self, function):
 | |
|         self.__on_resize = function
 | |
| 
 | |
|     def update_menus(self, menu_dict, menu=None):
 | |
|         # if not a sub menu
 | |
|         if menu == None:
 | |
|             menu = self.menuBar()
 | |
|             menu.clear()
 | |
| 
 | |
|         #Looping through entire menu_dict
 | |
|         for entry in menu_dict:
 | |
|             # inactive or separator
 | |
|             if menu_dict[entry] == None:
 | |
|                 # determine if entry is a separator or an inactive menu item
 | |
|                 if type(entry) == int:
 | |
|                     menu.addSeparator()
 | |
|                 else:
 | |
|                     menu_item = menu.addAction(entry)
 | |
|                     menu_item.setEnabled(False)
 | |
|             # sub menus
 | |
|             if type(menu_dict[entry]) == dict:
 | |
|                 submenu = menu.addMenu(entry)
 | |
|                 # recurse because sub menus may have sub menus
 | |
|                 self.update_menus(menu_dict[entry], menu=submenu)
 | |
|             # ordinary menu entries
 | |
|             if callable(menu_dict[entry]):
 | |
|                 menu_item = menu.addAction(entry)
 | |
|                 menu_item.triggered.connect(menu_dict[entry])
 | |
| 
 | |
|     # Toolkit specific! Do not use outside gui_handler.
 | |
|     def resizeEvent(self, event):
 | |
|         self.__on_resize(event)
 | |
| 
 | |
| 
 | |
| class Editor(Window):
 | |
|     def __init__(self, size=(640, 480)):
 | |
|         super().__init__(size, "Editor")
 | |
| 
 | |
|         #TODO: Figure out a way to do the fucking line numbers
 | |
| 
 | |
|         #Text Editor
 | |
|         self.text_edit = QtWidgets.QPlainTextEdit()
 | |
|         self.text_edit.setFrameStyle(QtWidgets.QFrame.NoFrame)
 | |
|         self.text_edit.setWordWrapMode(QtGui.QTextOption.NoWrap)
 | |
|         
 | |
|         self.tabs = QtWidgets.QTabWidget()
 | |
|         self.tabs.addTab(self.text_edit, "untitled")
 | |
|         self.setCentralWidget(self.tabs)
 | |
| 
 | |
| class Message(QtWidgets.QMessageBox):
 | |
|     def __init__(self, title, text):
 | |
|         super().__init__()
 | |
| 
 | |
|         self.setWindowTitle(title)
 | |
|         self.setText(text)
 | |
|         self.setStandardButtons(QtWidgets.QMessageBox.Ok)
 | |
|         self.exec()
 | |
| 
 | |
| 
 | |
| #TODO: This needs to run in a thread but Qt really doesn't want it to. There are two ways around this:
 | |
| #   - create the QtWidgets.QApplication inside a thread and run all QT stuff inside that thread
 | |
| #   - make a generic wrapper for window mainloop that will always run in the main thread while the actual main control flow of the program gets moved to another thread
 | |
| # There are some issues with these workarounds though; mainly that QT isn't thread safe.
 | |
| # I really want to keep QT running in its own thread because I want to retain the ability to arbitrarily spawn and manipulate windows while other windows are running.
 | |
| # Another issue that is probably easily worked around / fixed is that app.exec() will return once all running windows are closed.
 | |
| # Idea for a workaround for both:
 | |
| #   Maybe Qt has scheduled events in which case a scheduled polling event could run a function inside the Qt thread that fetches commands and executes them.
 | |
| #   This could work by passing (lambda) functions through a Communication object.
 | |
| #UPDATE: Tried implementing both approaches, neither worked. :(
 | |
| def fixme_window_mainloop_workaround_to_just_get_a_window_started_really_should_not_be_implemented_this_way_for_reasons_stated_in_the_comment_above_the_definition_of_this_function():
 | |
|     app.exec()
 |