gtk4 4.2.3 → 4.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +2 -2
- data/gtk4.gemspec +11 -1
- data/lib/gtk4/gesture-stylus.rb +29 -0
- data/lib/gtk4/loader.rb +2 -1
- data/sample/demos/gtk-demo/demo.rb +14 -3
- data/sample/demos/gtk-demo/glarea.rb +8 -3
- data/sample/demos/gtk-demo/main.rb +14 -1
- data/sample/demos/gtk-demo/paint.rb +347 -0
- data/sample/demos/gtk-demo/shortcut-triggers.rb +78 -0
- metadata +17 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b64a77d23e74b0a9ccc3983bc26d5df71f75e3c55b476513da6ac51e4e4c0c3
|
4
|
+
data.tar.gz: 7c34382193be7893a57df42cb86a388eb6340d07e4e4d6eb8f8c63b43ea64e8a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db222bd29ae3414e8cdc87dd2f20a5b97a2830e3362833af3c5d1c0b06c1a77767fa8b15a1c14807f3475a5c91bfe340c65d3a422318979419a1f066cfd38352
|
7
|
+
data.tar.gz: 1a3151f08c2073f33b3e5bdfce02346cc11660abb6f56842a0c68630dd69e2a9878d3bdcb5ef47f12170b3bbf5d568ccd535d0df29d5647bf098ba1bc21064cd
|
data/Rakefile
CHANGED
@@ -17,10 +17,10 @@
|
|
17
17
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
|
19
19
|
$LOAD_PATH.unshift("./../glib2/lib")
|
20
|
-
require "
|
20
|
+
require "gnome/rake/package-task"
|
21
21
|
|
22
22
|
package_name = File.basename(__dir__)
|
23
23
|
spec = Gem::Specification.load("#{package_name}.gemspec")
|
24
24
|
|
25
|
-
|
25
|
+
GNOME::Rake::PackageTask.define(spec, __dir__) do |package|
|
26
26
|
end
|
data/gtk4.gemspec
CHANGED
@@ -21,7 +21,17 @@ require_relative "../glib2/version"
|
|
21
21
|
Gem::Specification.new do |s|
|
22
22
|
s.name = "gtk4"
|
23
23
|
s.summary = "Ruby/GTK4 is a Ruby binding of GTK+-4.x."
|
24
|
-
s.description
|
24
|
+
s.description = "Ruby/GTK4 is a Ruby binding of GTK 4.x. It allows Ruby " +
|
25
|
+
"programmers to use the GTK graphics toolkit to make " +
|
26
|
+
"graphical user interfaces for their Ruby scripts. " +
|
27
|
+
"Many of the programs you use like file explorers, " +
|
28
|
+
"browsers, graphics programs etc. use GTK to make their " +
|
29
|
+
"GUI. In fact, there's a good chance that you're looking at " +
|
30
|
+
"a GTK window right now. All the GTK commands and widgets " +
|
31
|
+
"have been translated into Ruby, so Ruby programmers can " +
|
32
|
+
"write scripts that create windows instead of only " +
|
33
|
+
"using the command line. Visit our homepage for install " +
|
34
|
+
"instructions and tutorials."
|
25
35
|
s.author = "The Ruby-GNOME Project Team"
|
26
36
|
s.email = "ruby-gnome2-devel-en@lists.sourceforge.net"
|
27
37
|
s.homepage = "https://ruby-gnome.github.io/"
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Copyright (C) 2024 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
|
+
module Gtk
|
18
|
+
class GestureStylus
|
19
|
+
alias_method :backlog_raw, :backlog
|
20
|
+
def backlog
|
21
|
+
have_backlog, backlog = backlog_raw
|
22
|
+
if have_backlog
|
23
|
+
backlog
|
24
|
+
else
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/gtk4/loader.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2014-
|
1
|
+
# Copyright (C) 2014-2024 Ruby-GNOME Project Team
|
2
2
|
#
|
3
3
|
# This library is free software; you can redistribute it and/or
|
4
4
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -95,6 +95,7 @@ module Gtk
|
|
95
95
|
require_relative "file-chooser-dialog"
|
96
96
|
require_relative "font-chooser-dialog"
|
97
97
|
require_relative "gesture-multi-press"
|
98
|
+
require_relative "gesture-stylus"
|
98
99
|
require_relative "icon-theme"
|
99
100
|
require_relative "icon-view"
|
100
101
|
require_relative "image"
|
@@ -54,6 +54,8 @@ class GtkDemo < GLib::Object
|
|
54
54
|
install_property(GLib::Param::String.new("name", nil, nil, nil, :readable))
|
55
55
|
attr_reader :name
|
56
56
|
|
57
|
+
attr_reader :group
|
58
|
+
|
57
59
|
install_property(GLib::Param::String.new("title", nil, nil, nil, :readable))
|
58
60
|
attr_reader :title
|
59
61
|
|
@@ -66,9 +68,14 @@ class GtkDemo < GLib::Object
|
|
66
68
|
attr_reader :description
|
67
69
|
attr_accessor :children_model
|
68
70
|
|
69
|
-
def initialize(filename, title, description, keywords)
|
71
|
+
def initialize(filename, group, title, description, keywords)
|
70
72
|
super()
|
71
|
-
|
73
|
+
if filename.nil?
|
74
|
+
@name = nil
|
75
|
+
else
|
76
|
+
@name = File.basename(filename, ".rb")
|
77
|
+
end
|
78
|
+
@group = group
|
72
79
|
@title = title
|
73
80
|
@description = description
|
74
81
|
@keywords = keywords
|
@@ -76,7 +83,11 @@ class GtkDemo < GLib::Object
|
|
76
83
|
@children_model = nil
|
77
84
|
end
|
78
85
|
|
86
|
+
def group?
|
87
|
+
@name.nil?
|
88
|
+
end
|
89
|
+
|
79
90
|
def run(parent)
|
80
|
-
raise
|
91
|
+
raise NotImplementedError
|
81
92
|
end
|
82
93
|
end
|
@@ -21,7 +21,11 @@
|
|
21
21
|
# * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/AUTHORS
|
22
22
|
# * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/COPYING
|
23
23
|
|
24
|
-
|
24
|
+
begin
|
25
|
+
require "opengl"
|
26
|
+
rescue LoadError
|
27
|
+
$stderr.puts("opengl gem can't be loaded")
|
28
|
+
end
|
25
29
|
|
26
30
|
class GtkGLAreaDemo < GtkDemo
|
27
31
|
X_AXIS = 0
|
@@ -31,7 +35,8 @@ class GtkGLAreaDemo < GtkDemo
|
|
31
35
|
|
32
36
|
def initialize
|
33
37
|
super(__FILE__,
|
34
|
-
"OpenGL
|
38
|
+
"OpenGL",
|
39
|
+
"OpenGL Area",
|
35
40
|
"Gtk::GLArea is a widget that allows custom drawing using OpenGL calls.",
|
36
41
|
[])
|
37
42
|
end
|
@@ -319,5 +324,5 @@ class GtkGLAreaDemo < GtkDemo
|
|
319
324
|
box
|
320
325
|
end
|
321
326
|
|
322
|
-
GtkDemo.register(new)
|
327
|
+
GtkDemo.register(new) if defined?(GL)
|
323
328
|
end
|
@@ -55,6 +55,7 @@ end
|
|
55
55
|
|
56
56
|
|
57
57
|
def run_demo(demo, window)
|
58
|
+
return if demo.group?
|
58
59
|
demo_window = demo.run(window)
|
59
60
|
demo_window.transient_for = window
|
60
61
|
demo_window.modal = true
|
@@ -63,8 +64,19 @@ end
|
|
63
64
|
|
64
65
|
def create_demo_model(window)
|
65
66
|
store = Gio::ListStore.new(GtkDemo)
|
67
|
+
groups = {}
|
66
68
|
GtkDemo.all.each do |demo|
|
67
|
-
|
69
|
+
if demo.group
|
70
|
+
group = groups[demo.group]
|
71
|
+
if group.nil?
|
72
|
+
group = GtkDemo.new(nil, nil, demo.group, nil, [])
|
73
|
+
group.children_model = Gio::ListStore.new(GtkDemo)
|
74
|
+
end
|
75
|
+
group.children_model.append(demo)
|
76
|
+
store.append(group)
|
77
|
+
else
|
78
|
+
store.append(demo)
|
79
|
+
end
|
68
80
|
end
|
69
81
|
store
|
70
82
|
end
|
@@ -92,6 +104,7 @@ def select_item(selection, window, notebook, info_view)
|
|
92
104
|
notebook.sensitive = !!row
|
93
105
|
if row
|
94
106
|
demo = row.item
|
107
|
+
return if demo.group?
|
95
108
|
load_file(demo, notebook, info_view)
|
96
109
|
run_action = window.lookup_action("run")
|
97
110
|
run_action.enabled = true
|
@@ -0,0 +1,347 @@
|
|
1
|
+
# Copyright (C) 2024 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
|
+
# Original:
|
18
|
+
# https://gitlab.gnome.org/GNOME/gtk/-/blob/main/demos/gtk-demo/paint.c
|
19
|
+
#
|
20
|
+
# See the following for license information:
|
21
|
+
# * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/AUTHORS
|
22
|
+
# * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/COPYING
|
23
|
+
|
24
|
+
class MyDrawingArea < Gtk::Widget
|
25
|
+
type_register
|
26
|
+
|
27
|
+
attr_accessor :draw_color
|
28
|
+
attr_accessor :brush_size
|
29
|
+
attr_reader :gesture
|
30
|
+
def initialize
|
31
|
+
super
|
32
|
+
@draw_color = Gdk::RGBA.new(0, 0, 0, 1)
|
33
|
+
@brush_size = 1
|
34
|
+
@gesture = Gtk::GestureStylus.new
|
35
|
+
@context = nil
|
36
|
+
@gesture.signal_connect(:down) do |_, _x, _y|
|
37
|
+
#@context.new_path
|
38
|
+
end
|
39
|
+
@gesture.signal_connect(:motion) do |_, x, y|
|
40
|
+
tool = @gesture.device_tool
|
41
|
+
backlog = @gesture.backlog
|
42
|
+
if backlog
|
43
|
+
backlog.each_with_index do |time_coord, i|
|
44
|
+
puts("#{i}/#{backlog.size} #{time_coord.time}, #{time_coord.axes[1]}, #{time_coord.axes[2]}")
|
45
|
+
axes = time_coord.axes
|
46
|
+
if time_coord.flags.pressure?
|
47
|
+
pressure = axes[Gdk::AxisUse::PRESSURE.to_i]
|
48
|
+
else
|
49
|
+
pressure = 1.0
|
50
|
+
end
|
51
|
+
apply_stroke(tool,
|
52
|
+
axes[Gdk::AxisUse::X.to_i],
|
53
|
+
axes[Gdk::AxisUse::Y.to_i],
|
54
|
+
pressure)
|
55
|
+
end
|
56
|
+
else
|
57
|
+
pressure = @gesture.get_axis(:pressure) || 1.0
|
58
|
+
apply_stroke(tool, x, y, pressure)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
add_controller(@gesture)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
def apply_stroke(tool, x, y, pressure)
|
66
|
+
# TODO
|
67
|
+
if tool and tool.tool_type == Gdk::DeviceToolType::ERASER
|
68
|
+
else
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class PaintDemo < GtkDemo
|
74
|
+
def initialize
|
75
|
+
super(__FILE__,
|
76
|
+
nil,
|
77
|
+
"Paint",
|
78
|
+
"Demonstrates practical handling of drawing tablets in a real world " +
|
79
|
+
"usecase.",
|
80
|
+
["Gdk::DrawingArea", "Gtk::Gesture"])
|
81
|
+
end
|
82
|
+
|
83
|
+
def run(parent)
|
84
|
+
window = Gtk::Window.new
|
85
|
+
window.display = parent.display
|
86
|
+
|
87
|
+
drawing_area = MyDrawingArea.new
|
88
|
+
window.child = drawing_area
|
89
|
+
|
90
|
+
header_bar = Gtk::HeaderBar.new
|
91
|
+
|
92
|
+
color_button = Gtk::ColorDialogButton.new(Gtk::ColorDialog.new)
|
93
|
+
color_button.signal_connect("notify::rgba") do |_, _spec|
|
94
|
+
color = color_button.rgba
|
95
|
+
drawing_area.draw_color = color
|
96
|
+
end
|
97
|
+
# drawing_area.signal_connect("color-set") do |_, color|
|
98
|
+
# color_button.rgba = color
|
99
|
+
# end
|
100
|
+
color_button.rgba = Gdk::RGBA.new(0, 0, 0, 1);
|
101
|
+
header_bar.pack_end(color_button)
|
102
|
+
|
103
|
+
check_button = Gtk::CheckButton.new("Stylus only")
|
104
|
+
check_button.bind_property("active",
|
105
|
+
drawing_area.gesture,
|
106
|
+
"stylus-only",
|
107
|
+
:sync_create)
|
108
|
+
header_bar.pack_start(check_button)
|
109
|
+
|
110
|
+
window.titlebar = header_bar
|
111
|
+
window.title = "Paint"
|
112
|
+
|
113
|
+
window.present
|
114
|
+
|
115
|
+
window
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
# We need to set up our state when we realize the GtkGLArea widget
|
120
|
+
def realize(gl_area)
|
121
|
+
@rotation_angles = [0.0] * N_AXISES
|
122
|
+
|
123
|
+
GL.load_lib
|
124
|
+
|
125
|
+
gl_area.make_current
|
126
|
+
api_name = gl_area.api.nick
|
127
|
+
vertex_path = "/glarea/glarea-#{api_name}.vs.glsl"
|
128
|
+
fragment_path = "/glarea/glarea-#{api_name}.fs.glsl"
|
129
|
+
init_buffers
|
130
|
+
init_shaders(vertex_path, fragment_path)
|
131
|
+
end
|
132
|
+
|
133
|
+
# The object we are drawing
|
134
|
+
VERTEX_DATA = [
|
135
|
+
0.0, 0.5, 0.0, 1.0,
|
136
|
+
0.5, -0.366, 0.0, 1.0,
|
137
|
+
-0.5, -0.366, 0.0, 1.0,
|
138
|
+
]
|
139
|
+
|
140
|
+
def init_buffers
|
141
|
+
# We only use one VAO, so we always keep it bound
|
142
|
+
vao_buffer = " " * Fiddle::SIZEOF_UINT32_T
|
143
|
+
GL.GenVertexArrays(1, vao_buffer)
|
144
|
+
@vao = vao_buffer.unpack1("L")
|
145
|
+
GL.BindVertexArray(@vao)
|
146
|
+
|
147
|
+
# This is the buffer that holds the vertices
|
148
|
+
position_buffer = " " * Fiddle::SIZEOF_UINT32_T
|
149
|
+
GL.GenBuffers(1, position_buffer)
|
150
|
+
GL.GenBuffers(1, position_buffer)
|
151
|
+
@position = position_buffer.unpack1("L")
|
152
|
+
GL.BindBuffer(GL::ARRAY_BUFFER, @position)
|
153
|
+
GL.BufferData(GL::ARRAY_BUFFER,
|
154
|
+
Fiddle::SIZEOF_FLOAT * VERTEX_DATA.size,
|
155
|
+
VERTEX_DATA.pack("f*"),
|
156
|
+
GL::STATIC_DRAW)
|
157
|
+
GL.BindBuffer(GL::ARRAY_BUFFER, 0)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Initialize the shaders and link them into a program
|
161
|
+
def init_shaders(vertex_path, fragment_path)
|
162
|
+
@program = nil
|
163
|
+
vertex = 0
|
164
|
+
fragment = 0
|
165
|
+
|
166
|
+
begin
|
167
|
+
source = Gio::Resources.lookup_data(vertex_path)
|
168
|
+
vertex = create_shader(GL::VERTEX_SHADER, source.to_s)
|
169
|
+
return if vertex.zero?
|
170
|
+
|
171
|
+
source = Gio::Resources.lookup_data(fragment_path)
|
172
|
+
fragment = create_shader(GL::FRAGMENT_SHADER, source.to_s)
|
173
|
+
return if fragment.zero?
|
174
|
+
|
175
|
+
@program = GL.CreateProgram
|
176
|
+
return if @program.zero?
|
177
|
+
|
178
|
+
GL.AttachShader(@program, vertex)
|
179
|
+
GL.AttachShader(@program, fragment)
|
180
|
+
|
181
|
+
GL.LinkProgram(@program)
|
182
|
+
|
183
|
+
program_ok_buffer = " " * Fiddle::SIZEOF_UINT32_T
|
184
|
+
GL.GetProgramiv(@program, GL::LINK_STATUS, program_ok_buffer)
|
185
|
+
program_ok = (program_ok_buffer.unpack1("L") == GL::TRUE)
|
186
|
+
unless program_ok
|
187
|
+
log_length_buffer = " " * Fiddle::SIZEOF_UINT32_T
|
188
|
+
GL.GetProgramiv(@program, GL::INFO_LOG_LENGTH, log_length_buffer)
|
189
|
+
log_length = log_length_buffer.unpack1("L")
|
190
|
+
log = " " * log_length
|
191
|
+
GL.GetProgramInfoLog(@program, log_length, nil, log)
|
192
|
+
$stderr.puts("Linking failure:")
|
193
|
+
$stderr.puts(log)
|
194
|
+
GL.DeleteProgram(@program)
|
195
|
+
@program = nil
|
196
|
+
return
|
197
|
+
end
|
198
|
+
|
199
|
+
# Get the location of the "mvp" uniform
|
200
|
+
@mvp_location = GL.GetUniformLocation(@program, "mvp")
|
201
|
+
|
202
|
+
GL.DetachShader(@program, vertex)
|
203
|
+
GL.DetachShader(@program, fragment)
|
204
|
+
ensure
|
205
|
+
GL.DeleteShader(vertex) if vertex.zero?
|
206
|
+
GL.DeleteShader(fragment) if fragment.zero?
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# Create and compile a shader
|
211
|
+
def create_shader(type, source)
|
212
|
+
shader = GL.CreateShader(type)
|
213
|
+
GL.ShaderSource(shader, 1, [source].pack("p"), nil)
|
214
|
+
GL.CompileShader(shader)
|
215
|
+
|
216
|
+
shader_ok_buffer = " " * Fiddle::SIZEOF_UINT32_T
|
217
|
+
GL.GetShaderiv(shader, GL::COMPILE_STATUS, shader_ok_buffer)
|
218
|
+
shader_ok = (shader_ok_buffer.unpack1("L") == GL::TRUE)
|
219
|
+
unless shader_ok
|
220
|
+
log_length_buffer = " " * Fiddle::SIZEOF_UINT32_t
|
221
|
+
GL.GetShaderiv(shader, GL::INFO_LOG_LENGTH, log_length_buffer)
|
222
|
+
log_length = log_length_buffer.unpack1("L")
|
223
|
+
log = " " * log_length
|
224
|
+
GL.GetShaderInfoLog(shader, log_length, nil, buffer)
|
225
|
+
type_name = (type == GL::VERTEX_SHADER ? "vertex" : "fragment")
|
226
|
+
$stderr.puts("Compile failure in #{type_name} shader:")
|
227
|
+
$stderr.puts(log)
|
228
|
+
GL.DeleteShader(shader)
|
229
|
+
return 0
|
230
|
+
end
|
231
|
+
|
232
|
+
shader
|
233
|
+
end
|
234
|
+
|
235
|
+
# We should tear down the state when unrealizing
|
236
|
+
def unrealize(gl_area)
|
237
|
+
gl_area.make_current
|
238
|
+
GL.DeleteBuffers(1, [[@position].pack("L")].pack("p"))
|
239
|
+
GL.DeleteProgram(@program)
|
240
|
+
end
|
241
|
+
|
242
|
+
def compute_mvp(phi, theta, psi)
|
243
|
+
x = phi * (Math::PI / 180.0)
|
244
|
+
y = theta * (Math::PI / 180.0)
|
245
|
+
z = psi * (Math::PI / 180.0)
|
246
|
+
c1 = Math.cos(x)
|
247
|
+
s1 = Math.sin(x)
|
248
|
+
c2 = Math.cos(y)
|
249
|
+
s2 = Math.sin(y)
|
250
|
+
c3 = Math.cos(z)
|
251
|
+
s3 = Math.sin(z)
|
252
|
+
c3c2 = c3 * c2
|
253
|
+
s3c1 = s3 * c1
|
254
|
+
c3s2s1 = c3 * s2 * s1
|
255
|
+
s3s1 = s3 * s1
|
256
|
+
c3s2c1 = c3 * s2 * c1
|
257
|
+
s3c2 = s3 * c2
|
258
|
+
c3c1 = c3 * c1
|
259
|
+
s3s2s1 = s3 * s2 * s1
|
260
|
+
c3s1 = c3 * s1
|
261
|
+
s3s2c1 = s3 * s2 * c1
|
262
|
+
c2s1 = c2 * s1
|
263
|
+
c2c1 = c2 * c1
|
264
|
+
|
265
|
+
# apply all three rotations using the three matrices:
|
266
|
+
#
|
267
|
+
# ⎡ c3 s3 0 ⎤ ⎡ c2 0 -s2 ⎤ ⎡ 1 0 0 ⎤
|
268
|
+
# ⎢ -s3 c3 0 ⎥ ⎢ 0 1 0 ⎥ ⎢ 0 c1 s1 ⎥
|
269
|
+
# ⎣ 0 0 1 ⎦ ⎣ s2 0 c2 ⎦ ⎣ 0 -s1 c1 ⎦
|
270
|
+
mvp = [0.0] * 16
|
271
|
+
mvp[0] = c3c2; mvp[4] = s3c1 + c3s2s1; mvp[8] = s3s1 - c3s2c1; mvp[12] = 0.0;
|
272
|
+
mvp[1] = -s3c2; mvp[5] = c3c1 - s3s2s1; mvp[9] = c3s1 + s3s2c1; mvp[13] = 0.0;
|
273
|
+
mvp[2] = s2; mvp[6] = -c2s1; mvp[10] = c2c1; mvp[14] = 0.0;
|
274
|
+
mvp[3] = 0.0; mvp[7] = 0.0; mvp[11] = 0.0; mvp[15] = 1.0;
|
275
|
+
mvp
|
276
|
+
end
|
277
|
+
|
278
|
+
def draw_triangle
|
279
|
+
# Compute the model view projection matrix using the
|
280
|
+
# rotation angles specified through the GtkRange widgets
|
281
|
+
mvp = compute_mvp(@rotation_angles[X_AXIS],
|
282
|
+
@rotation_angles[Y_AXIS],
|
283
|
+
@rotation_angles[Z_AXIS])
|
284
|
+
|
285
|
+
# Use our shaders
|
286
|
+
GL.UseProgram(@program)
|
287
|
+
|
288
|
+
# Update the "mvp" matrix we use in the shader
|
289
|
+
GL.UniformMatrix4fv(@mvp_location, 1, GL::FALSE, mvp.pack("f*"))
|
290
|
+
|
291
|
+
# Use the vertices in our buffer
|
292
|
+
GL.BindBuffer(GL::ARRAY_BUFFER, @position)
|
293
|
+
GL.EnableVertexAttribArray(0)
|
294
|
+
GL.VertexAttribPointer(0, 4, GL::FLOAT, GL::FALSE, 0, 0)
|
295
|
+
|
296
|
+
# Draw the three vertices as a triangle
|
297
|
+
GL.DrawArrays(GL::TRIANGLES, 0, 3)
|
298
|
+
|
299
|
+
# We finished using the buffers and program
|
300
|
+
GL.DisableVertexAttribArray(0)
|
301
|
+
GL.BindBuffer(GL::ARRAY_BUFFER, 0)
|
302
|
+
GL.UseProgram(0)
|
303
|
+
end
|
304
|
+
|
305
|
+
def render(gl_area)
|
306
|
+
# Clear the viewport
|
307
|
+
GL.ClearColor(0.5, 0.5, 0.5, 1.0)
|
308
|
+
GL.Clear(GL::COLOR_BUFFER_BIT)
|
309
|
+
|
310
|
+
# Draw our object
|
311
|
+
draw_triangle
|
312
|
+
|
313
|
+
# Flush the contents of the pipeline
|
314
|
+
GL.Flush
|
315
|
+
|
316
|
+
true
|
317
|
+
end
|
318
|
+
|
319
|
+
def create_axis_slider(gl_area, axis)
|
320
|
+
box = Gtk::Box.new(:horizontal)
|
321
|
+
case axis
|
322
|
+
when X_AXIS
|
323
|
+
text = "X axis"
|
324
|
+
when Y_AXIS
|
325
|
+
text = "Y axis"
|
326
|
+
when Z_AXIS
|
327
|
+
text = "Z axis"
|
328
|
+
end
|
329
|
+
label = Gtk::Label.new(text)
|
330
|
+
box.append(label)
|
331
|
+
|
332
|
+
adjustment = Gtk::Adjustment.new(0.0, 0.0, 360.0, 1.0, 12.0, 0.0)
|
333
|
+
adjustment.signal_connect("value-changed") do
|
334
|
+
@rotation_angles[axis] = adjustment.value
|
335
|
+
# Update the contents of the GL drawing area
|
336
|
+
gl_area.queue_draw
|
337
|
+
end
|
338
|
+
|
339
|
+
slider = Gtk::Scale.new(:horizontal, adjustment)
|
340
|
+
box.append(slider)
|
341
|
+
slider.hexpand = true
|
342
|
+
|
343
|
+
box
|
344
|
+
end
|
345
|
+
|
346
|
+
GtkDemo.register(new)
|
347
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# Copyright (C) 2024 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
|
+
# Original:
|
18
|
+
# https://gitlab.gnome.org/GNOME/gtk/-/blob/main/demos/gtk-demo/shortcut_triggers.c
|
19
|
+
#
|
20
|
+
# See the following for license information:
|
21
|
+
# * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/AUTHORS
|
22
|
+
# * https://gitlab.gnome.org/GNOME/gtk/-/blob/main/COPYING
|
23
|
+
|
24
|
+
class ShortcutTriggersDemo < GtkDemo
|
25
|
+
def initialize
|
26
|
+
super(__FILE__,
|
27
|
+
nil,
|
28
|
+
"Shortcuts",
|
29
|
+
<<-DESCRIPTION,
|
30
|
+
Gtk::Shortcut is the abstraction used by GTK to handle shortcuts from
|
31
|
+
keyboard or other input devices.
|
32
|
+
|
33
|
+
Shortcut triggers can be used to weave complex sequences of key
|
34
|
+
presses into sophisticated mechanisms to activate shortcuts.
|
35
|
+
|
36
|
+
This demo code shows creative ways to do that.
|
37
|
+
DESCRIPTION
|
38
|
+
["Gtk::ShortcutController"])
|
39
|
+
end
|
40
|
+
|
41
|
+
def run(parent)
|
42
|
+
window = Gtk::Window.new
|
43
|
+
window.display = parent.display
|
44
|
+
window.title = "Shortcuts"
|
45
|
+
window.set_default_size(200, -1)
|
46
|
+
window.resizable = false
|
47
|
+
|
48
|
+
list = Gtk::ListBox.new
|
49
|
+
list.margin_top = 6
|
50
|
+
list.margin_bottom = 6
|
51
|
+
list.margin_start = 6
|
52
|
+
list.margin_end = 6
|
53
|
+
window.child = list
|
54
|
+
|
55
|
+
[
|
56
|
+
["Press Ctrl-g", Gtk::KeyvalTrigger.new(Gdk::Keyval::KEY_g, :control_mask)],
|
57
|
+
["Press x", Gtk::KeyvalTrigger.new(Gdk::Keyval::KEY_x, 0)],
|
58
|
+
].each do |label, trigger|
|
59
|
+
row = Gtk::Label.new(label)
|
60
|
+
list.append(row)
|
61
|
+
controller = Gtk::ShortcutController.new
|
62
|
+
controller.scope = :global
|
63
|
+
row.add_controller(controller)
|
64
|
+
|
65
|
+
action = Gtk::CallbackAction.new do
|
66
|
+
puts("activated: #{row.label}\n")
|
67
|
+
end
|
68
|
+
shortcut = Gtk::Shortcut.new(trigger, action)
|
69
|
+
controller.add_shortcut(shortcut)
|
70
|
+
end
|
71
|
+
|
72
|
+
window.present
|
73
|
+
|
74
|
+
window
|
75
|
+
end
|
76
|
+
|
77
|
+
GtkDemo.register(new)
|
78
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gtk4
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.2.
|
4
|
+
version: 4.2.5
|
5
5
|
platform: ruby
|
6
|
+
original_platform: ''
|
6
7
|
authors:
|
7
8
|
- The Ruby-GNOME Project Team
|
8
9
|
bindir: bin
|
9
10
|
cert_chain: []
|
10
|
-
date: 2024-
|
11
|
+
date: 2024-12-15 00:00:00.000000000 Z
|
11
12
|
dependencies:
|
12
13
|
- !ruby/object:Gem::Dependency
|
13
14
|
name: atk
|
@@ -15,29 +16,35 @@ dependencies:
|
|
15
16
|
requirements:
|
16
17
|
- - '='
|
17
18
|
- !ruby/object:Gem::Version
|
18
|
-
version: 4.2.
|
19
|
+
version: 4.2.5
|
19
20
|
type: :runtime
|
20
21
|
prerelease: false
|
21
22
|
version_requirements: !ruby/object:Gem::Requirement
|
22
23
|
requirements:
|
23
24
|
- - '='
|
24
25
|
- !ruby/object:Gem::Version
|
25
|
-
version: 4.2.
|
26
|
+
version: 4.2.5
|
26
27
|
- !ruby/object:Gem::Dependency
|
27
28
|
name: gdk4
|
28
29
|
requirement: !ruby/object:Gem::Requirement
|
29
30
|
requirements:
|
30
31
|
- - '='
|
31
32
|
- !ruby/object:Gem::Version
|
32
|
-
version: 4.2.
|
33
|
+
version: 4.2.5
|
33
34
|
type: :runtime
|
34
35
|
prerelease: false
|
35
36
|
version_requirements: !ruby/object:Gem::Requirement
|
36
37
|
requirements:
|
37
38
|
- - '='
|
38
39
|
- !ruby/object:Gem::Version
|
39
|
-
version: 4.2.
|
40
|
-
description: Ruby/GTK4 is a Ruby binding of GTK
|
40
|
+
version: 4.2.5
|
41
|
+
description: Ruby/GTK4 is a Ruby binding of GTK 4.x. It allows Ruby programmers to
|
42
|
+
use the GTK graphics toolkit to make graphical user interfaces for their Ruby scripts.
|
43
|
+
Many of the programs you use like file explorers, browsers, graphics programs etc.
|
44
|
+
use GTK to make their GUI. In fact, there's a good chance that you're looking at
|
45
|
+
a GTK window right now. All the GTK commands and widgets have been translated into
|
46
|
+
Ruby, so Ruby programmers can write scripts that create windows instead of only
|
47
|
+
using the command line. Visit our homepage for install instructions and tutorials.
|
41
48
|
email: ruby-gnome2-devel-en@lists.sourceforge.net
|
42
49
|
executables: []
|
43
50
|
extensions:
|
@@ -82,6 +89,7 @@ files:
|
|
82
89
|
- lib/gtk4/font-chooser-dialog.rb
|
83
90
|
- lib/gtk4/gdk-display.rb
|
84
91
|
- lib/gtk4/gesture-multi-press.rb
|
92
|
+
- lib/gtk4/gesture-stylus.rb
|
85
93
|
- lib/gtk4/icon-theme.rb
|
86
94
|
- lib/gtk4/icon-view.rb
|
87
95
|
- lib/gtk4/image.rb
|
@@ -133,6 +141,8 @@ files:
|
|
133
141
|
- sample/demos/gtk-demo/main-listitem.ui
|
134
142
|
- sample/demos/gtk-demo/main.rb
|
135
143
|
- sample/demos/gtk-demo/main.ui
|
144
|
+
- sample/demos/gtk-demo/paint.rb
|
145
|
+
- sample/demos/gtk-demo/shortcut-triggers.rb
|
136
146
|
- sample/examples/README.md
|
137
147
|
- sample/examples/action-namespace.rb
|
138
148
|
- sample/examples/application1/README.md
|