gui add stack switcher, remove notebook tabs #602
@ -6,19 +6,32 @@ from typing import Any
|
||||
|
||||
import gi
|
||||
|
||||
from clan_vm_manager.models import VMBase
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gio, Gtk
|
||||
|
||||
from .constants import constants
|
||||
from .ui.clan_select_list import ClanSelectPage
|
||||
from .ui.clan_select_list import ClanEdit, ClanList
|
||||
|
||||
|
||||
class ClanJoinPage(Gtk.Box):
|
||||
def __init__(self) -> None:
|
||||
def __init__(self, stack: Gtk.Stack) -> None:
|
||||
super().__init__()
|
||||
self.page = Gtk.Box()
|
||||
self.page = Gtk.Box(
|
||||
orientation=Gtk.Orientation.VERTICAL, spacing=6, expand=True
|
||||
)
|
||||
self.set_border_width(10)
|
||||
self.add(Gtk.Label(label="Join"))
|
||||
self.stack = stack
|
||||
|
||||
button = Gtk.Button(label="Back to list", margin_left=10)
|
||||
button.connect("clicked", self.switch)
|
||||
self.add(button)
|
||||
|
||||
self.add(Gtk.Label("Join cLan"))
|
||||
|
||||
def switch(self, widget: Gtk.Widget) -> None:
|
||||
self.stack.set_visible_child_name("list")
|
||||
|
||||
|
||||
class MainWindow(Gtk.ApplicationWindow):
|
||||
@ -35,25 +48,46 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
# Add a notebook layout
|
||||
# https://python-gtk-3-tutorial.readthedocs.io/en/latest/layout.html#notebook
|
||||
self.notebook = Gtk.Notebook()
|
||||
vbox.add(self.notebook)
|
||||
self.stack = Gtk.Stack()
|
||||
# self.stack_switcher = Gtk.StackSwitcher()
|
||||
|
||||
self.notebook.append_page(
|
||||
ClanSelectPage(self.reload_clan_tab), Gtk.Label(label="Overview")
|
||||
# Add named stacks
|
||||
self.stack.add_titled(
|
||||
ClanList(self.show_list, self.show_edit, self.set_selected), "list", "List"
|
||||
)
|
||||
self.notebook.append_page(ClanJoinPage(), Gtk.Label(label="Join"))
|
||||
self.stack.add_titled(ClanJoinPage(self.show_list), "join", "Join")
|
||||
self.stack.add_titled(ClanEdit(self.show_list, None), "edit", "Edit")
|
||||
|
||||
vbox.add(self.stack)
|
||||
|
||||
# Must be called AFTER all components were added
|
||||
self.show_all()
|
||||
|
||||
def reload_clan_tab(self) -> None:
|
||||
print("Remounting ClanSelectPage")
|
||||
self.notebook.remove_page(0)
|
||||
self.notebook.insert_page(
|
||||
ClanSelectPage(self.reload_clan_tab), Gtk.Label(label="Overview2"), 0
|
||||
def set_selected(self, sel: VMBase | None) -> None:
|
||||
self.selected = sel
|
||||
print(f"APP selected + {self.selected}")
|
||||
|
||||
def show_list(self) -> None:
|
||||
widget = self.stack.get_child_by_name("list")
|
||||
print("Remounting ClanListView")
|
||||
if widget:
|
||||
widget.destroy()
|
||||
|
||||
self.stack.add_titled(
|
||||
ClanList(self.show_list, self.show_edit, self.set_selected), "list", "List"
|
||||
)
|
||||
# must call show_all before set active tab
|
||||
self.show_all()
|
||||
self.notebook.set_current_page(0)
|
||||
self.stack.set_visible_child_name("list")
|
||||
|
||||
def show_edit(self) -> None:
|
||||
print("Remounting ClanEdit")
|
||||
widget = self.stack.get_child_by_name("edit")
|
||||
if widget:
|
||||
widget.destroy()
|
||||
|
||||
self.stack.add_titled(ClanEdit(self.show_list, self.selected), "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())
|
||||
|
@ -5,10 +5,93 @@ from gi.repository import GdkPixbuf, Gtk
|
||||
from ..models import VMBase, get_initial_vms
|
||||
|
||||
|
||||
class ClanSelectPage(Gtk.Box):
|
||||
def __init__(self, reload: Callable[[], None]) -> None:
|
||||
class ClanEditForm(Gtk.ListBox):
|
||||
def __init__(self, selected: VMBase | None) -> None:
|
||||
super().__init__()
|
||||
self.page = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, expand=True)
|
||||
self.set_border_width(10)
|
||||
self.selected = selected
|
||||
self.set_selection_mode(0)
|
||||
|
||||
if self.selected:
|
||||
row = Gtk.ListBoxRow()
|
||||
row.add(Gtk.Label(f"\n {self.selected.name}"))
|
||||
self.add(row)
|
||||
|
||||
# ---------- row 1 --------
|
||||
row = Gtk.ListBoxRow()
|
||||
row_layout = Gtk.Box(spacing=6, expand=True)
|
||||
|
||||
# Doc: pack_start/end takes alignment params Expand, Fill, Padding
|
||||
row_layout.pack_start(Gtk.Label("Memory Size in MiB"), False, False, 5)
|
||||
row_layout.pack_start(
|
||||
Gtk.SpinButton.new_with_range(512, 4096, 256), True, True, 0
|
||||
)
|
||||
|
||||
row.add(row_layout)
|
||||
self.add(row)
|
||||
|
||||
# ----------- row 2 -------
|
||||
|
||||
row = Gtk.ListBoxRow()
|
||||
row_layout = Gtk.Box(spacing=6, expand=True)
|
||||
|
||||
row_layout.pack_start(Gtk.Label("CPU Count"), False, False, 5)
|
||||
row_layout.pack_end(Gtk.SpinButton.new_with_range(1, 5, 1), True, True, 0)
|
||||
|
||||
row.add(row_layout)
|
||||
self.add(row)
|
||||
|
||||
def switch(self, widget: Gtk.Widget) -> None:
|
||||
self.show_list()
|
||||
|
||||
|
||||
class ClanEdit(Gtk.Box):
|
||||
def __init__(self, show_list: Callable[[], None], selected: VMBase | None) -> None:
|
||||
super().__init__(orientation=Gtk.Orientation.VERTICAL, expand=True)
|
||||
|
||||
self.show_list = show_list
|
||||
self.selected = selected
|
||||
|
||||
button_hooks = {
|
||||
"on_save_clicked": self.on_save,
|
||||
}
|
||||
|
||||
self.toolbar = ClanEditToolbar(**button_hooks)
|
||||
self.add(self.toolbar)
|
||||
self.add(ClanEditForm(self.selected))
|
||||
|
||||
def on_save(self, widget: Gtk.Widget) -> None:
|
||||
print("Save clicked saving values")
|
||||
self.show_list()
|
||||
|
||||
|
||||
class ClanList(Gtk.Box):
|
||||
"""
|
||||
The ClanList
|
||||
Is the composition of
|
||||
the ClanListToolbar
|
||||
the clanListView
|
||||
# ------------------------#
|
||||
# - Tools <Join> < Edit> #
|
||||
# ------------------------#
|
||||
# - List Items
|
||||
# - <...>
|
||||
# ------------------------#
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
show_list: Callable[[], None],
|
||||
show_edit: Callable[[], None],
|
||||
set_selected: Callable[[VMBase | None], None],
|
||||
) -> None:
|
||||
super().__init__(orientation=Gtk.Orientation.VERTICAL, expand=True)
|
||||
|
||||
self.show_edit = show_edit
|
||||
self.show_list = show_list
|
||||
self.set_selected = set_selected
|
||||
|
||||
# TODO: We should use somekind of useState hook here.
|
||||
# that updates the list of VMs when the user changes something
|
||||
# @hsjobeki reply: @qubasa: This is how to update data in the list store
|
||||
@ -17,59 +100,89 @@ class ClanSelectPage(Gtk.Box):
|
||||
# This class needs to take ownership of the data because it has access to the listStore only
|
||||
self.selected_vm: VMBase | None = None
|
||||
|
||||
self.list_hooks = {
|
||||
"on_select_row": self.on_select_vm,
|
||||
}
|
||||
self.add(ClanSelectList(**self.list_hooks))
|
||||
self.reload = reload
|
||||
button_hooks = {
|
||||
"on_start_clicked": self.on_start_clicked,
|
||||
"on_stop_clicked": self.on_stop_clicked,
|
||||
"on_backup_clicked": self.on_backup_clicked,
|
||||
"on_edit_clicked": self.on_edit_clicked,
|
||||
}
|
||||
self.add(ClanSelectButtons(**button_hooks))
|
||||
self.toolbar = ClanListToolbar(**button_hooks)
|
||||
self.toolbar.set_is_selected(False)
|
||||
self.add(self.toolbar)
|
||||
|
||||
self.list_hooks = {
|
||||
"on_select_row": self.on_select_vm,
|
||||
}
|
||||
self.add(ClanListView(**self.list_hooks))
|
||||
|
||||
def on_start_clicked(self, widget: Gtk.Widget) -> None:
|
||||
print("Start clicked")
|
||||
if self.selected_vm:
|
||||
self.selected_vm.run()
|
||||
self.reload()
|
||||
# Call this to reload
|
||||
self.show_list()
|
||||
|
||||
def on_stop_clicked(self, widget: Gtk.Widget) -> None:
|
||||
print("Stop clicked")
|
||||
|
||||
def on_backup_clicked(self, widget: Gtk.Widget) -> None:
|
||||
print("Backup clicked")
|
||||
def on_edit_clicked(self, widget: Gtk.Widget) -> None:
|
||||
print("Edit clicked")
|
||||
self.show_edit()
|
||||
|
||||
def on_select_vm(self, vm: VMBase) -> None:
|
||||
print(f"on_select_vm: {vm}")
|
||||
if vm is None:
|
||||
self.toolbar.set_is_selected(False)
|
||||
else:
|
||||
self.toolbar.set_is_selected(True)
|
||||
|
||||
self.set_selected(vm)
|
||||
self.selected_vm = vm
|
||||
|
||||
|
||||
class ClanSelectButtons(Gtk.Box):
|
||||
class ClanListToolbar(Gtk.Toolbar):
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
on_start_clicked: Callable[[Gtk.Widget], None],
|
||||
on_stop_clicked: Callable[[Gtk.Widget], None],
|
||||
on_backup_clicked: Callable[[Gtk.Widget], None],
|
||||
on_edit_clicked: Callable[[Gtk.Widget], None],
|
||||
) -> None:
|
||||
super().__init__(
|
||||
orientation=Gtk.Orientation.HORIZONTAL, margin_bottom=10, margin_top=10
|
||||
)
|
||||
super().__init__(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
|
||||
button = Gtk.Button(label="Start", margin_left=10)
|
||||
button.connect("clicked", on_start_clicked)
|
||||
self.add(button)
|
||||
button = Gtk.Button(label="Stop", margin_left=10)
|
||||
button.connect("clicked", on_stop_clicked)
|
||||
self.add(button)
|
||||
button = Gtk.Button(label="Edit", margin_left=10)
|
||||
button.connect("clicked", on_backup_clicked)
|
||||
self.add(button)
|
||||
self.start_button = Gtk.ToolButton(label="Join")
|
||||
self.start_button.connect("clicked", on_start_clicked)
|
||||
self.add(self.start_button)
|
||||
|
||||
self.edit_button = Gtk.ToolButton(label="Edit")
|
||||
self.edit_button.connect("clicked", on_edit_clicked)
|
||||
self.add(self.edit_button)
|
||||
|
||||
def set_is_selected(self, s: bool) -> None:
|
||||
if s:
|
||||
self.edit_button.set_sensitive(True)
|
||||
self.start_button.set_sensitive(True)
|
||||
else:
|
||||
self.edit_button.set_sensitive(False)
|
||||
self.start_button.set_sensitive(False)
|
||||
|
||||
|
||||
class ClanSelectList(Gtk.Box):
|
||||
class ClanEditToolbar(Gtk.Toolbar):
|
||||
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.save_button = Gtk.ToolButton(label="Save")
|
||||
self.save_button.connect("clicked", on_save_clicked)
|
||||
|
||||
self.add(self.save_button)
|
||||
|
||||
|
||||
class ClanListView(Gtk.Box):
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
|
Loading…
Reference in New Issue
Block a user