gtk4 4.1.1 → 4.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/lib/gtk4/css-provider.rb +9 -5
  3. data/lib/gtk4/loader.rb +2 -1
  4. data/sample/examples/application1/README.md +32 -0
  5. data/sample/examples/application1/exampleapp.png +0 -0
  6. data/sample/examples/application1/exampleapp.rb +50 -0
  7. data/sample/examples/application1/org.gtk.exampleapp.desktop +6 -0
  8. data/sample/examples/application2/README.md +10 -0
  9. data/sample/examples/application2/exampleapp.rb +80 -0
  10. data/sample/examples/application3/README.md +1 -0
  11. data/sample/examples/application3/exampleapp.rb +108 -0
  12. data/sample/examples/application4/README.md +13 -0
  13. data/sample/examples/application4/exampleapp.rb +158 -0
  14. data/sample/examples/application5/README.md +30 -0
  15. data/sample/examples/application5/Rakefile +27 -0
  16. data/sample/examples/application5/exampleapp.rb +171 -0
  17. data/sample/examples/application5/org.gtk.exampleapp.gschema.xml +20 -0
  18. data/sample/examples/application6/README.md +15 -0
  19. data/sample/examples/application6/Rakefile +27 -0
  20. data/sample/examples/application6/exampleapp.rb +265 -0
  21. data/sample/examples/application6/org.gtk.exampleapp.gschema.xml +20 -0
  22. data/sample/examples/application7/README.md +15 -0
  23. data/sample/examples/application7/Rakefile +27 -0
  24. data/sample/examples/application7/exampleapp.rb +307 -0
  25. data/sample/examples/application7/org.gtk.exampleapp.gschema.xml +20 -0
  26. data/sample/examples/application8/README.md +15 -0
  27. data/sample/examples/application8/Rakefile +27 -0
  28. data/sample/examples/application8/exampleapp.rb +357 -0
  29. data/sample/examples/application8/org.gtk.exampleapp.gschema.xml +25 -0
  30. data/sample/examples/application9/README.md +15 -0
  31. data/sample/examples/application9/Rakefile +27 -0
  32. data/sample/examples/application9/exampleapp.rb +387 -0
  33. data/sample/examples/application9/org.gtk.exampleapp.gschema.xml +25 -0
  34. metadata +36 -6
@@ -0,0 +1,357 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Copyright (C) 2023 Ruby-GNOME Project Team
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2.1 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ #
19
+ # Example from:
20
+ # * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application8/exampleapp.c
21
+ # * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application8/exampleappwin.c
22
+ # * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application8/exampleappprefs.c
23
+ # * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application8/window.ui
24
+ # * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application8/gears-menu.ui
25
+ # * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application8/prefs.ui
26
+ # License: LGPL2.1-or-later
27
+
28
+ # GSETTINGS_SCHEMA_DIR must be set before requiring "gtk4" gem because it is used in the GIO initialization.
29
+
30
+ if File.exist?(File.join(__dir__, "gschemas.compiled"))
31
+ ENV["GSETTINGS_SCHEMA_DIR"] = __dir__
32
+ else
33
+ raise %{gschemas.compiled doesn't exist. Run "rake" to generate it.}
34
+ end
35
+
36
+ require "gtk4"
37
+
38
+ class ExampleAppPrefs < Gtk::Dialog
39
+ type_register
40
+ class << self
41
+ def init
42
+ template = <<~TEMPLATE
43
+ <?xml version="1.0" encoding="UTF-8"?>
44
+ <interface>
45
+ <template class="ExampleAppPrefs" parent="GtkDialog">
46
+ <property name="title" translatable="yes">Preferences</property>
47
+ <property name="resizable">0</property>
48
+ <property name="modal">1</property>
49
+ <child internal-child="content_area">
50
+ <object class="GtkBox" id="content_area">
51
+ <child>
52
+ <object class="GtkGrid" id="grid">
53
+ <property name="margin-start">12</property>
54
+ <property name="margin-end">12</property>
55
+ <property name="margin-top">12</property>
56
+ <property name="margin-bottom">12</property>
57
+ <property name="row-spacing">12</property>
58
+ <property name="column-spacing">12</property>
59
+ <child>
60
+ <object class="GtkLabel" id="fontlabel">
61
+ <property name="label">_Font:</property>
62
+ <property name="use-underline">1</property>
63
+ <property name="mnemonic-widget">font</property>
64
+ <property name="xalign">1</property>
65
+ <layout>
66
+ <property name="column">0</property>
67
+ <property name="row">0</property>
68
+ </layout>
69
+ </object>
70
+ </child>
71
+ <child>
72
+ <object class="GtkFontButton" id="font">
73
+ <layout>
74
+ <property name="column">1</property>
75
+ <property name="row">0</property>
76
+ </layout>
77
+ </object>
78
+ </child>
79
+ <child>
80
+ <object class="GtkLabel" id="transitionlabel">
81
+ <property name="label">_Transition:</property>
82
+ <property name="use-underline">1</property>
83
+ <property name="mnemonic-widget">transition</property>
84
+ <property name="xalign">1</property>
85
+ <layout>
86
+ <property name="column">0</property>
87
+ <property name="row">1</property>
88
+ </layout>
89
+ </object>
90
+ </child>
91
+ <child>
92
+ <object class="GtkComboBoxText" id="transition">
93
+ <items>
94
+ <item translatable="yes" id="none">None</item>
95
+ <item translatable="yes" id="crossfade">Fade</item>
96
+ <item translatable="yes" id="slide-left-right">Slide</item>
97
+ </items>
98
+ <layout>
99
+ <property name="column">1</property>
100
+ <property name="row">1</property>
101
+ </layout>
102
+ </object>
103
+ </child>
104
+ </object>
105
+ </child>
106
+ </object>
107
+ </child>
108
+ </template>
109
+ </interface>
110
+ TEMPLATE
111
+ set_template(data: template)
112
+ bind_template_child("font")
113
+ bind_template_child("transition")
114
+ end
115
+ end
116
+
117
+ def initialize(win)
118
+ # The original C program sets use-header-bar property to TRUE instead of 1.
119
+ # But the property type is int, not gboolean.
120
+ # Therefore, the property value must be 1, not `true` here.
121
+ super('transient-for': win, 'use-header-bar': 1)
122
+ settings = Gio::Settings.new("org.gtk.exampleapp")
123
+ settings.bind("font", font, "font", :default)
124
+ settings.bind("transition", transition, "active-id", :default)
125
+ end
126
+ end
127
+
128
+ class ExampleAppWindow < Gtk::ApplicationWindow
129
+ type_register
130
+ class << self
131
+ def init
132
+ template = <<~TEMPLATE
133
+ <?xml version="1.0" encoding="UTF-8"?>
134
+ <interface>
135
+ <template class="ExampleAppWindow" parent="GtkApplicationWindow">
136
+ <property name="title" translatable="yes">Example Application</property>
137
+ <property name="default-width">600</property>
138
+ <property name="default-height">400</property>
139
+ <child type="titlebar">
140
+ <object class="GtkHeaderBar" id="header">
141
+ <child type="title">
142
+ <object class="GtkStackSwitcher" id="tabs">
143
+ <property name="stack">stack</property>
144
+ </object>
145
+ </child>
146
+ <child type="end">
147
+ <object class="GtkToggleButton" id="search">
148
+ <property name="sensitive">0</property>
149
+ <property name="icon-name">edit-find-symbolic</property>
150
+ </object>
151
+ </child>
152
+ <child type="end">
153
+ <object class="GtkMenuButton" id="gears">
154
+ <property name="direction">none</property>
155
+ </object>
156
+ </child>
157
+ </object>
158
+ </child>
159
+ <child>
160
+ <object class="GtkBox" id="content_box">
161
+ <property name="orientation">vertical</property>
162
+ <child>
163
+ <object class="GtkSearchBar" id="searchbar">
164
+ <child>
165
+ <object class="GtkSearchEntry" id="searchentry">
166
+ <signal name="search-changed" handler="search_text_changed"/>
167
+ </object>
168
+ </child>
169
+ </object>
170
+ </child>
171
+ <child>
172
+ <object class="GtkBox" id="hbox">
173
+ <child>
174
+ <object class="GtkRevealer" id="sidebar">
175
+ <property name="transition-type">slide-right</property>
176
+ <child>
177
+ <object class="GtkScrolledWindow" id="sidebar-sw">
178
+ <property name="hscrollbar-policy">never</property>
179
+ <child>
180
+ <object class="GtkListBox" id="words">
181
+ <property name="selection-mode">none</property>
182
+ </object>
183
+ </child>
184
+ </object>
185
+ </child>
186
+ </object>
187
+ </child>
188
+ <child>
189
+ <object class="GtkStack" id="stack">
190
+ <signal name="notify::visible-child" handler="visible_child_changed"/>
191
+ </object>
192
+ </child>
193
+ </object>
194
+ </child>
195
+ </object>
196
+ </child>
197
+ </template>
198
+ </interface>
199
+ TEMPLATE
200
+ set_template(data: template)
201
+ bind_template_child("stack")
202
+ bind_template_child("gears")
203
+ bind_template_child("search")
204
+ bind_template_child("searchbar")
205
+ bind_template_child("searchentry")
206
+ bind_template_child("words")
207
+ bind_template_child("sidebar")
208
+ bind_template_callback_full("search_text_changed")
209
+ bind_template_callback_full("visible_child_changed")
210
+ end
211
+ end
212
+
213
+ def initialize(application)
214
+ menu_ui = <<~MENU
215
+ <?xml version="1.0" encoding="UTF-8"?>
216
+ <interface>
217
+ <menu id="menu">
218
+ <section>
219
+ <item>
220
+ <attribute name="label" translatable="yes">_Words</attribute>
221
+ <attribute name="action">win.show-words</attribute>
222
+ </item>
223
+ <item>
224
+ <attribute name="label" translatable="yes">_Preferences</attribute>
225
+ <attribute name="action">app.preferences</attribute>
226
+ </item>
227
+ </section>
228
+ <section>
229
+ <item>
230
+ <attribute name="label" translatable="yes">_Quit</attribute>
231
+ <attribute name="action">app.quit</attribute>
232
+ </item>
233
+ </section>
234
+ </menu>
235
+ </interface>
236
+ MENU
237
+ super(application: application)
238
+ builder = Gtk::Builder.new(string: menu_ui)
239
+ gears.menu_model = builder["menu"]
240
+ @settings = Gio::Settings.new("org.gtk.exampleapp")
241
+ @settings.bind("transition", stack, "transition-type", :default)
242
+ @settings.bind("show-words", sidebar, "reveal-child", :default)
243
+ search.bind_property("active", searchbar, "search-mode-enabled", :bidirectional)
244
+ sidebar.signal_connect "notify::reveal-child" do |_sidebar, _pspec|
245
+ update_words
246
+ end
247
+ action = @settings.create_action("show-words")
248
+ add_action(action)
249
+ end
250
+
251
+ def open(file)
252
+ basename = file.basename
253
+ scrolled = Gtk::ScrolledWindow.new
254
+ scrolled.hexpand = true
255
+ scrolled.vexpand = true
256
+ view = Gtk::TextView.new
257
+ view.editable = false
258
+ view.cursor_visible = false
259
+ scrolled.child = view
260
+ stack.add_titled(scrolled, basename, basename)
261
+ buffer = view.buffer
262
+ file.read do |stream|
263
+ buffer.text = stream.read.force_encoding(Encoding::UTF_8)
264
+ end
265
+ tag = buffer.create_tag
266
+ @settings.bind("font", tag, "font", :default)
267
+ buffer.apply_tag(tag, buffer.start_iter, buffer.end_iter)
268
+ search.sensitive = true
269
+ update_words
270
+ end
271
+
272
+ private
273
+
274
+ def search_text_changed(search_entry)
275
+ text = search_entry.text
276
+ return if text.empty?
277
+ tab = stack.visible_child
278
+ view = tab.child
279
+ buffer = view.buffer
280
+ range = buffer.start_iter.forward_search(text, :case_insensitive)
281
+ return unless range
282
+ buffer.select_range(range[0], range[1])
283
+ view.scroll_to_iter(range[0], 0.0, false, 0.0, 0.0)
284
+ end
285
+
286
+ def update_words
287
+ tab = stack.visible_child
288
+ return unless tab
289
+ view = tab.child
290
+ buffer = view.buffer
291
+ strings = buffer.text.downcase.scan(/[[:word:]]+/).uniq
292
+ while (child = words.first_child)
293
+ words.remove(child)
294
+ end
295
+ strings.each do |s|
296
+ row = Gtk::Button.new(label: s)
297
+ row.signal_connect("clicked") {searchentry.text = s}
298
+ words.insert(row, -1)
299
+ end
300
+ end
301
+
302
+ def visible_child_changed(stack, params)
303
+ return if stack.in_destruction?
304
+ searchbar.search_mode = false
305
+ update_words
306
+ end
307
+ end
308
+
309
+ class ExampleApp < Gtk::Application
310
+ def initialize
311
+ super("org.gtk.exampleapp", :handles_open)
312
+
313
+ signal_connect "startup" do |application|
314
+ [
315
+ "preferences",
316
+ "quit"
317
+ ].each do |action_name|
318
+ action = Gio::SimpleAction.new(action_name)
319
+ action.signal_connect("activate") do |_action, _parameter|
320
+ __send__("#{action_name}_activated")
321
+ end
322
+ application.add_action(action)
323
+ end
324
+ application.set_accels_for_action("app.quit", ["<Control>Q"])
325
+ end
326
+ signal_connect "activate" do |application|
327
+ window = ExampleAppWindow.new(application)
328
+ window.present
329
+ end
330
+ signal_connect "open" do |application, files, hint|
331
+ window = application.windows[0] || ExampleAppWindow.new(application)
332
+ files.each do |file|
333
+ window.open(file)
334
+ end
335
+ window.present
336
+ end
337
+ end
338
+
339
+ private
340
+
341
+ def preferences_activated
342
+ prefs = ExampleAppPrefs.new(active_window)
343
+ prefs.present
344
+ end
345
+
346
+ def quit_activated
347
+ quit
348
+ end
349
+ end
350
+
351
+ app = ExampleApp.new
352
+
353
+ # Gtk::Application#run needs C style argv ([prog, arg1, arg2, ...,argn]).
354
+ # The ARGV ruby variable only contains the arguments ([arg1, arg2, ...,argb])
355
+ # and not the program name. We have to add it explicitly.
356
+
357
+ app.run([$PROGRAM_NAME] + ARGV)
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <schemalist>
3
+ <schema path="/org/gtk/exampleapp/" id="org.gtk.exampleapp">
4
+ <key name="font" type="s">
5
+ <default>'Monospace 12'</default>
6
+ <summary>Font</summary>
7
+ <description>The font to be used for content.</description>
8
+ </key>
9
+ <key name="transition" type="s">
10
+ <choices>
11
+ <choice value='none'/>
12
+ <choice value='crossfade'/>
13
+ <choice value='slide-left-right'/>
14
+ </choices>
15
+ <default>'none'</default>
16
+ <summary>Transition</summary>
17
+ <description>The transition to use when switching tabs.</description>
18
+ </key>
19
+ <key name="show-words" type="b">
20
+ <default>false</default>
21
+ <summary>Show words</summary>
22
+ <description>Whether to show a word list in the sidebar</description>
23
+ </key>
24
+ </schema>
25
+ </schemalist>
@@ -0,0 +1,15 @@
1
+ # Step 9: Using properties
2
+
3
+ The original files are located in the following directory.
4
+
5
+ - https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application9
6
+
7
+ The original schema file is [here](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application9/org.gtk.exampleapp.gschema.xml) and the license is LGPL 2.1 or later.
8
+
9
+ Run `rake` before trying `exampleapp.rb`.
10
+
11
+ ```console
12
+ $ cd gtk4/sample/examples/application9
13
+ $ rake
14
+ $ ruby exampleapp.rb README.md Rakefile
15
+ ```
@@ -0,0 +1,27 @@
1
+ # Copyright (C) 2023 Ruby-GNOME Project Team
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License as published by the Free Software Foundation; either
6
+ # version 2.1 of the License, or (at your option) any later version.
7
+ #
8
+ # This library is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this library; if not, write to the Free Software
15
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
+
17
+ require "rake/clean"
18
+
19
+ task :default => "gschemas.compiled"
20
+
21
+ file "gschemas.compiled" => "org.gtk.exampleapp.gschema.xml" do
22
+ sh("glib-compile-schemas", ".")
23
+ end
24
+
25
+ CLEAN << "gschemas.compiled"
26
+
27
+ task :clean