forked from clan/clan-core
remove window based navigation
This commit is contained in:
parent
ffd80b77b3
commit
3f88bb7a83
@ -2,11 +2,14 @@
|
|||||||
import argparse
|
import argparse
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import os
|
||||||
|
|
||||||
import gi
|
import gi
|
||||||
from clan_cli import vms
|
from clan_cli import vms
|
||||||
|
|
||||||
from clan_vm_manager.windows.flash import FlashUSBWindow
|
from clan_vm_manager.views.list import ClanList
|
||||||
|
|
||||||
|
# from clan_vm_manager.windows.flash import FlashUSBWindow
|
||||||
|
|
||||||
gi.require_version("Gtk", "4.0")
|
gi.require_version("Gtk", "4.0")
|
||||||
gi.require_version("Adw", "1")
|
gi.require_version("Adw", "1")
|
||||||
@ -14,26 +17,19 @@ gi.require_version("Adw", "1")
|
|||||||
import multiprocessing as mp
|
import multiprocessing as mp
|
||||||
|
|
||||||
from clan_cli.clan_uri import ClanURI
|
from clan_cli.clan_uri import ClanURI
|
||||||
from gi.repository import Gio, Gtk, Adw
|
from gi.repository import Adw, Gio, Gtk, Gdk
|
||||||
|
|
||||||
from .constants import constants
|
from .constants import constants
|
||||||
from .errors.show_error import show_error_dialog
|
from .errors.show_error import show_error_dialog
|
||||||
from .executor import ProcessManager
|
from .executor import ProcessManager
|
||||||
from .interfaces import Callbacks, InitialFlashValues, InitialJoinValues
|
|
||||||
from .windows.join import JoinWindow
|
|
||||||
from .windows.overview import OverviewWindow
|
|
||||||
|
|
||||||
|
# from .windows.join import JoinWindow
|
||||||
@dataclass
|
# from .windows.overview import OverviewWindow
|
||||||
class ClanWindows:
|
|
||||||
join: type[JoinWindow]
|
|
||||||
overview: type[OverviewWindow]
|
|
||||||
flash_usb: type[FlashUSBWindow]
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ClanConfig:
|
class ClanConfig:
|
||||||
initial_window: str
|
initial_view: str
|
||||||
url: ClanURI | None
|
url: ClanURI | None
|
||||||
|
|
||||||
|
|
||||||
@ -43,30 +39,53 @@ def on_except(error: Exception, proc: mp.process.BaseProcess) -> None:
|
|||||||
|
|
||||||
|
|
||||||
class MainWindow(Adw.ApplicationWindow):
|
class MainWindow(Adw.ApplicationWindow):
|
||||||
def __init__(self, config: ClanConfig) -> None:
|
def __init__(self, app: Gtk.Application, config: ClanConfig) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.set_title("Clan Manager")
|
self.set_application(app)
|
||||||
view = Adw.ToolbarView()
|
|
||||||
header = Adw.HeaderBar()
|
|
||||||
view.add_top_bar(header)
|
|
||||||
|
|
||||||
label = Gtk.Label.new("testlabel")
|
self.set_title("Clan Manager")
|
||||||
view.set_content(label)
|
|
||||||
|
# ToolbarView is the root layout.
|
||||||
|
# A Widget containing a page, as well as top and/or bottom bars.
|
||||||
|
# See https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.ToolbarView.html
|
||||||
|
self.view = Adw.ToolbarView()
|
||||||
|
self.header = Adw.HeaderBar()
|
||||||
|
self.view.add_top_bar(self.header)
|
||||||
|
|
||||||
|
|
||||||
self.set_content(view)
|
clan_list = ClanList(
|
||||||
|
app = app
|
||||||
|
)
|
||||||
|
|
||||||
|
self.stack = Adw.ViewStack()
|
||||||
|
self.stack.add_titled(
|
||||||
|
clan_list, "list", "list"
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
class Application(Gtk.Application):
|
self.view.set_content(self.stack)
|
||||||
|
|
||||||
|
self.set_content(self.view)
|
||||||
|
|
||||||
|
|
||||||
|
# AdwApplication
|
||||||
|
# - handles library initialization by calling adw_init() in the default GApplication::startup signal handle
|
||||||
|
# - automatically loads stylesheets (style.css, style-dark.css, ...)
|
||||||
|
# - ...
|
||||||
|
# More see: https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/class.Application.html
|
||||||
|
class Application(Adw.Application):
|
||||||
def __init__(self, config: ClanConfig) -> None:
|
def __init__(self, config: ClanConfig) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
application_id=constants["APPID"], flags=Gio.ApplicationFlags.FLAGS_NONE
|
application_id=constants["APPID"], flags=Gio.ApplicationFlags.FLAGS_NONE
|
||||||
)
|
)
|
||||||
# TODO:
|
self.config = config
|
||||||
# self.init_style()
|
|
||||||
|
|
||||||
self.window = MainWindow(config)
|
|
||||||
self.proc_manager = ProcessManager()
|
self.proc_manager = ProcessManager()
|
||||||
|
|
||||||
|
# self.connect("activate", self.do_activate)
|
||||||
self.connect("shutdown", self.on_shutdown)
|
self.connect("shutdown", self.on_shutdown)
|
||||||
|
# constants
|
||||||
|
# breakpoint()
|
||||||
|
|
||||||
|
|
||||||
def on_shutdown(self, app: Gtk.Application) -> None:
|
def on_shutdown(self, app: Gtk.Application) -> None:
|
||||||
print("Shutting down")
|
print("Shutting down")
|
||||||
@ -115,25 +134,22 @@ class Application(Gtk.Application):
|
|||||||
|
|
||||||
|
|
||||||
def do_activate(self) -> None:
|
def do_activate(self) -> None:
|
||||||
win = self.props.active_window
|
self.init_style()
|
||||||
if not win:
|
window = MainWindow(app=self,config=self.config)
|
||||||
win = self.window
|
window.set_default_size(980,650)
|
||||||
win.set_application(self)
|
window.present()
|
||||||
win.present()
|
|
||||||
|
|
||||||
# TODO: For css styling
|
# TODO: For css styling
|
||||||
def init_style(self) -> None:
|
def init_style(self) -> None:
|
||||||
pass
|
resource_path = Path(__file__).parent / "style.css"
|
||||||
# css_provider = Gtk.CssProvider()
|
css_provider = Gtk.CssProvider()
|
||||||
# css_provider.load_from_resource(constants['RESOURCEID'] + '/style.css')
|
css_provider.load_from_path(str(resource_path))
|
||||||
# screen = Gdk.Screen.get_default()
|
Gtk.StyleContext.add_provider_for_display(Gdk.Display.get_default(), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
|
||||||
# style_context = Gtk.StyleContext()
|
|
||||||
# style_context.add_provider_for_screen(screen, css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
|
|
||||||
|
|
||||||
|
|
||||||
def show_join(args: argparse.Namespace) -> None:
|
def show_join(args: argparse.Namespace) -> None:
|
||||||
app = Application(
|
app = Application(
|
||||||
config=ClanConfig(url=args.clan_uri, initial_window="join"),
|
config=ClanConfig(url=args.clan_uri, initial_view="join"),
|
||||||
)
|
)
|
||||||
return app.run()
|
return app.run()
|
||||||
|
|
||||||
@ -145,7 +161,7 @@ def register_join_parser(parser: argparse.ArgumentParser) -> None:
|
|||||||
|
|
||||||
def show_overview(args: argparse.Namespace) -> None:
|
def show_overview(args: argparse.Namespace) -> None:
|
||||||
app = Application(
|
app = Application(
|
||||||
config=ClanConfig(url=None, initial_window="overview"),
|
config=ClanConfig(url=None, initial_view="list"),
|
||||||
)
|
)
|
||||||
return app.run()
|
return app.run()
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import gi
|
|||||||
gi.require_version("Gtk", "4.0")
|
gi.require_version("Gtk", "4.0")
|
||||||
gi.require_version('Adw', '1')
|
gi.require_version('Adw', '1')
|
||||||
from clan_cli.errors import ClanError
|
from clan_cli.errors import ClanError
|
||||||
from gi.repository import Gtk, Adw
|
from gi.repository import Adw
|
||||||
|
|
||||||
Severity = Literal["Error"] | Literal["Warning"] | Literal["Info"] | str
|
Severity = Literal["Error"] | Literal["Warning"] | Literal["Info"] | str
|
||||||
|
|
||||||
|
27
pkgs/clan-vm-manager/clan_vm_manager/style.css
Normal file
27
pkgs/clan-vm-manager/clan_vm_manager/style.css
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
window {
|
||||||
|
/* Set consistent border radius */
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 300;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
row {
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
stack {
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
@ -16,7 +16,7 @@ gi.require_version("Gtk", "4.0")
|
|||||||
gi.require_version("Adw", "1")
|
gi.require_version("Adw", "1")
|
||||||
|
|
||||||
|
|
||||||
from gi.repository import GdkPixbuf, Gio, Gtk, Adw
|
from gi.repository import GdkPixbuf, Gio, Gtk
|
||||||
|
|
||||||
|
|
||||||
class Trust(Gtk.Box):
|
class Trust(Gtk.Box):
|
@ -1,9 +1,13 @@
|
|||||||
from typing import Callable, Any
|
from collections.abc import Callable
|
||||||
|
|
||||||
from gi.repository import Gdk, GdkPixbuf, Gtk, Adw
|
|
||||||
|
|
||||||
from ..interfaces import Callbacks
|
import gi
|
||||||
from ..models import VMBase, VMStatus
|
gi.require_version("Adw", "1")
|
||||||
|
from gi.repository import Adw, GdkPixbuf, Gio, GObject, Gtk
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from ..models import VMBase, get_initial_vms
|
||||||
|
|
||||||
# from .context_menu import VmMenu
|
# from .context_menu import VmMenu
|
||||||
|
|
||||||
|
|
||||||
@ -66,6 +70,21 @@ class ClanEdit(Gtk.Box):
|
|||||||
self.show_list()
|
self.show_list()
|
||||||
|
|
||||||
|
|
||||||
|
class VMListItem(GObject.Object):
|
||||||
|
def __init__(self, data: VMBase) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.data = data
|
||||||
|
|
||||||
|
class ClanIcon(Gtk.Box):
|
||||||
|
def __init__(self, icon_path: Path) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.append(
|
||||||
|
GdkPixbuf.Pixbuf.new_from_file_at_scale(
|
||||||
|
filename=icon_path, width=64, height=64, preserve_aspect_ratio=True
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ClanList(Gtk.Box):
|
class ClanList(Gtk.Box):
|
||||||
"""
|
"""
|
||||||
The ClanList
|
The ClanList
|
||||||
@ -83,132 +102,67 @@ class ClanList(Gtk.Box):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
remount_list: Callable[[], None],
|
app: Adw.Application
|
||||||
remount_edit: Callable[[], None],
|
|
||||||
set_selected: Callable[[VMBase | None], None],
|
|
||||||
cbs: Callbacks,
|
|
||||||
selected_vm: VMBase | None,
|
|
||||||
vms: list[VMBase],
|
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(orientation=Gtk.Orientation.VERTICAL, )
|
super().__init__(orientation=Gtk.Orientation.VERTICAL)
|
||||||
|
self.application = app
|
||||||
|
|
||||||
self.remount_edit_view = remount_edit
|
boxed_list = Gtk.ListBox()
|
||||||
self.remount_list_view = remount_list
|
boxed_list.set_selection_mode(Gtk.SelectionMode.NONE)
|
||||||
self.set_selected = set_selected
|
boxed_list.add_css_class("boxed-list")
|
||||||
self.cbs = cbs
|
|
||||||
self.show_join = cbs.show_join
|
|
||||||
|
|
||||||
self.selected_vm: VMBase | None = selected_vm
|
def create_widget(item: VMListItem) -> Gtk.Widget:
|
||||||
|
print("Creating", item.data)
|
||||||
|
vm = item.data
|
||||||
|
# Not displayed; Can be used as id.
|
||||||
|
row = Adw.SwitchRow()
|
||||||
|
row.set_name(vm.url)
|
||||||
|
|
||||||
|
row.set_title(vm.name)
|
||||||
|
row.set_title_lines(1)
|
||||||
|
|
||||||
# self.toolbar = ClanListToolbar(
|
row.set_subtitle(vm.url)
|
||||||
# selected_vm=selected_vm,
|
row.set_subtitle_lines(1)
|
||||||
# on_start_clicked=self.on_start_clicked,
|
|
||||||
# on_stop_clicked=self.on_stop_clicked,
|
|
||||||
# on_edit_clicked=self.on_edit_clicked,
|
|
||||||
# on_join_clan_clicked=self.on_join_clan_clicked,
|
|
||||||
# on_flash_clicked=self.on_flash_clicked,
|
|
||||||
# )
|
|
||||||
# self.add(self.toolbar)
|
|
||||||
|
|
||||||
self.append(
|
avatar = Adw.Avatar()
|
||||||
ClanListView(
|
avatar.set_text(vm.name)
|
||||||
vms=vms,
|
avatar.set_show_initials(True)
|
||||||
on_select_row=self.on_select_vm,
|
avatar.set_size(50)
|
||||||
selected_vm=selected_vm,
|
# (GdkPixbuf.Pixbuf.new_from_file_at_scale(
|
||||||
on_double_click=self.on_double_click,
|
# filename=vm.icon,
|
||||||
)
|
# width=512,
|
||||||
)
|
# height=512,
|
||||||
|
# preserve_aspect_ratio=True,
|
||||||
def on_flash_clicked(self, widget: Gtk.Widget) -> None:
|
# ))
|
||||||
self.cbs.show_flash()
|
|
||||||
|
# Gtk.Image.new_from_pixbuf(
|
||||||
def on_double_click(self, vm: VMBase) -> None:
|
|
||||||
self.on_start_clicked(self)
|
# )
|
||||||
|
row.add_prefix(avatar)
|
||||||
def on_start_clicked(self, widget: Gtk.Widget) -> None:
|
|
||||||
if self.selected_vm:
|
|
||||||
self.cbs.spawn_vm(self.selected_vm.url, self.selected_vm._flake_attr)
|
|
||||||
# Call this to reload
|
|
||||||
self.remount_list_view()
|
|
||||||
|
|
||||||
def on_stop_clicked(self, widget: Gtk.Widget) -> None:
|
|
||||||
if self.selected_vm:
|
|
||||||
self.cbs.stop_vm(self.selected_vm.url, self.selected_vm._flake_attr)
|
|
||||||
self.remount_list_view()
|
|
||||||
|
|
||||||
def on_join_clan_clicked(self, widget: Gtk.Widget) -> None:
|
|
||||||
self.show_join()
|
|
||||||
|
|
||||||
def on_edit_clicked(self, widget: Gtk.Widget) -> None:
|
|
||||||
self.remount_edit_view()
|
|
||||||
|
|
||||||
def on_select_vm(self, vm: VMBase) -> None:
|
|
||||||
# self.toolbar.set_selected_vm(vm)
|
|
||||||
|
|
||||||
self.set_selected(vm)
|
|
||||||
self.selected_vm = vm
|
|
||||||
|
|
||||||
|
|
||||||
class ClanListToolbar(Gtk.Box):
|
row.connect("notify::active", self.on_row_toggle)
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
*,
|
|
||||||
selected_vm: VMBase | None,
|
|
||||||
on_start_clicked: Callable[[Gtk.Widget], None],
|
|
||||||
on_stop_clicked: Callable[[Gtk.Widget], None],
|
|
||||||
on_edit_clicked: Callable[[Gtk.Widget], None],
|
|
||||||
on_join_clan_clicked: Callable[[Gtk.Widget], None],
|
|
||||||
on_flash_clicked: Callable[[Gtk.Widget], None],
|
|
||||||
) -> None:
|
|
||||||
super().__init__(orientation=Gtk.Orientation.HORIZONTAL)
|
|
||||||
|
|
||||||
self.start_button = Gtk.ToolButton(label="Start")
|
return row
|
||||||
self.start_button.connect("clicked", on_start_clicked)
|
|
||||||
self.append(self.start_button)
|
|
||||||
|
|
||||||
self.stop_button = Gtk.ToolButton(label="Stop")
|
list_store = Gio.ListStore()
|
||||||
self.stop_button.connect("clicked", on_stop_clicked)
|
print(list_store)
|
||||||
self.append(self.stop_button)
|
|
||||||
|
|
||||||
self.edit_button = Gtk.ToolButton(label="Edit")
|
for vm in get_initial_vms(app.running_vms()):
|
||||||
self.edit_button.connect("clicked", on_edit_clicked)
|
list_store.append(VMListItem(data=vm.base))
|
||||||
self.append(self.edit_button)
|
|
||||||
|
|
||||||
self.join_clan_button = Gtk.ToolButton(label="Join Clan")
|
|
||||||
self.join_clan_button.connect("clicked", on_join_clan_clicked)
|
|
||||||
self.append(self.join_clan_button)
|
|
||||||
|
|
||||||
self.flash_button = Gtk.ToolButton(label="Write to USB")
|
|
||||||
self.flash_button.connect("clicked", on_flash_clicked)
|
|
||||||
self.append(self.flash_button)
|
|
||||||
|
|
||||||
self.set_selected_vm(selected_vm)
|
|
||||||
|
|
||||||
def set_selected_vm(self, vm: VMBase | None) -> None:
|
|
||||||
if vm:
|
|
||||||
self.edit_button.set_sensitive(True)
|
|
||||||
self.start_button.set_sensitive(vm.status == VMStatus.STOPPED)
|
|
||||||
self.stop_button.set_sensitive(vm.status == VMStatus.RUNNING)
|
|
||||||
else:
|
|
||||||
self.edit_button.set_sensitive(False)
|
|
||||||
self.start_button.set_sensitive(False)
|
|
||||||
self.stop_button.set_sensitive(False)
|
|
||||||
|
|
||||||
|
|
||||||
class ClanEditToolbar(Gtk.Box):
|
boxed_list.bind_model(list_store, create_widget_func=create_widget)
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
*,
|
|
||||||
on_save_clicked: Callable[[Gtk.Widget], None],
|
|
||||||
) -> None:
|
|
||||||
super().__init__(orientation=Gtk.Orientation.HORIZONTAL)
|
|
||||||
|
|
||||||
# Icons See: https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
|
|
||||||
# Could not find a suitable one
|
self.append(boxed_list)
|
||||||
self.save_button = Gtk.ToolButton(label="Save")
|
|
||||||
self.save_button.connect("clicked", on_save_clicked)
|
|
||||||
|
|
||||||
self.append(self.save_button)
|
def on_row_toggle(self, row: Adw.SwitchRow, state: bool) -> None:
|
||||||
|
print("Toggled", row.get_name(), "active:", row.get_active())
|
||||||
|
# TODO: start VM here
|
||||||
|
# question: Should we disable the switch
|
||||||
|
# for the time until we got a response for this VM?
|
||||||
|
|
||||||
|
|
||||||
class ClanListView(Gtk.Box):
|
class ClanListView(Gtk.Box):
|
79
pkgs/clan-vm-manager/clan_vm_manager/views/~list.py
Normal file
79
pkgs/clan-vm-manager/clan_vm_manager/views/~list.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
|
||||||
|
import gi
|
||||||
|
|
||||||
|
gi.require_version("Gtk", "4.0")
|
||||||
|
|
||||||
|
|
||||||
|
# class List():
|
||||||
|
# def __init__(self, cbs: Callbacks) -> None:
|
||||||
|
# super().__init__()
|
||||||
|
# self.set_title("cLAN Manager")
|
||||||
|
# # self.connect("delete-event", self.on_quit)
|
||||||
|
# self.set_default_size(800, 600)
|
||||||
|
# self.cbs = cbs
|
||||||
|
|
||||||
|
# vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6, )
|
||||||
|
# self.set_child(vbox)
|
||||||
|
# self.stack = Gtk.Stack()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# # Add named stacks
|
||||||
|
# self.stack.add_titled(clan_list, "list", "List")
|
||||||
|
# self.stack.add_titled(
|
||||||
|
# ClanJoinPage(stack=self.remount_list_view), "join", "Join"
|
||||||
|
# )
|
||||||
|
# self.stack.add_titled(
|
||||||
|
# ClanEdit(remount_list=self.remount_list_view, selected_vm=None),
|
||||||
|
# "edit",
|
||||||
|
# "Edit",
|
||||||
|
# )
|
||||||
|
|
||||||
|
# vbox.append(self.stack)
|
||||||
|
|
||||||
|
# # Must be called AFTER all components were added
|
||||||
|
# # self.show_all()
|
||||||
|
|
||||||
|
# def set_selected(self, sel: VMBase | None) -> None:
|
||||||
|
# self.selected_vm = sel
|
||||||
|
|
||||||
|
# def remount_list_view(self) -> None:
|
||||||
|
# widget = self.stack.get_child_by_name("list")
|
||||||
|
# if widget:
|
||||||
|
# widget.destroy()
|
||||||
|
# vms = []
|
||||||
|
|
||||||
|
# for vm in get_initial_vms(self.cbs.running_vms()):
|
||||||
|
# vms.append(vm.base)
|
||||||
|
# # FIXME: It feels very odd that we have to re-fetch the selected VM.
|
||||||
|
# # The model should be just updated in-place.
|
||||||
|
# if self.selected_vm and vm.base.url == self.selected_vm.url:
|
||||||
|
# self.selected_vm = vm.base
|
||||||
|
|
||||||
|
# clan_list = ClanList(
|
||||||
|
# vms=vms,
|
||||||
|
# cbs=self.cbs,
|
||||||
|
# remount_list=self.remount_list_view,
|
||||||
|
# remount_edit=self.remount_edit_view,
|
||||||
|
# set_selected=self.set_selected,
|
||||||
|
# selected_vm=self.selected_vm,
|
||||||
|
# )
|
||||||
|
# self.stack.add_titled(clan_list, "list", "List")
|
||||||
|
# # self.show_all()
|
||||||
|
# self.stack.set_visible_child_name("list")
|
||||||
|
|
||||||
|
# def remount_edit_view(self) -> None:
|
||||||
|
# widget = self.stack.get_child_by_name("edit")
|
||||||
|
# if widget:
|
||||||
|
# widget.destroy()
|
||||||
|
|
||||||
|
# self.stack.add_titled(
|
||||||
|
# ClanEdit(remount_list=self.remount_list_view, selected_vm=self.selected_vm),
|
||||||
|
# "edit",
|
||||||
|
# "Edit",
|
||||||
|
# )
|
||||||
|
# # self.show_all()
|
||||||
|
# self.stack.set_visible_child_name("edit")
|
||||||
|
|
||||||
|
# def on_quit(self, *args: Any) -> None:
|
||||||
|
# Gio.Application.quit(self.get_application())
|
@ -1,95 +0,0 @@
|
|||||||
from typing import Any
|
|
||||||
|
|
||||||
import gi
|
|
||||||
|
|
||||||
from ..models import VMBase, get_initial_vms
|
|
||||||
|
|
||||||
gi.require_version("Gtk", "4.0")
|
|
||||||
|
|
||||||
from gi.repository import Gio, Gtk
|
|
||||||
|
|
||||||
from ..interfaces import Callbacks
|
|
||||||
from ..ui.clan_join_page import ClanJoinPage
|
|
||||||
from ..ui.clan_select_list import ClanEdit, ClanList
|
|
||||||
|
|
||||||
|
|
||||||
class OverviewWindow(Gtk.ApplicationWindow):
|
|
||||||
def __init__(self, cbs: Callbacks) -> None:
|
|
||||||
super().__init__()
|
|
||||||
self.set_title("cLAN Manager")
|
|
||||||
# self.connect("delete-event", self.on_quit)
|
|
||||||
self.set_default_size(800, 600)
|
|
||||||
self.cbs = cbs
|
|
||||||
|
|
||||||
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6, )
|
|
||||||
self.set_child(vbox)
|
|
||||||
self.stack = Gtk.Stack()
|
|
||||||
|
|
||||||
clan_list = ClanList(
|
|
||||||
vms=[vm.base for vm in get_initial_vms(self.cbs.running_vms())],
|
|
||||||
cbs=self.cbs,
|
|
||||||
remount_list=self.remount_list_view,
|
|
||||||
remount_edit=self.remount_edit_view,
|
|
||||||
set_selected=self.set_selected,
|
|
||||||
selected_vm=None,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add named stacks
|
|
||||||
self.stack.add_titled(clan_list, "list", "List")
|
|
||||||
self.stack.add_titled(
|
|
||||||
ClanJoinPage(stack=self.remount_list_view), "join", "Join"
|
|
||||||
)
|
|
||||||
self.stack.add_titled(
|
|
||||||
ClanEdit(remount_list=self.remount_list_view, selected_vm=None),
|
|
||||||
"edit",
|
|
||||||
"Edit",
|
|
||||||
)
|
|
||||||
|
|
||||||
vbox.append(self.stack)
|
|
||||||
|
|
||||||
# Must be called AFTER all components were added
|
|
||||||
# self.show_all()
|
|
||||||
|
|
||||||
def set_selected(self, sel: VMBase | None) -> None:
|
|
||||||
self.selected_vm = sel
|
|
||||||
|
|
||||||
def remount_list_view(self) -> None:
|
|
||||||
widget = self.stack.get_child_by_name("list")
|
|
||||||
if widget:
|
|
||||||
widget.destroy()
|
|
||||||
vms = []
|
|
||||||
|
|
||||||
for vm in get_initial_vms(self.cbs.running_vms()):
|
|
||||||
vms.append(vm.base)
|
|
||||||
# FIXME: It feels very odd that we have to re-fetch the selected VM.
|
|
||||||
# The model should be just updated in-place.
|
|
||||||
if self.selected_vm and vm.base.url == self.selected_vm.url:
|
|
||||||
self.selected_vm = vm.base
|
|
||||||
|
|
||||||
clan_list = ClanList(
|
|
||||||
vms=vms,
|
|
||||||
cbs=self.cbs,
|
|
||||||
remount_list=self.remount_list_view,
|
|
||||||
remount_edit=self.remount_edit_view,
|
|
||||||
set_selected=self.set_selected,
|
|
||||||
selected_vm=self.selected_vm,
|
|
||||||
)
|
|
||||||
self.stack.add_titled(clan_list, "list", "List")
|
|
||||||
# self.show_all()
|
|
||||||
self.stack.set_visible_child_name("list")
|
|
||||||
|
|
||||||
def remount_edit_view(self) -> None:
|
|
||||||
widget = self.stack.get_child_by_name("edit")
|
|
||||||
if widget:
|
|
||||||
widget.destroy()
|
|
||||||
|
|
||||||
self.stack.add_titled(
|
|
||||||
ClanEdit(remount_list=self.remount_list_view, selected_vm=self.selected_vm),
|
|
||||||
"edit",
|
|
||||||
"Edit",
|
|
||||||
)
|
|
||||||
# self.show_all()
|
|
||||||
self.stack.set_visible_child_name("edit")
|
|
||||||
|
|
||||||
def on_quit(self, *args: Any) -> None:
|
|
||||||
Gio.Application.quit(self.get_application())
|
|
Loading…
Reference in New Issue
Block a user