Skip to content

Commit

Permalink
library: Support monitoring external changes to the source file
Browse files Browse the repository at this point in the history
  • Loading branch information
tchx84 committed Mar 2, 2024
1 parent 8095a77 commit a3d4794
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 5 deletions.
33 changes: 28 additions & 5 deletions src/gameeky/library/coder.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from .widgets.window import Window

from ..common.logger import logger
from ..common.monitor import Monitor
from ..common.utils import bytearray_to_string


Expand All @@ -46,6 +47,7 @@ def __init__(self) -> None:

self._window: Optional[Window] = None
self._source_path: Optional[str] = None
self._monitor = Monitor.default()

self.add_main_option(
GLib.OPTION_REMAINING,
Expand All @@ -61,7 +63,7 @@ def __on_new(self, action: Gio.SimpleAction, data: Optional[Any] = None) -> None
return

self._window.source = ""
self._source_path = None
self.source_path = None

def __on_open(self, action: Gio.SimpleAction, data: Optional[Any] = None) -> None:
default_filter = Gtk.FileFilter()
Expand All @@ -86,7 +88,7 @@ def __on_open_finished(
else:
path = file.get_path()
self._window.source = self._do_load(path)
self._source_path = path
self.source_path = path

def __on_save(self, *args) -> None:
if self._source_path is None:
Expand Down Expand Up @@ -127,7 +129,15 @@ def _do_save(self, path: str) -> None:
flags=Gio.FileCreateFlags.REPLACE_DESTINATION,
cancellable=None,
)
self._source_path = path
self.source_path = path

def __on_reload(self, window: Window, data: Optional[Any] = None) -> None:
if self._window is None:
return
if self._source_path is None:
return

self._window.source = self._do_load(self._source_path)

def _do_load(self, path: str) -> str:
file = Gio.File.new_for_path(path)
Expand All @@ -143,8 +153,7 @@ def do_command_line(self, command_line: Gio.ApplicationCommandLine) -> int:

if (source_path := options.get(GLib.OPTION_REMAINING, None)) is not None:
source_path = bytearray_to_string(source_path[-1])

self._source_path = source_path
self.source_path = source_path

self.activate()
return 0
Expand All @@ -159,6 +168,7 @@ def do_activate(self) -> None:
)

self._window = Window(application=self)
self._window.connect("reload", self.__on_reload)
self._window.present()

if self._source_path is not None:
Expand All @@ -184,8 +194,21 @@ def do_startup(self) -> None:
self.add_action(save_as_action)

def do_shutdown(self) -> None:
self._monitor.shutdown()
Adw.Application.do_shutdown(self)

@property
def source_path(self) -> Optional[str]:
return self._source_path

@source_path.setter
def source_path(self, path: Optional[str]) -> None:
self._monitor.shutdown()
self._source_path = path

if self._source_path is not None:
self._monitor.add(self._source_path)


def main(version: str) -> None:
application = Application()
Expand Down
16 changes: 16 additions & 0 deletions src/gameeky/library/widgets/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

from ...common.logger import logger
from ...common.config import pkgdatadir
from ...common.monitor import Monitor


@Gtk.Template(resource_path="/dev/tchx84/gameeky/library/widgets/window.ui")
Expand All @@ -37,6 +38,7 @@ class Window(Adw.ApplicationWindow):
output_buffer = Gtk.Template.Child()
execute_button = Gtk.Template.Child()
stop_button = Gtk.Template.Child()
banner = Gtk.Template.Child()

def __init__(self, *args, **kargs) -> None:
super().__init__(*args, **kargs)
Expand All @@ -46,6 +48,8 @@ def __init__(self, *args, **kargs) -> None:
"changed", self.__on_source_changed
)

Monitor.default().connect("changed", self.__on_monitor_changed)

@Gtk.Template.Callback("on_execute_clicked")
def __on_execute_clicked(self, button: Gtk.Button) -> None:
self.execute_button.props.visible = False
Expand Down Expand Up @@ -155,6 +159,18 @@ def __on_source_changed(
) -> None:
self.emit("changed")

def __on_monitor_changed(self, monitor: Monitor) -> None:
self.banner.props.revealed = True

@Gtk.Template.Callback("on_reload_clicked")
def __on_reload_clicked(
self,
banner: Adw.Banner,
user_data: Optional[Any] = None,
) -> None:
self.emit("reload")
self.banner.props.revealed = False

@property
def source(self) -> str:
return self.source_buffer.props.text
Expand Down
7 changes: 7 additions & 0 deletions src/gameeky/library/widgets/window.ui
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@
<property name="content">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="AdwBanner" id="banner">
<property name="button-label" translatable="yes">Reload</property>
<property name="title" translatable="yes">Source has been changed on disk</property>
<signal name="button-clicked" handler="on_reload_clicked"/>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<child>
Expand Down

0 comments on commit a3d4794

Please sign in to comment.