gtk-stream 0.9__py3-none-any.whl → 0.10__py3-none-any.whl

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/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.9'
16
- __version_tuple__ = version_tuple = (0, 9)
15
+ __version__ = version = '0.10'
16
+ __version_tuple__ = version_tuple = (0, 10)
gtk_stream/application.py CHANGED
@@ -17,7 +17,16 @@
17
17
  import sys
18
18
  from . import Gtk, GLib, Gdk
19
19
  from .common import printEvent
20
- from .properties import parse_property, get_prop_type
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
21
30
 
22
31
  class GtkStreamApp(Gtk.Application):
23
32
  def __init__(self, logger, name = None, **kwargs):
@@ -28,14 +37,18 @@ class GtkStreamApp(Gtk.Application):
28
37
  self.namedWidgets = { }
29
38
  self.namedWindows = { }
30
39
 
31
- self.callback_queue = []
32
-
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 = []
33
46
  def run_when_idle_before_startup(cb):
34
- self.callback_queue.append(cb)
47
+ callback_queue.append(cb)
35
48
  self.run_when_idle = run_when_idle_before_startup
36
49
 
37
50
  def on_startup(_):
38
- for cb in self.callback_queue:
51
+ for cb in callback_queue:
39
52
  GLib.idle_add(cb)
40
53
  self.run_when_idle = GLib.idle_add
41
54
  self.connect('startup', on_startup)
@@ -44,58 +57,61 @@ class GtkStreamApp(Gtk.Application):
44
57
  if id is not None:
45
58
  self.namedWidgets[id] = w
46
59
 
60
+ @piloted
47
61
  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)
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
74
86
  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)
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
80
97
  def closeWindow(self, id):
81
- def cb():
82
- self.namedWindows[id].close()
83
- self.run_when_idle(cb)
98
+ self.namedWindows[id].close()
99
+
100
+ @piloted
84
101
  def removeWidget(self, id):
85
- def cb():
86
- w = self.namedWidgets[id]
87
- w.get_parent().remove(w)
88
- self.run_when_idle(cb)
102
+ w = self.namedWidgets[id]
103
+ w.get_parent().remove(w)
104
+
105
+ @piloted
89
106
  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)
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
97
114
  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)
115
+ w = self.namedWidgets[id]
116
+ w.set_property(name, parse_property(get_prop_type(w.__class__, name), value)(self))
117
+
gtk_stream/parser.py CHANGED
@@ -127,6 +127,13 @@ class GtkStreamXMLHandler(sax.ContentHandler):
127
127
  self.transition_chars = onchars
128
128
  self.transition_enter = self.transE_final
129
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)
130
137
 
131
138
  case 'window':
132
139
  if 'id' in attrs:
gtk_stream/properties.py CHANGED
@@ -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
- return klass.find_property(prop).value_type.name
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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: gtk-stream
3
- Version: 0.9
3
+ Version: 0.10
4
4
  Summary: A simple stream-oriented GUI protocol
5
5
  Author-email: Marc Coiffier <marc.coiffier@univ-grenoble-alpes.fr>
6
6
  Project-URL: Homepage, https://coiffier.net/projects/gtk-stream/
@@ -1,10 +1,10 @@
1
1
  gtk_stream/__init__.py,sha256=y6JLknVFexWrSo_Zl7-TXrPR6EQ5XVMeFO1bUzLN9Lg,98
2
- gtk_stream/_version.py,sha256=hKX8UWcecrr9nhVjGc3l22za_VMbIrPYQgL_u8Ufa58,406
3
- gtk_stream/application.py,sha256=gOsJv6AUizfQZrwNe9LxVz9dOKScxzw97XO3lRTmxRs,3886
2
+ gtk_stream/_version.py,sha256=wg35lkz1DoondiGS1z7m4ZtbxPvMGnIj2qR4wzIH4-U,408
3
+ gtk_stream/application.py,sha256=s-2A8JSSIum9QDo35oxri-10OLg5BUIfTKS0FZDQd6A,4114
4
4
  gtk_stream/command_line.py,sha256=Ej4mmPiuYjr5-1JrvjGK0BDitKUCfVEI9uHp1p_FAr4,1520
5
5
  gtk_stream/common.py,sha256=xdscxYgBg_Ux6iyk26gB-AMSgoUIqlZUPgso5YS_gKE,2106
6
- gtk_stream/parser.py,sha256=Ip5x63_Lx-Eu4kpTD_2TMTVLiE_oYCqs6qqTcAnUeRY,8427
7
- gtk_stream/properties.py,sha256=r_zxYIBe5g8SGueuhtf5CIAWesmm2tXv6llh6657a74,2374
6
+ gtk_stream/parser.py,sha256=rcZtH0T5s6ttVXvbHZjX2hBoasWNbtDR5LEa8yiHUj4,8772
7
+ gtk_stream/properties.py,sha256=oCG4EIMWS4WdKY4YzQZzllddoIY33GvnbgvMG3C5Muo,2630
8
8
  gtk_stream/documents/__init__.py,sha256=MVqnPXrTuoKyUHJ41jgqbFr3VA5JWfI6QFfXAIE6DuQ,789
9
9
  gtk_stream/documents/classes/Box.py,sha256=d01o2-JQ3-k0VjvvY8E7mly-u_f1v1NqYz1IDjHZLUo,1381
10
10
  gtk_stream/documents/classes/Button.py,sha256=0Cs5DOt-FoDVLWIktJHuH6OasI58TNI0Gs3uIKJDj2o,1563
@@ -23,8 +23,8 @@ gtk_stream/documents/classes/Separator.py,sha256=uw_EgAKs_6pNA8nrOLzruIlJfk4uaog
23
23
  gtk_stream/documents/classes/Stack.py,sha256=YA6NDzZL2u4Ko8GXtx8Or-jEWGMCEw2cC1HNkAMRw-8,1030
24
24
  gtk_stream/documents/classes/Switch.py,sha256=OLCWWNeVyNrk4Tu3JDe64FqsLhedh3dDzKDKne2CyDw,1382
25
25
  gtk_stream/documents/classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
- gtk_stream-0.9.dist-info/METADATA,sha256=enjy2jWEEX9cFvPCW86EDe4TuyF4uvKIxeIFnoLrbco,804
27
- gtk_stream-0.9.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
28
- gtk_stream-0.9.dist-info/entry_points.txt,sha256=PmhKTb4MMQM6dN2HJcoDSMI8L0lZIFIlFn-BgdfPDpo,60
29
- gtk_stream-0.9.dist-info/top_level.txt,sha256=vE9zfHGe9Ke7FSe0wBK2WYJI-BpcQNu6xDC3Cu5O8rQ,11
30
- gtk_stream-0.9.dist-info/RECORD,,
26
+ gtk_stream-0.10.dist-info/METADATA,sha256=Tmq513moUwqczsg1EYEh0-eBcz-SJs3gTVAXUHGlt_Y,805
27
+ gtk_stream-0.10.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
28
+ gtk_stream-0.10.dist-info/entry_points.txt,sha256=PmhKTb4MMQM6dN2HJcoDSMI8L0lZIFIlFn-BgdfPDpo,60
29
+ gtk_stream-0.10.dist-info/top_level.txt,sha256=vE9zfHGe9Ke7FSe0wBK2WYJI-BpcQNu6xDC3Cu5O8rQ,11
30
+ gtk_stream-0.10.dist-info/RECORD,,