gtk-stream 0.8__tar.gz → 0.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gtk_stream-0.8 → gtk_stream-0.10}/PKG-INFO +1 -1
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/_version.py +2 -2
- gtk_stream-0.10/gtk_stream/application.py +117 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/__init__.py +1 -1
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/Picture.py +8 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/parser.py +8 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/properties.py +6 -1
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream.egg-info/PKG-INFO +1 -1
- gtk_stream-0.8/gtk_stream/application.py +0 -101
- {gtk_stream-0.8 → gtk_stream-0.10}/README.md +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk-stream +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/__init__.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/command_line.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/common.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/Box.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/Button.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/Document.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/Dropdown.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/Entry.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/FlowBox.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/Frame.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/Grid.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/Label.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/Paned.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/ProgressBar.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/ScrolledWindow.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/Separator.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/Stack.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/Switch.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream/documents/classes/__init__.py +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream.egg-info/SOURCES.txt +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream.egg-info/dependency_links.txt +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream.egg-info/entry_points.txt +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream.egg-info/requires.txt +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/gtk_stream.egg-info/top_level.txt +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/pyproject.toml +0 -0
- {gtk_stream-0.8 → gtk_stream-0.10}/setup.cfg +0 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
# Gtk-Stream : A stream-based GUI protocol
|
2
|
+
# Copyright (C) 2024 Marc Coiffier
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
import sys
|
18
|
+
from . import Gtk, GLib, Gdk
|
19
|
+
from .common import printEvent
|
20
|
+
from .properties import parse_property, get_prop_type, set_parse_prop
|
21
|
+
|
22
|
+
def piloted(f):
|
23
|
+
"""A decorator for methods that are both called from the pilot
|
24
|
+
application and need access to the gtk main thread"""
|
25
|
+
def ret(self, *args, **kwargs):
|
26
|
+
def cb():
|
27
|
+
f(self, *args, **kwargs)
|
28
|
+
self.run_when_idle(cb)
|
29
|
+
return ret
|
30
|
+
|
31
|
+
class GtkStreamApp(Gtk.Application):
|
32
|
+
def __init__(self, logger, name = None, **kwargs):
|
33
|
+
super().__init__(**kwargs)
|
34
|
+
self.logger = logger
|
35
|
+
if name != None:
|
36
|
+
GLib.set_application_name(name)
|
37
|
+
self.namedWidgets = { }
|
38
|
+
self.namedWindows = { }
|
39
|
+
|
40
|
+
# The first messages from the pilot may arrive before the
|
41
|
+
# application is ready to process them.
|
42
|
+
#
|
43
|
+
# If that happens, store the actions until they can be taken
|
44
|
+
# (when the "startup" signal is called)
|
45
|
+
callback_queue = []
|
46
|
+
def run_when_idle_before_startup(cb):
|
47
|
+
callback_queue.append(cb)
|
48
|
+
self.run_when_idle = run_when_idle_before_startup
|
49
|
+
|
50
|
+
def on_startup(_):
|
51
|
+
for cb in callback_queue:
|
52
|
+
GLib.idle_add(cb)
|
53
|
+
self.run_when_idle = GLib.idle_add
|
54
|
+
self.connect('startup', on_startup)
|
55
|
+
|
56
|
+
def nameWidget(self, id, w):
|
57
|
+
if id is not None:
|
58
|
+
self.namedWidgets[id] = w
|
59
|
+
|
60
|
+
@piloted
|
61
|
+
def openFileDialog(self, id, parent):
|
62
|
+
dialog = Gtk.FileDialog()
|
63
|
+
dialog.props.modal = True
|
64
|
+
def on_choose(_, b):
|
65
|
+
try:
|
66
|
+
file = dialog.open_finish(b)
|
67
|
+
print(f"{id}:selected:{file.get_path()}")
|
68
|
+
sys.stdout.flush()
|
69
|
+
except GLib.GError as e:
|
70
|
+
print(f"{id}:none-selected")
|
71
|
+
sys.stdout.flush()
|
72
|
+
|
73
|
+
dialog.open(parent = self.namedWindows[parent], callback = on_choose)
|
74
|
+
|
75
|
+
@piloted
|
76
|
+
def newWindow(self, document, id, **attrs):
|
77
|
+
win = Gtk.Window(application=self)
|
78
|
+
for (attr_name, attr_val) in attrs.items():
|
79
|
+
set_parse_prop(self, win, attr_name, attr_val)
|
80
|
+
self.namedWindows[id] = win
|
81
|
+
win.set_child(document.render())
|
82
|
+
win.connect('close-request', printEvent(self.logger, 'close-request', id))
|
83
|
+
win.present()
|
84
|
+
|
85
|
+
@piloted
|
86
|
+
def addStyle(self, style):
|
87
|
+
provider = Gtk.CssProvider()
|
88
|
+
provider.load_from_data(style)
|
89
|
+
Gtk.StyleContext.add_provider_for_display(Gdk.Display.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
|
90
|
+
|
91
|
+
@piloted
|
92
|
+
def addIconPath(self, path):
|
93
|
+
theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default())
|
94
|
+
theme.add_search_path(path)
|
95
|
+
|
96
|
+
@piloted
|
97
|
+
def closeWindow(self, id):
|
98
|
+
self.namedWindows[id].close()
|
99
|
+
|
100
|
+
@piloted
|
101
|
+
def removeWidget(self, id):
|
102
|
+
w = self.namedWidgets[id]
|
103
|
+
w.get_parent().remove(w)
|
104
|
+
|
105
|
+
@piloted
|
106
|
+
def insertWidget(self, to, document):
|
107
|
+
if to in self.namedWidgets:
|
108
|
+
w = self.namedWidgets[to]
|
109
|
+
w.insert_child(document)
|
110
|
+
else:
|
111
|
+
raise Exception(f"Error: unknown widget id '{to}'")
|
112
|
+
|
113
|
+
@piloted
|
114
|
+
def setProp(self, id, name, value):
|
115
|
+
w = self.namedWidgets[id]
|
116
|
+
w.set_property(name, parse_property(get_prop_type(w.__class__, name), value)(self))
|
117
|
+
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from .classes.Document import Document, PseudoDocument
|
2
2
|
|
3
3
|
from .classes.Label import Label
|
4
|
-
from .classes.Picture import Picture
|
4
|
+
from .classes.Picture import Picture, Icon
|
5
5
|
from .classes.ProgressBar import ProgressBar
|
6
6
|
from .classes.Separator import Separator
|
7
7
|
|
@@ -25,3 +25,11 @@ class Picture(Document):
|
|
25
25
|
self.src = src
|
26
26
|
def render_raw(self):
|
27
27
|
return Gtk.Picture.new_for_filename(self.src)
|
28
|
+
|
29
|
+
class Icon(Document):
|
30
|
+
__g_class__ = Gtk.Image
|
31
|
+
def __init__(self, app, src, **kwargs):
|
32
|
+
super().__init__(app, **kwargs)
|
33
|
+
self.src = src
|
34
|
+
def render_raw(self):
|
35
|
+
return Gtk.Image.new_from_file(self.src)
|
@@ -43,6 +43,7 @@ WIDGET_DOCUMENTS = {
|
|
43
43
|
'link' : docs.LinkButton,
|
44
44
|
'switch' : docs.Switch,
|
45
45
|
'picture' : docs.Picture,
|
46
|
+
'icon' : docs.Icon,
|
46
47
|
'separator' : docs.Separator,
|
47
48
|
'scrolled-window' : docs.ScrolledWindow,
|
48
49
|
'stack' : docs.Stack,
|
@@ -126,6 +127,13 @@ class GtkStreamXMLHandler(sax.ContentHandler):
|
|
126
127
|
self.transition_chars = onchars
|
127
128
|
self.transition_enter = self.transE_final
|
128
129
|
self.transition_leave = self.transL_tag('style', self.transE_message, leave_parent, leave)
|
130
|
+
|
131
|
+
case 'add-icon-path':
|
132
|
+
if 'path' in attrs:
|
133
|
+
def leave():
|
134
|
+
self.app.addIconPath(attrs['path'])
|
135
|
+
self.transition_enter = self.transE_final
|
136
|
+
self.transition_leave = self.transL_tag('add-icon-path', self.transE_message, leave_parent, leave)
|
129
137
|
|
130
138
|
case 'window':
|
131
139
|
if 'id' in attrs:
|
@@ -57,4 +57,9 @@ def parse_property(prop_type, val):
|
|
57
57
|
# print(f"Parsing property '{val}' of type '{prop_type}'", file=sys.stderr)
|
58
58
|
return _PARSE_TYPE_PROPERTY[prop_type](val)
|
59
59
|
def get_prop_type(klass, prop):
|
60
|
-
|
60
|
+
try:
|
61
|
+
return klass.find_property(prop).value_type.name
|
62
|
+
except AttributeError:
|
63
|
+
raise Exception(f"Unknown GTK property '{prop}' of class '{klass}'")
|
64
|
+
def set_parse_prop(app, w, prop_name, val):
|
65
|
+
w.set_property(prop_name, parse_property(get_prop_type(w.__class__, prop_name), val)(app))
|
@@ -1,101 +0,0 @@
|
|
1
|
-
# Gtk-Stream : A stream-based GUI protocol
|
2
|
-
# Copyright (C) 2024 Marc Coiffier
|
3
|
-
#
|
4
|
-
# This program is free software: you can redistribute it and/or modify
|
5
|
-
# it under the terms of the GNU General Public License as published by
|
6
|
-
# the Free Software Foundation, either version 3 of the License, or
|
7
|
-
# (at your option) any later version.
|
8
|
-
#
|
9
|
-
# This program is distributed in the hope that it will be useful,
|
10
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
-
# GNU General Public License for more details.
|
13
|
-
#
|
14
|
-
# You should have received a copy of the GNU General Public License
|
15
|
-
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
16
|
-
|
17
|
-
import sys
|
18
|
-
from . import Gtk, GLib, Gdk
|
19
|
-
from .common import printEvent
|
20
|
-
from .properties import parse_property, get_prop_type
|
21
|
-
|
22
|
-
class GtkStreamApp(Gtk.Application):
|
23
|
-
def __init__(self, logger, name = None, **kwargs):
|
24
|
-
super().__init__(**kwargs)
|
25
|
-
self.logger = logger
|
26
|
-
if name != None:
|
27
|
-
GLib.set_application_name(name)
|
28
|
-
self.namedWidgets = { }
|
29
|
-
self.namedWindows = { }
|
30
|
-
|
31
|
-
self.callback_queue = []
|
32
|
-
|
33
|
-
def run_when_idle_before_startup(cb):
|
34
|
-
self.callback_queue.append(cb)
|
35
|
-
self.run_when_idle = run_when_idle_before_startup
|
36
|
-
|
37
|
-
def on_startup(_):
|
38
|
-
for cb in self.callback_queue:
|
39
|
-
GLib.idle_add(cb)
|
40
|
-
self.run_when_idle = GLib.idle_add
|
41
|
-
self.connect('startup', on_startup)
|
42
|
-
|
43
|
-
def nameWidget(self, id, w):
|
44
|
-
if id is not None:
|
45
|
-
self.namedWidgets[id] = w
|
46
|
-
|
47
|
-
def openFileDialog(self, id, parent):
|
48
|
-
def cb():
|
49
|
-
dialog = Gtk.FileDialog()
|
50
|
-
dialog.props.modal = True
|
51
|
-
def on_choose(_, b):
|
52
|
-
try:
|
53
|
-
file = dialog.open_finish(b)
|
54
|
-
print(f"{id}:selected:{file.get_path()}")
|
55
|
-
sys.stdout.flush()
|
56
|
-
except GLib.GError as e:
|
57
|
-
print(f"{id}:none-selected")
|
58
|
-
sys.stdout.flush()
|
59
|
-
|
60
|
-
dialog.open(parent = self.namedWindows[parent], callback = on_choose)
|
61
|
-
self.run_when_idle(cb)
|
62
|
-
def newWindow(self, document, id, title = "Window", width = None, height = None):
|
63
|
-
def cb():
|
64
|
-
win = Gtk.Window(application=self)
|
65
|
-
win.set_title(title)
|
66
|
-
if width != None and height != None:
|
67
|
-
win.set_default_size(int(width), int(height))
|
68
|
-
self.namedWindows[id] = win
|
69
|
-
win.set_child(document.render())
|
70
|
-
win.connect('close-request', printEvent(self.logger, 'close-request', id))
|
71
|
-
win.present()
|
72
|
-
return False
|
73
|
-
self.run_when_idle(cb)
|
74
|
-
def addStyle(self, style):
|
75
|
-
def cb():
|
76
|
-
provider = Gtk.CssProvider()
|
77
|
-
provider.load_from_data(style)
|
78
|
-
Gtk.StyleContext.add_provider_for_display(Gdk.Display.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
|
79
|
-
self.run_when_idle(cb)
|
80
|
-
def closeWindow(self, id):
|
81
|
-
def cb():
|
82
|
-
self.namedWindows[id].close()
|
83
|
-
self.run_when_idle(cb)
|
84
|
-
def removeWidget(self, id):
|
85
|
-
def cb():
|
86
|
-
w = self.namedWidgets[id]
|
87
|
-
w.get_parent().remove(w)
|
88
|
-
self.run_when_idle(cb)
|
89
|
-
def insertWidget(self, to, document):
|
90
|
-
def cb():
|
91
|
-
if to in self.namedWidgets:
|
92
|
-
w = self.namedWidgets[to]
|
93
|
-
w.insert_child(document)
|
94
|
-
else:
|
95
|
-
raise Exception(f"Error: unknown widget id '{to}'")
|
96
|
-
self.run_when_idle(cb)
|
97
|
-
def setProp(self, id, name, value):
|
98
|
-
def cb():
|
99
|
-
w = self.namedWidgets[id]
|
100
|
-
w.set_property(name, parse_property(get_prop_type(w.__class__, name), value)(self))
|
101
|
-
self.run_when_idle(cb)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|