from ttkbootstrap import Style
import webbrowser as wb
from pathlib import Path
from tkinter import Frame, Menu, filedialog as fd, messagebox as mb
import scripts.RecentsManager as RecentsManager
# VirtualRocks source is released under GPL-3.0-only or GPL-3.0-or-later
[docs]
class AppWindow(Frame):
def __init__(self, parent, controller):
"""
`AppWindow` is the class that inherits from `Tkinter.Frame`. It has subclasses
:ref:`PipelineGUI <pipelineGUI>` and :ref:`StartGUI <startGUI>`. It handles elements that
remain consistent throughout the GUI, including the menu bar, the light and dark styling,
and the functionality for opening new projects, existing projects, and recent projects.
Args:
parent (tkinter container): passed from :ref:`main <main>` to make the tkinter frame.
controller (:ref:`main <main>`\*): a reference to main.
"""
Frame.__init__(self, parent)
self.controller = controller
self._create_menu()
# Setup method for top menu bar
# Event handler for the "new project" menu item
# Should open a dialogue asking the user to selct a working directory
# Then call controllers new_project method
[docs]
def new_project(self):
"""
Event handler for opening new projects. It handles the "New" menu item under then "File"
menu tab and the "New Project" button on the start screen on the Tk app. It opens a dialog
that prompts the user to select a workspace/working directory. Once the user selects a
valid directory, it calls the controller's `new_project` method in :ref:`main <main>`.
"""
projdir = fd.askdirectory(title='Select Workspace', initialdir='/home/')
if not projdir:
return
if ' ' in projdir:
print("Path must not contain white spaces")
mb.showerror("Paths cannot contain whitespace ")
return
self.controller.new_project(projdir)
# Event handler for the "open project" menu item
# Should open a dialogue asking the user to selct a project file
# Then call controllers open_project method
[docs]
def open_project(self, projfile=None):
"""
Event handler for opening existing projects. It handles the "Open" menu item and the items
under the "Open Recent..." cascade in the `File` menu tab, and the "Open Project" button on
the start screen of the Tk app. If a project file directory is passed or the user selects a
file directory using the dialog, then the function calls the controller's `open_project`
method in :ref:`main <main>` with the project file directory.
Args:
projfile (pathlib.Path): optional path to a .vrp file.
"""
if not projfile:
projfile = fd.askopenfilename(filetypes=[('Choose a project (.vrp) file', '*.vrp')])
if not projfile:
return
self.controller.open_project(Path(projfile))
[docs]
def open_recent(self,recent):
"""
Event handler for the menu items representing files in the recents dictionary under the
"Open Recents..." cascade in the "File" menu tab in the menu bar. If the project exists,
then it's passed to `open_project`.
Args:
recent (pathlib.Path): a string of the path of the recent file to open.
"""
try:
print("opening recent: " + str(recent))
if not recent:
return
self.open_project(recent)
except Exception as e:
print(e)
print("Could not find project")
# Handler for setting dark mode
# changes theme to a dark theme
# might be worth adding some flag so that we don't have to switch if we already have one style.
[docs]
def _start_darkmode(self):
"""
Handler for setting the app to dark mode.
Uses `ttkbootstrap <https://ttkbootstrap.readthedocs.io/en/latest/themes/>`_ theme
`"darkly"`. If the app isn't already in dark mode, it changes the style and sets
:ref:`main <main>`'s `styleflag`.
"""
if (self.controller.styleflag == "dark"):
return
self.controller.style = Style("darkly")
self.controller.styleflag = "dark"
self.controller.init_style()
[docs]
def _start_lightmode(self):
"""
Handler for setting the app to light mode.
Uses `ttkbootstrap <https://ttkbootstrap.readthedocs.io/en/latest/themes/>`_ theme
`"lumen"`. If the app isn't already in light mode, it changes the style and sets
:ref:`main <main>`'s `styleflag`.
"""
if (self.controller.styleflag == "light"):
return
self.controller.style = Style("lumen")
self.controller.styleflag = "light"
self.controller.init_style()
# Handler for opening the help menu/docs
# can take argument to specify which page to open if it isn't the main page.