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,171 @@
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/application5/exampleapp.c
21
+ # * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application5/exampleappwin.c
22
+ # * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application5/window.ui
23
+ # * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application5/gears-menu.ui
24
+ # License: LGPL2.1-or-later
25
+
26
+ # GSETTINGS_SCHEMA_DIR must be set before requiring "gtk4" gem because it is used in the GIO initialization.
27
+
28
+ if File.exist?(File.join(__dir__, "gschemas.compiled"))
29
+ ENV["GSETTINGS_SCHEMA_DIR"] = __dir__
30
+ else
31
+ raise %{gschemas.compiled doesn't exist. Run "rake" to generate it.}
32
+ end
33
+
34
+ require "gtk4"
35
+
36
+ class ExampleAppWindow < Gtk::ApplicationWindow
37
+ type_register
38
+ class << self
39
+ def init
40
+ template = <<~TEMPLATE
41
+ <?xml version="1.0" encoding="UTF-8"?>
42
+ <interface>
43
+ <template class="ExampleAppWindow" parent="GtkApplicationWindow">
44
+ <property name="title" translatable="yes">Example Application</property>
45
+ <property name="default-width">600</property>
46
+ <property name="default-height">400</property>
47
+ <child type="titlebar">
48
+ <object class="GtkHeaderBar" id="header">
49
+ <child type="title">
50
+ <object class="GtkStackSwitcher" id="tabs">
51
+ <property name="stack">stack</property>
52
+ </object>
53
+ </child>
54
+ <child type="end">
55
+ <object class="GtkMenuButton" id="gears">
56
+ <property name="direction">none</property>
57
+ </object>
58
+ </child>
59
+ </object>
60
+ </child>
61
+ <child>
62
+ <object class="GtkBox" id="content_box">
63
+ <property name="orientation">vertical</property>
64
+ <child>
65
+ <object class="GtkStack" id="stack"/>
66
+ </child>
67
+ </object>
68
+ </child>
69
+ </template>
70
+ </interface>
71
+ TEMPLATE
72
+ set_template(data: template)
73
+ bind_template_child("stack")
74
+ bind_template_child("gears")
75
+ end
76
+ end
77
+
78
+ def initialize(application)
79
+ menu_ui = <<~MENU
80
+ <?xml version="1.0" encoding="UTF-8"?>
81
+ <interface>
82
+ <menu id="menu">
83
+ <section>
84
+ <item>
85
+ <attribute name="label" translatable="yes">_Preferences</attribute>
86
+ <attribute name="action">app.preferences</attribute>
87
+ </item>
88
+ </section>
89
+ <section>
90
+ <item>
91
+ <attribute name="label" translatable="yes">_Quit</attribute>
92
+ <attribute name="action">app.quit</attribute>
93
+ </item>
94
+ </section>
95
+ </menu>
96
+ </interface>
97
+ MENU
98
+ super(application: application)
99
+ builder = Gtk::Builder.new(string: menu_ui)
100
+ gears.menu_model = builder["menu"]
101
+ @settings = Gio::Settings.new("org.gtk.exampleapp")
102
+ @settings.bind("transition", stack, "transition-type", :default)
103
+ end
104
+
105
+ def open(file)
106
+ basename = file.basename
107
+ scrolled = Gtk::ScrolledWindow.new
108
+ scrolled.hexpand = true
109
+ scrolled.vexpand = true
110
+ view = Gtk::TextView.new
111
+ view.editable = false
112
+ view.cursor_visible = false
113
+ scrolled.child = view
114
+ stack.add_titled(scrolled, basename, basename)
115
+ buffer = view.buffer
116
+ file.read do |stream|
117
+ buffer.text = stream.read.force_encoding(Encoding::UTF_8)
118
+ end
119
+ tag = buffer.create_tag
120
+ @settings.bind("font", tag, "font", :default)
121
+ buffer.apply_tag(tag, buffer.start_iter, buffer.end_iter)
122
+ end
123
+ end
124
+
125
+ class ExampleApp < Gtk::Application
126
+ def initialize
127
+ super("org.gtk.exampleapp", :handles_open)
128
+
129
+ signal_connect "startup" do |application|
130
+ [
131
+ "preferences",
132
+ "quit"
133
+ ].each do |action_name|
134
+ action = Gio::SimpleAction.new(action_name)
135
+ action.signal_connect("activate") do |_action, _parameter|
136
+ __send__("#{action_name}_activated")
137
+ end
138
+ application.add_action(action)
139
+ end
140
+ application.set_accels_for_action("app.quit", ["<Control>Q"])
141
+ end
142
+ signal_connect "activate" do |application|
143
+ window = ExampleAppWindow.new(application)
144
+ window.present
145
+ end
146
+ signal_connect "open" do |application, files, hint|
147
+ window = application.windows[0] || ExampleAppWindow.new(application)
148
+ files.each do |file|
149
+ window.open(file)
150
+ end
151
+ window.present
152
+ end
153
+ end
154
+
155
+ private
156
+
157
+ def preferences_activated
158
+ end
159
+
160
+ def quit_activated
161
+ quit
162
+ end
163
+ end
164
+
165
+ app = ExampleApp.new
166
+
167
+ # Gtk::Application#run needs C style argv ([prog, arg1, arg2, ...,argn]).
168
+ # The ARGV ruby variable only contains the arguments ([arg1, arg2, ...,argb])
169
+ # and not the program name. We have to add it explicitly.
170
+
171
+ app.run([$PROGRAM_NAME] + ARGV)
@@ -0,0 +1,20 @@
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
+ </schema>
20
+ </schemalist>
@@ -0,0 +1,15 @@
1
+ # Step 6: Add a preference dialog
2
+
3
+ The original files are located in the following directory.
4
+
5
+ - https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application6
6
+
7
+ The original schema file is [here](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application6/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/application6
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
@@ -0,0 +1,265 @@
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/application6/exampleapp.c
21
+ # * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application6/exampleappwin.c
22
+ # * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application6/exampleappprefs.c
23
+ # * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application6/window.ui
24
+ # * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application6/gears-menu.ui
25
+ # * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application6/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="GtkMenuButton" id="gears">
148
+ <property name="direction">none</property>
149
+ </object>
150
+ </child>
151
+ </object>
152
+ </child>
153
+ <child>
154
+ <object class="GtkBox" id="content_box">
155
+ <property name="orientation">vertical</property>
156
+ <child>
157
+ <object class="GtkStack" id="stack"/>
158
+ </child>
159
+ </object>
160
+ </child>
161
+ </template>
162
+ </interface>
163
+ TEMPLATE
164
+ set_template(data: template)
165
+ bind_template_child("stack")
166
+ bind_template_child("gears")
167
+ end
168
+ end
169
+
170
+ def initialize(application)
171
+ menu_ui = <<~MENU
172
+ <?xml version="1.0" encoding="UTF-8"?>
173
+ <interface>
174
+ <menu id="menu">
175
+ <section>
176
+ <item>
177
+ <attribute name="label" translatable="yes">_Preferences</attribute>
178
+ <attribute name="action">app.preferences</attribute>
179
+ </item>
180
+ </section>
181
+ <section>
182
+ <item>
183
+ <attribute name="label" translatable="yes">_Quit</attribute>
184
+ <attribute name="action">app.quit</attribute>
185
+ </item>
186
+ </section>
187
+ </menu>
188
+ </interface>
189
+ MENU
190
+ super(application: application)
191
+ builder = Gtk::Builder.new(string: menu_ui)
192
+ gears.menu_model = builder["menu"]
193
+ @settings = Gio::Settings.new("org.gtk.exampleapp")
194
+ @settings.bind("transition", stack, "transition-type", :default)
195
+ end
196
+
197
+ def open(file)
198
+ basename = file.basename
199
+ scrolled = Gtk::ScrolledWindow.new
200
+ scrolled.hexpand = true
201
+ scrolled.vexpand = true
202
+ view = Gtk::TextView.new
203
+ view.editable = false
204
+ view.cursor_visible = false
205
+ scrolled.child = view
206
+ stack.add_titled(scrolled, basename, basename)
207
+ buffer = view.buffer
208
+ file.read do |stream|
209
+ buffer.text = stream.read.force_encoding(Encoding::UTF_8)
210
+ end
211
+ tag = buffer.create_tag
212
+ @settings.bind("font", tag, "font", :default)
213
+ buffer.apply_tag(tag, buffer.start_iter, buffer.end_iter)
214
+ end
215
+ end
216
+
217
+ class ExampleApp < Gtk::Application
218
+ def initialize
219
+ super("org.gtk.exampleapp", :handles_open)
220
+
221
+ signal_connect "startup" do |application|
222
+ [
223
+ "preferences",
224
+ "quit"
225
+ ].each do |action_name|
226
+ action = Gio::SimpleAction.new(action_name)
227
+ action.signal_connect("activate") do |_action, _parameter|
228
+ __send__("#{action_name}_activated")
229
+ end
230
+ application.add_action(action)
231
+ end
232
+ application.set_accels_for_action("app.quit", ["<Control>Q"])
233
+ end
234
+ signal_connect "activate" do |application|
235
+ window = ExampleAppWindow.new(application)
236
+ window.present
237
+ end
238
+ signal_connect "open" do |application, files, hint|
239
+ window = application.windows[0] || ExampleAppWindow.new(application)
240
+ files.each do |file|
241
+ window.open(file)
242
+ end
243
+ window.present
244
+ end
245
+ end
246
+
247
+ private
248
+
249
+ def preferences_activated
250
+ prefs = ExampleAppPrefs.new(active_window)
251
+ prefs.present
252
+ end
253
+
254
+ def quit_activated
255
+ quit
256
+ end
257
+ end
258
+
259
+ app = ExampleApp.new
260
+
261
+ # Gtk::Application#run needs C style argv ([prog, arg1, arg2, ...,argn]).
262
+ # The ARGV ruby variable only contains the arguments ([arg1, arg2, ...,argb])
263
+ # and not the program name. We have to add it explicitly.
264
+
265
+ app.run([$PROGRAM_NAME] + ARGV)
@@ -0,0 +1,20 @@
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
+ </schema>
20
+ </schemalist>
@@ -0,0 +1,15 @@
1
+ # Step 7: Add a search bar
2
+
3
+ The original files are located in the following directory.
4
+
5
+ - https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application7
6
+
7
+ The original schema file is [here](https://gitlab.gnome.org/GNOME/gtk/-/blob/main/examples/application7/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/application7
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