rabbit 3.0.5 → 4.0.1

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.
Files changed (241) hide show
  1. checksums.yaml +4 -4
  2. data/data/locale/ja/LC_MESSAGES/rabbit.mo +0 -0
  3. data/doc/_config.yml +2 -2
  4. data/doc/en/news.rd +63 -0
  5. data/doc/ja/news.rd +63 -0
  6. data/lib/rabbit/actions.rb +446 -0
  7. data/lib/rabbit/author-configuration.rb +7 -10
  8. data/lib/rabbit/canvas.rb +74 -42
  9. data/lib/rabbit/command/rabbit-slide.rb +11 -13
  10. data/lib/rabbit/command/rabbit-theme.rb +10 -12
  11. data/lib/rabbit/command/rabbit.rb +31 -43
  12. data/lib/rabbit/console.rb +20 -22
  13. data/lib/rabbit/dependency-canvas.rb +2 -2
  14. data/lib/rabbit/element/base.rb +93 -6
  15. data/lib/rabbit/element/block-element.rb +17 -1
  16. data/lib/rabbit/element/block.rb +17 -1
  17. data/lib/rabbit/element/container-element.rb +59 -3
  18. data/lib/rabbit/element/description-list.rb +18 -2
  19. data/lib/rabbit/element/enum-list.rb +18 -2
  20. data/lib/rabbit/element/footnote.rb +18 -2
  21. data/lib/rabbit/element/image-title-slide.rb +17 -1
  22. data/lib/rabbit/element/image.rb +32 -2
  23. data/lib/rabbit/element/index-slide.rb +29 -13
  24. data/lib/rabbit/element/item-list.rb +18 -2
  25. data/lib/rabbit/element/method-list.rb +18 -2
  26. data/lib/rabbit/element/poppler-page.rb +17 -1
  27. data/lib/rabbit/element/poppler-slide.rb +18 -2
  28. data/lib/rabbit/element/poppler-title-slide.rb +18 -2
  29. data/lib/rabbit/element/preformatted.rb +18 -2
  30. data/lib/rabbit/element/slide-element.rb +29 -2
  31. data/lib/rabbit/element/slide.rb +18 -2
  32. data/lib/rabbit/element/syntax-highlighting.rb +17 -1
  33. data/lib/rabbit/element/table.rb +19 -3
  34. data/lib/rabbit/element/tag.rb +18 -2
  35. data/lib/rabbit/element/text-block-element.rb +18 -2
  36. data/lib/rabbit/element/text-container-element.rb +41 -2
  37. data/lib/rabbit/element/text-element.rb +17 -1
  38. data/lib/rabbit/element/text-renderer.rb +17 -1
  39. data/lib/rabbit/element/text.rb +4 -4
  40. data/lib/rabbit/element/title-slide.rb +19 -3
  41. data/lib/rabbit/element/video.rb +157 -56
  42. data/lib/rabbit/element.rb +20 -20
  43. data/lib/rabbit/formatter.rb +18 -1
  44. data/lib/rabbit/frame.rb +101 -93
  45. data/lib/rabbit/front.rb +11 -4
  46. data/lib/rabbit/gem-finder.rb +4 -8
  47. data/lib/rabbit/gem-pusher.rb +4 -4
  48. data/lib/rabbit/gesture/handler.rb +26 -21
  49. data/lib/rabbit/graffiti/config-dialog.rb +18 -2
  50. data/lib/rabbit/graffiti/processor.rb +20 -4
  51. data/lib/rabbit/gtk.rb +48 -14
  52. data/lib/rabbit/html/generator.rb +18 -18
  53. data/{test/helper/fixture.rb → lib/rabbit/icon.rb} +16 -6
  54. data/lib/rabbit/image/base.rb +7 -6
  55. data/lib/rabbit/image/default.rb +17 -1
  56. data/lib/rabbit/image/dia.rb +2 -2
  57. data/lib/rabbit/image/eps.rb +16 -2
  58. data/lib/rabbit/image/gimp.rb +28 -11
  59. data/lib/rabbit/image/mermaid.rb +3 -3
  60. data/lib/rabbit/image/pdf.rb +3 -3
  61. data/lib/rabbit/image/svg.rb +2 -2
  62. data/lib/rabbit/image.rb +8 -8
  63. data/lib/rabbit/info-window.rb +55 -18
  64. data/lib/rabbit/key-handler.rb +381 -0
  65. data/lib/rabbit/keys.rb +31 -2
  66. data/lib/rabbit/logger/base.rb +17 -1
  67. data/lib/rabbit/logger/gui.rb +20 -4
  68. data/lib/rabbit/logger/stderr.rb +16 -2
  69. data/lib/rabbit/logger.rb +4 -4
  70. data/lib/rabbit/menu.rb +200 -220
  71. data/lib/rabbit/parser/base.rb +17 -1
  72. data/lib/rabbit/parser/ext/aafigure.rb +17 -1
  73. data/lib/rabbit/parser/ext/blockdiag.rb +17 -1
  74. data/lib/rabbit/parser/ext/charty.rb +2 -2
  75. data/lib/rabbit/parser/ext/coderay.rb +20 -4
  76. data/lib/rabbit/parser/ext/enscript.rb +31 -15
  77. data/lib/rabbit/parser/ext/entity.rb +17 -1
  78. data/lib/rabbit/parser/ext/image.rb +6 -6
  79. data/lib/rabbit/parser/ext/inline.rb +17 -1
  80. data/lib/rabbit/parser/ext/rouge.rb +7 -4
  81. data/lib/rabbit/parser/ext/tex.rb +18 -2
  82. data/lib/rabbit/parser/ext/video.rb +4 -4
  83. data/lib/rabbit/parser/image.rb +20 -4
  84. data/lib/rabbit/parser/markdown/converter.rb +12 -13
  85. data/lib/rabbit/parser/markdown.rb +18 -2
  86. data/lib/rabbit/parser/pause-support.rb +1 -0
  87. data/lib/rabbit/parser/pdf.rb +3 -3
  88. data/lib/rabbit/parser/rd/ext/base.rb +20 -4
  89. data/lib/rabbit/parser/rd/ext/block-verbatim.rb +24 -28
  90. data/lib/rabbit/parser/rd/ext/character-reference.rb +18 -2
  91. data/lib/rabbit/parser/rd/ext/image.rb +3 -3
  92. data/lib/rabbit/parser/rd/ext/inline-verbatim.rb +6 -6
  93. data/lib/rabbit/parser/rd/ext/refer.rb +18 -2
  94. data/lib/rabbit/parser/rd/ext/video.rb +19 -2
  95. data/lib/rabbit/parser/rd/rd2rabbit-lib.rb +24 -8
  96. data/lib/rabbit/parser/rd/rt/rt2rabbit-lib.rb +18 -2
  97. data/lib/rabbit/parser/rd/visitor.rb +18 -2
  98. data/lib/rabbit/parser/rd.rb +18 -2
  99. data/lib/rabbit/parser/wiki/output.rb +25 -28
  100. data/lib/rabbit/parser/wiki.rb +18 -2
  101. data/lib/rabbit/parser.rb +6 -6
  102. data/lib/rabbit/path-manipulatable.rb +4 -4
  103. data/lib/rabbit/progress.rb +17 -1
  104. data/lib/rabbit/properties.rb +3 -3
  105. data/lib/rabbit/rabbit.rb +15 -7
  106. data/lib/rabbit/readme-parser.rb +4 -6
  107. data/lib/rabbit/renderer/base.rb +44 -36
  108. data/lib/rabbit/renderer/color.rb +18 -2
  109. data/lib/rabbit/renderer/display/base.rb +10 -12
  110. data/lib/rabbit/renderer/display/button-handler.rb +141 -60
  111. data/lib/rabbit/renderer/display/cursor.rb +4 -5
  112. data/lib/rabbit/renderer/display/drawing-area-base.rb +32 -48
  113. data/lib/rabbit/renderer/display/drawing-area-primitive.rb +10 -61
  114. data/lib/rabbit/renderer/display/drawing-area-view-only.rb +19 -8
  115. data/lib/rabbit/renderer/display/drawing-area.rb +19 -15
  116. data/lib/rabbit/renderer/display/gesture.rb +9 -9
  117. data/lib/rabbit/renderer/display/graffiti.rb +22 -13
  118. data/lib/rabbit/renderer/display/info.rb +22 -2
  119. data/lib/rabbit/renderer/display/magnifier.rb +30 -17
  120. data/lib/rabbit/renderer/display/mask.rb +17 -1
  121. data/lib/rabbit/renderer/display/menu.rb +27 -3
  122. data/lib/rabbit/renderer/display/motion-handler.rb +45 -0
  123. data/lib/rabbit/renderer/display/progress.rb +17 -2
  124. data/lib/rabbit/renderer/display/scroll-handler.rb +60 -13
  125. data/lib/rabbit/renderer/display/search.rb +19 -2
  126. data/lib/rabbit/renderer/display/spotlight.rb +39 -25
  127. data/lib/rabbit/renderer/display.rb +16 -36
  128. data/lib/rabbit/renderer/engine/cairo.rb +4 -11
  129. data/lib/rabbit/renderer/engine.rb +17 -1
  130. data/lib/rabbit/renderer/kernel.rb +2 -20
  131. data/lib/rabbit/renderer/offscreen.rb +8 -14
  132. data/lib/rabbit/renderer/print-layout.rb +2 -2
  133. data/lib/rabbit/renderer/printer.rb +9 -16
  134. data/lib/rabbit/renderer/scene-background-widget.rb +95 -0
  135. data/lib/rabbit/renderer/scene-node-widget.rb +63 -0
  136. data/lib/rabbit/renderer/scene.rb +508 -0
  137. data/lib/rabbit/renderer.rb +6 -6
  138. data/lib/rabbit/search-window.rb +18 -2
  139. data/lib/rabbit/searcher.rb +15 -1
  140. data/lib/rabbit/size.rb +9 -1
  141. data/lib/rabbit/slide-configuration.rb +11 -14
  142. data/lib/rabbit/soap/driver.rb +20 -4
  143. data/lib/rabbit/soap/server.rb +17 -1
  144. data/lib/rabbit/source/argf.rb +5 -5
  145. data/lib/rabbit/source/base.rb +5 -6
  146. data/lib/rabbit/source/file.rb +5 -5
  147. data/lib/rabbit/source/memory.rb +20 -4
  148. data/lib/rabbit/source/uri.rb +9 -11
  149. data/lib/rabbit/source-generator/hiki.rb +2 -7
  150. data/lib/rabbit/source-generator/markdown.rb +2 -7
  151. data/lib/rabbit/source-generator/rd.rb +2 -7
  152. data/lib/rabbit/source-generator.rb +4 -4
  153. data/lib/rabbit/source.rb +5 -5
  154. data/lib/rabbit/task/slide.rb +13 -11
  155. data/lib/rabbit/task/theme.rb +8 -11
  156. data/lib/rabbit/task.rb +3 -3
  157. data/lib/rabbit/theme/applier.rb +27 -11
  158. data/lib/rabbit/theme/clear-blue/clear-blue.rb +1 -1
  159. data/lib/rabbit/theme/color-circle/color-circle.rb +18 -1
  160. data/lib/rabbit/theme/cozmixng/cozmixng.rb +1 -1
  161. data/lib/rabbit/theme/default/default.rb +1 -0
  162. data/lib/rabbit/theme/default-icon/default-icon.rb +1 -1
  163. data/lib/rabbit/theme/default-item-mark-setup/default-item-mark-setup.rb +17 -1
  164. data/lib/rabbit/theme/default-preformatted/default-preformatted.rb +9 -1
  165. data/lib/rabbit/theme/enishi-green/enishi-green.rb +1 -1
  166. data/lib/rabbit/theme/entry.rb +10 -12
  167. data/lib/rabbit/theme/icon/icon.rb +3 -8
  168. data/lib/rabbit/theme/image-slide-number/image-slide-number.rb +5 -5
  169. data/lib/rabbit/theme/image-timer/image-timer.rb +3 -3
  170. data/lib/rabbit/theme/lightning-simple/lightning-simple.rb +1 -0
  171. data/lib/rabbit/theme/lightning-talk/lightning-talk.rb +1 -0
  172. data/lib/rabbit/theme/manager.rb +19 -9
  173. data/lib/rabbit/theme/rabbit-icon/rabbit-icon.rb +1 -1
  174. data/lib/rabbit/theme/ranguba/ranguba.rb +1 -1
  175. data/lib/rabbit/theme/red-frame/red-frame.rb +6 -2
  176. data/lib/rabbit/theme/ruby-gnome2/ruby-gnome2.rb +1 -0
  177. data/lib/rabbit/theme/ruby-gnome2-icon/ruby-gnome2-icon.rb +1 -1
  178. data/lib/rabbit/theme/searcher.rb +23 -7
  179. data/lib/rabbit/theme/slide-number/slide-number.rb +1 -1
  180. data/lib/rabbit/theme/slide-show/slide-show.rb +1 -1
  181. data/lib/rabbit/theme/table/table.rb +2 -2
  182. data/lib/rabbit/theme/video/property.rb +3 -0
  183. data/lib/rabbit/theme/video/video.rb +5 -0
  184. data/lib/rabbit/theme-configuration.rb +9 -11
  185. data/lib/rabbit/utils.rb +12 -94
  186. data/lib/rabbit/version.rb +1 -1
  187. data/lib/rabbit/xmlrpc/client.rb +17 -1
  188. data/lib/rabbit/xmlrpc/server.rb +17 -1
  189. data/po/en/rabbit.edit.po +324 -316
  190. data/po/en/rabbit.po +61 -55
  191. data/po/fr/rabbit.edit.po +324 -316
  192. data/po/fr/rabbit.po +61 -55
  193. data/po/ja/rabbit.edit.po +345 -370
  194. data/po/ja/rabbit.po +83 -80
  195. data/rabbit.gemspec +4 -2
  196. data/sample/block-quote.rab +13 -0
  197. data/sample/description-list.rab +17 -0
  198. data/sample/mermaid.rab +16 -0
  199. data/sample/rabbit-en.hiki +0 -1
  200. data/sample/rabbit-en.md +0 -1
  201. data/sample/rabbit-en.rd +0 -1
  202. data/sample/rabbit.hiki +0 -1
  203. data/sample/rabbit.md +0 -1
  204. data/sample/rabbit.rd +0 -1
  205. data/sample/video.rab +17 -0
  206. metadata +33 -65
  207. data/lib/rabbit/action/basic.rb +0 -304
  208. data/lib/rabbit/action/radio.rb +0 -78
  209. data/lib/rabbit/action/toggle.rb +0 -82
  210. data/lib/rabbit/action.rb +0 -140
  211. data/lib/rabbit/renderer/display/gl.rb +0 -98
  212. data/lib/rabbit/renderer/display/key-handler.rb +0 -321
  213. data/lib/rabbit/renderer/gl.rb +0 -95
  214. data/lib/rabbit/renderer/screen.rb +0 -286
  215. data/lib/rabbit/renderer/widget/drawing-area.rb +0 -93
  216. data/lib/rabbit/stock.rb +0 -31
  217. data/lib/rabbit/trackball.rb +0 -228
  218. data/lib/rabbit/video-window.rb +0 -123
  219. data/test/command/test-rabbit.rb +0 -101
  220. data/test/helper/parser.rb +0 -48
  221. data/test/helper.rb +0 -24
  222. data/test/image/test-dia.rb +0 -54
  223. data/test/image/test-eps.rb +0 -41
  224. data/test/parser/test-markdown.rb +0 -360
  225. data/test/parser/test-rd.rb +0 -43
  226. data/test/parser/test-wiki.rb +0 -71
  227. data/test/run-test.rb +0 -27
  228. data/test/source-generator/test-hiki.rb +0 -68
  229. data/test/source-generator/test-markdown.rb +0 -67
  230. data/test/source-generator/test-rd.rb +0 -69
  231. data/test/test-applier.rb +0 -73
  232. data/test/test-author-configuration.rb +0 -37
  233. data/test/test-canvas.rb +0 -70
  234. data/test/test-color.rb +0 -51
  235. data/test/test-element.rb +0 -103
  236. data/test/test-readme-parser.rb +0 -160
  237. data/test/test-size.rb +0 -155
  238. data/test/test-slide-configuration.rb +0 -74
  239. data/test/test-source.rb +0 -122
  240. data/test/test-theme-configuration.rb +0 -47
  241. data/test/test-utils.rb +0 -64
@@ -1,9 +1,25 @@
1
- require "rabbit/utils"
1
+ # Copyright (C) 2012 Narihiro Nakamura <authornari@gmail.com>
2
+ # Copyright (C) 2013-2025 Sutou Kouhei <kou@cozmixng.org>
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 2 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 along
15
+ # with this program; if not, write to the Free Software Foundation, Inc.,
16
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2
17
 
3
- require "rabbit/image"
4
- require "rabbit/element/block-element"
5
- require "rabbit/element/text-renderer"
6
- require "rabbit/parser/base"
18
+ require_relative "../image"
19
+ require_relative "../parser/base"
20
+ require_relative "../properties"
21
+ require_relative "block-element"
22
+ require_relative "text-renderer"
7
23
 
8
24
  module Rabbit
9
25
  module Element
@@ -11,7 +27,6 @@ module Rabbit
11
27
  include Base
12
28
  include BlockElement
13
29
  include BlockHorizontalCentering
14
- include TextRenderer
15
30
 
16
31
  attr_reader :filename
17
32
  attr_reader :relative_width, :relative_height
@@ -20,33 +35,24 @@ module Rabbit
20
35
  attr_reader :relative_padding_top, :relative_padding_bottom
21
36
  attr_reader :relative_padding_left, :relative_padding_right
22
37
 
23
- def initialize(filename, prop)
38
+ def initialize(filename, props)
24
39
  @filename = filename
25
- prop = Utils.stringify_hash_key(prop)
40
+ @thumbnail = nil
26
41
  super()
27
- normalized_prop = {}
28
- prop.each do |name, value|
29
- normalized_prop[name.gsub(/-/, '_')] = value
30
- end
31
- prop = normalized_prop
32
- %w(as_large_as_possible).each do |name|
33
- instance_variable_set("@#{name}", true_value?(prop[name]))
34
- end
35
- %w(width height
36
- relative_width relative_height
42
+ @properties = Properties.new(props)
43
+ width, height = detect_size
44
+ @original_width = width
45
+ @original_height = height
46
+ %w(relative_width relative_height
37
47
  relative_margin_top relative_margin_bottom
38
48
  relative_margin_left relative_margin_right
39
49
  relative_padding_top relative_padding_bottom
40
50
  relative_padding_left relative_padding_right
41
51
  ).each do |name|
42
- begin
43
- instance_variable_set("@#{name}", prop[name] && Integer(prop[name]))
44
- rescue ArgumentError
45
- raise InvalidSizeError.new(filename, name, prop[name])
46
- end
52
+ instance_variable_set("@#{name}",
53
+ @properties.get_relative_size(name, @filename))
47
54
  end
48
-
49
- resize(@width, @height)
55
+ resize(width, height)
50
56
  end
51
57
 
52
58
  alias _compile compile
@@ -59,6 +65,23 @@ module Rabbit
59
65
  adjust_size(canvas, @x, @y, @w, @h)
60
66
  end
61
67
 
68
+ def setup_scene_element(canvas, scene_widget, x, y, w, h)
69
+ x, y, w, h = super
70
+
71
+ video = Gtk::Video.new(@filename)
72
+ scene_widget.put(video, x, y, @width || w, @height || h)
73
+ y += @height
74
+ h -= @height
75
+
76
+ [x, y, w, h]
77
+ end
78
+
79
+ def scene_snapshot_element(widget, snapshot, canvas, x, y, w, h)
80
+ y += @height
81
+ h -= @height
82
+ [x, y, w, h]
83
+ end
84
+
62
85
  def width
63
86
  @width.to_i + @padding_left + @padding_right
64
87
  end
@@ -68,23 +91,24 @@ module Rabbit
68
91
  end
69
92
 
70
93
  def as_large_as_possible?
71
- @as_large_as_possible
94
+ @properties.get_boolean("as_large_as_possible", false)
95
+ end
96
+
97
+ def keep_ratio?
98
+ @properties.get_boolean("keep_ratio", true) and
99
+ @original_width and
100
+ @original_height
72
101
  end
73
102
 
74
103
  def draw_element(canvas, x, y, w, h, simulation)
75
104
  unless simulation
76
- if canvas.display?
77
- require "rabbit/video-window"
78
- VideoWindow.show(canvas.window, self)
79
- else
80
- draw_layout(canvas, x, y)
81
- end
105
+ @thumbnail.draw(canvas, x, y) if @thumbnail
82
106
  end
83
107
  [x, y + height, w, h - height]
84
108
  end
85
109
 
86
110
  def text
87
- "video : #{File.basename(@filename)}"
111
+ "video: #{File.basename(@filename)}"
88
112
  end
89
113
 
90
114
  def to_rd
@@ -92,26 +116,106 @@ module Rabbit
92
116
  end
93
117
 
94
118
  private
119
+ def detect_size
120
+ width = @properties.get_size("width", @filename)
121
+ height = @properties.get_size("height", @filename)
122
+ if (width.nil? or height.nil?) and Gtk.const_defined?(:MediaFile)
123
+ w, h = detect_size_media_file
124
+ width ||= w
125
+ height ||= h
126
+ end
127
+ if (width.nil? or height.nil?) and defined?(::Gst)
128
+ w, h = detect_size_gstreamer
129
+ width ||= w
130
+ height ||= h
131
+ end
132
+ [width, height]
133
+ end
134
+
135
+ def detect_size_media_file
136
+ gio_file = Gio::File.open(path: @filename)
137
+ media_file = Gtk::MediaFile.new(gio_file)
138
+ # We want to mute here to avoid playing audio but if we
139
+ # mute, media_file isn't prepared...
140
+ # media_file.muted = true
141
+ media_file.play
142
+ while GLib::MainContext.default.iteration(true) do
143
+ end
144
+ width = media_file.intrinsic_width
145
+ width = nil if width.zero?
146
+ height = media_file.intrinsic_height
147
+ height = nil if height.zero?
148
+ media_file.pause
149
+ media_file.unref
150
+ [width, height]
151
+ end
152
+
153
+ def detect_size_gstreamer
154
+ pipeline = Gst::Pipeline.new
155
+ filesrc = Gst::ElementFactory.make("filesrc")
156
+ filesrc.location = @filename
157
+ decodebin = Gst::ElementFactory.make("decodebin")
158
+ return [nil, nil] if decodebin.nil?
159
+ videoconvert = Gst::ElementFactory.make("videoconvert")
160
+ return [nil, nil] if videoconvert.nil?
161
+ jpegenc = Gst::ElementFactory.make("jpegenc")
162
+ return [nil, nil] if jpegenc.nil?
163
+ filesink = Gst::ElementFactory.make("filesink")
164
+ @thumbnail_file = Tempfile.new(["rabbit-video", ".jpeg"])
165
+ filesink.location = @thumbnail_file.path
166
+
167
+ pipeline << filesrc << decodebin << videoconvert << jpegenc << filesink
168
+ filesrc >> decodebin
169
+ decodebin.signal_connect(:pad_added) do |_, pad|
170
+ sink_pad = videoconvert.get_static_pad("sink")
171
+ pad.link(sink_pad)
172
+ end
173
+ videoconvert >> jpegenc >> filesink
174
+
175
+ loop = GLib::MainLoop.new
176
+
177
+ bus = pipeline.bus
178
+ bus.add_watch do |bus, message|
179
+ case message.type
180
+ when Gst::MessageType::EOS
181
+ loop.quit
182
+ when Gst::MessageType::ERROR
183
+ loop.quit
184
+ end
185
+ true
186
+ end
187
+
188
+ pipeline.play
189
+ begin
190
+ loop.run
191
+ ensure
192
+ pipeline.stop
193
+ end
194
+
195
+ @thumbnail = ImageLoader.new(@thumbnail_file.path)
196
+ [@thumbnail.width, @thumbnail.height]
197
+ end
198
+
95
199
  def adjust_margin(w, h)
96
200
  @margin_top =
97
- make_relative_size(@relative_margin_top, h) || @margin_top
201
+ @relative_margin_top&.resolve(h) || @margin_top
98
202
  @margin_bottom =
99
- make_relative_size(@relative_margin_bottom, h) || @margin_bottom
203
+ @relative_margin_bottom&.resolve(h) || @margin_bottom
100
204
  @margin_left =
101
- make_relative_size(@relative_margin_left, w) || @margin_left
205
+ @relative_margin_left&.resolve(w) || @margin_left
102
206
  @margin_right =
103
- make_relative_size(@relative_margin_right, w) || @margin_right
207
+ @relative_margin_right&.resolve(w) || @margin_right
104
208
  end
105
209
 
106
210
  def adjust_padding(w, h)
107
211
  @padding_top =
108
- make_relative_size(@relative_padding_top, h) || @padding_top
212
+ @relative_padding_top&.resolve(h) || @padding_top
109
213
  @padding_bottom =
110
- make_relative_size(@relative_padding_bottom, h) || @padding_bottom
214
+ @relative_padding_bottom&.resolve(h) || @padding_bottom
111
215
  @padding_left =
112
- make_relative_size(@relative_padding_left, w) || @padding_left
216
+ @relative_padding_left&.resolve(w) || @padding_left
113
217
  @padding_right =
114
- make_relative_size(@relative_padding_right, w) || @padding_right
218
+ @relative_padding_right&.resolve(w) || @padding_right
115
219
  end
116
220
 
117
221
  def adjust_size(canvas, x, y, w, h)
@@ -120,21 +224,25 @@ module Rabbit
120
224
  adjust_margin(base_w, base_h)
121
225
  adjust_padding(base_w, base_h)
122
226
  base_h = base_h - @padding_top - @padding_bottom
123
- if @as_large_as_possible
227
+ if as_large_as_possible?
124
228
  iw = base_w
125
229
  ih = base_h
126
230
  else
127
- rw = make_relative_size(@relative_width, base_w)
128
- rh = make_relative_size(@relative_height, base_h)
129
- iw = rw || base_w
130
- ih = rh || base_h
231
+ iw = @relative_width&.resolve(base_w)
232
+ ih = @relative_height&.resolve(base_h)
131
233
  end
132
234
  resize(iw, ih)
133
235
  end
134
236
 
135
237
  def resize(w, h)
136
- if w.nil? and h.nil?
137
- return
238
+ return if w.nil? and h.nil?
239
+
240
+ if keep_ratio?
241
+ if w and h.nil?
242
+ h = (@original_height * w.to_f / @original_width).ceil
243
+ elsif w.nil? and h
244
+ w = (@original_width * h.to_f / @original_height).ceil
245
+ end
138
246
  else
139
247
  w ||= width
140
248
  h ||= height
@@ -144,16 +252,9 @@ module Rabbit
144
252
  if w and w > 0 and h and h > 0 and [w, h] != [width, height]
145
253
  @width = w
146
254
  @height = h
255
+ @thumbnail&.resize(@width, @height)
147
256
  end
148
257
  end
149
-
150
- def make_relative_size(size, parent_size)
151
- size && parent_size && ((size / 100.0) * parent_size).ceil
152
- end
153
-
154
- def true_value?(value)
155
- value == true or value == "true"
156
- end
157
258
  end
158
259
  end
159
260
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2017 Kouhei Sutou <kou@cozmixng.org>
1
+ # Copyright (C) 2017-2025 Sutou Kouhei <kou@cozmixng.org>
2
2
  #
3
3
  # This program is free software; you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
@@ -14,22 +14,22 @@
14
14
  # with this program; if not, write to the Free Software Foundation, Inc.,
15
15
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
16
 
17
- require "rabbit/element/block"
18
- require "rabbit/element/description-list"
19
- require "rabbit/element/enum-list"
20
- require "rabbit/element/footnote"
21
- require "rabbit/element/image-title-slide"
22
- require "rabbit/element/image"
23
- require "rabbit/element/index-slide"
24
- require "rabbit/element/item-list"
25
- require "rabbit/element/method-list"
26
- require "rabbit/element/poppler-slide"
27
- require "rabbit/element/poppler-title-slide"
28
- require "rabbit/element/preformatted"
29
- require "rabbit/element/slide"
30
- require "rabbit/element/syntax-highlighting"
31
- require "rabbit/element/table"
32
- require "rabbit/element/tag"
33
- require "rabbit/element/text"
34
- require "rabbit/element/title-slide"
35
- require "rabbit/element/video"
17
+ require_relative "element/block"
18
+ require_relative "element/description-list"
19
+ require_relative "element/enum-list"
20
+ require_relative "element/footnote"
21
+ require_relative "element/image-title-slide"
22
+ require_relative "element/image"
23
+ require_relative "element/index-slide"
24
+ require_relative "element/item-list"
25
+ require_relative "element/method-list"
26
+ require_relative "element/poppler-slide"
27
+ require_relative "element/poppler-title-slide"
28
+ require_relative "element/preformatted"
29
+ require_relative "element/slide"
30
+ require_relative "element/syntax-highlighting"
31
+ require_relative "element/table"
32
+ require_relative "element/tag"
33
+ require_relative "element/text"
34
+ require_relative "element/title-slide"
35
+ require_relative "element/video"
@@ -1,5 +1,22 @@
1
+ # Copyright (C) 2004-2025 Sutou Kouhei <kou@cozmixng.org>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program 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
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along
14
+ # with this program; if not, write to the Free Software Foundation, Inc.,
15
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+
1
17
  require "erb"
2
- require "rabbit/renderer/color"
18
+
19
+ require_relative "renderer/color"
3
20
 
4
21
  module Rabbit
5
22
  module Format
data/lib/rabbit/frame.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2004-2024 Sutou Kouhei <kou@cozmixng.org>
1
+ # Copyright (C) 2004-2025 Sutou Kouhei <kou@cozmixng.org>
2
2
  #
3
3
  # This program is free software; you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
@@ -15,9 +15,10 @@
15
15
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
16
 
17
17
  require "forwardable"
18
- require "rabbit/gtk"
19
18
  require "rexml/text"
20
19
 
20
+ require_relative "gtk"
21
+
21
22
  begin
22
23
  case ENV["RABBIT_GTK"]
23
24
  when "4"
@@ -28,15 +29,14 @@ begin
28
29
  rescue LoadError
29
30
  end
30
31
 
31
- require "rabbit/rabbit"
32
- require "rabbit/utils"
32
+ require_relative "rabbit"
33
+ require_relative "utils"
33
34
 
34
35
  module Rabbit
35
36
  class Frame
36
37
  extend Forwardable
37
38
 
38
39
  def_delegators(:@window, :icon, :icon=, :set_icon)
39
- def_delegators(:@window, :icon_list, :icon_list=, :set_icon_list)
40
40
  def_delegators(:@window, :iconify, :show, :hide, :visible?)
41
41
  def_delegators(:@window, :set_size_request, :resize)
42
42
 
@@ -47,14 +47,13 @@ module Rabbit
47
47
  def_delegators(:@canvas, :output_html=, :output_index_html=)
48
48
  def_delegators(:@canvas, :rss_base_uri=, :use_gl?, :use_gl=)
49
49
 
50
- attr_reader :window, :logger
50
+ attr_reader :window
51
51
  attr_accessor :geometry
52
52
 
53
- def initialize(logger, canvas)
54
- @logger = logger
53
+ def initialize(canvas)
55
54
  @canvas = canvas
56
55
  @geometry = nil
57
- @notebook = nil
56
+ @stack = nil
58
57
  @terminal = nil
59
58
  @running = true
60
59
  end
@@ -115,8 +114,7 @@ module Rabbit
115
114
  @fullscreen = false
116
115
  @main_window = main_window
117
116
  @terminal.show if @terminal
118
- @notebook.show if @notebook
119
- @window.show
117
+ @stack.show if @stack
120
118
  @canvas.post_init_gui
121
119
  end
122
120
 
@@ -130,17 +128,20 @@ module Rabbit
130
128
 
131
129
  def toggle_terminal
132
130
  return if @terminal.nil?
133
- terminal_page = @notebook.page_num(@terminal)
134
- if @notebook.current_page == terminal_page
135
- @notebook.current_page = 0
131
+ if @stack.visible_child_name == "terminal"
132
+ if @stack.respond_to?(:pages)
133
+ @stack.visible_child = @stack.pages[0].child
134
+ else
135
+ @stack.visible_child = @stack.children[0]
136
+ end
136
137
  else
137
- @notebook.current_page = terminal_page
138
+ @stack.visible_child_name = "terminal"
138
139
  end
139
140
  end
140
141
 
141
142
  def in_terminal?
142
143
  return false if @terminal.nil?
143
- @notebook.current_page == @notebook.page_num(@terminal)
144
+ @stack.visible_child_name == "terminal"
144
145
  end
145
146
 
146
147
  private
@@ -149,54 +150,88 @@ module Rabbit
149
150
  @window = Gtk::ApplicationWindow.new(::Rabbit.application)
150
151
  @window.set_default_size(width, height)
151
152
  @window.parse_geometry(@geometry) if @geometry
152
- @window.set_app_paintable(true)
153
- if defined?(Vte::Terminal)
154
- init_notebook
155
- end
156
- set_window_signal
157
- setup_dnd
158
- @canvas.attach_to(self, @window, @notebook)
159
- if defined?(Vte::Terminal)
160
- init_terminal
161
- end
162
- end
163
-
164
- def init_notebook
165
- @notebook = Gtk::Notebook.new
166
- @notebook.show_tabs = false
167
- provider = Gtk::CssProvider.new
168
- provider.load(data: <<-CSS)
169
- notebook {
170
- border-width: 0px;
171
- }
172
- CSS
173
- @notebook.style_context.add_provider(provider,
174
- Gtk::StyleProvider::PRIORITY_USER)
175
- @window.add(@notebook)
176
- end
177
-
178
- def set_window_signal
179
- set_window_signal_window_state_event
153
+ init_stack
180
154
  set_window_signal_destroy
181
- end
182
-
183
- def set_window_signal_window_state_event
184
- @window.signal_connect("window_state_event") do |widget, event|
185
- if event.changed_mask.fullscreen?
186
- @fullscreen = event.new_window_state.fullscreen?
187
- if @fullscreen
188
- @canvas.fullscreened
189
- else
190
- @canvas.unfullscreened
155
+ setup_dnd
156
+ @window.show # @window.surface is only available after @window.show.
157
+ if Gtk::Version::MAJOR < 4
158
+ @window.signal_connect(:configure_event) do |_, event|
159
+ GLib::Idle.add do
160
+ width = @stack.allocated_width
161
+ height = @stack.allocated_height
162
+ @canvas.renderer.update_size(width, height)
163
+ GLib::Source::REMOVE
191
164
  end
192
- elsif event.changed_mask.iconified?
193
- if event.new_window_state.iconified?
194
- @canvas.iconified
165
+ false
166
+ end
167
+ @window.signal_connect(:window_state_event) do |widget, event|
168
+ if event.changed_mask.fullscreen?
169
+ @fullscreen = event.new_window_state.fullscreen?
170
+ if @fullscreen
171
+ @canvas.fullscreened
172
+ else
173
+ @canvas.unfullscreened
174
+ end
175
+ elsif event.changed_mask.iconified?
176
+ if event.new_window_state.iconified?
177
+ @canvas.iconified
178
+ end
195
179
  end
180
+
181
+ false
196
182
  end
183
+ else
184
+ previous_width = nil
185
+ previous_height = nil
186
+ previous_fullscreen = @fullscreen = @window.fullscreen?
187
+ previous_minimized = false
188
+ @surface = @window.surface # This is to guard from GC.
189
+ @surface.signal_connect(:notify) do |surface, param|
190
+ case param.name
191
+ when "width", "height"
192
+ GLib::Idle.add do
193
+ width = @stack.width
194
+ height = @stack.height
195
+ if previous_width != width or previous_height != height
196
+ @canvas.renderer.update_size(width, height)
197
+ previous_width = width
198
+ previous_height = height
199
+ end
200
+ GLib::Source::REMOVE
201
+ end
202
+ when "state"
203
+ state = surface.state
204
+ @canvas.reload_source if state.focused?
205
+ fullscreen = state.fullscreen?
206
+ if previous_fullscreen != fullscreen
207
+ @fullscreen = fullscreen
208
+ if @fullscreen
209
+ @canvas.fullscreened
210
+ else
211
+ @canvas.unfullscreened
212
+ end
213
+ previous_fullscreen = @fullscreen
214
+ end
215
+ minimized = state.minimized?
216
+ if previous_minimized != minimized
217
+ @canvas.iconified if minimized
218
+ previous_minimized = minimized
219
+ end
220
+ end
221
+ end
222
+ end
223
+ @canvas.attach_to(self, @window, @stack)
224
+ init_terminal if defined?(Vte::Terminal)
225
+ end
197
226
 
198
- false
227
+ def init_stack
228
+ @stack = Gtk::Stack.new
229
+ if Gtk::StackTransitionType.const_defined?(:ROTATE_LEFT_RIGHT)
230
+ @stack.transition_type = :rotate_left_right
231
+ else
232
+ @stack.transition_type = :slide_left_right
199
233
  end
234
+ @window.child = @stack
200
235
  end
201
236
 
202
237
  def set_window_signal_destroy
@@ -206,6 +241,7 @@ module Rabbit
206
241
  end
207
242
 
208
243
  def setup_dnd
244
+ return if Gtk::Version::MAJOR >= 4 # TODO
209
245
  @window.drag_dest_set(:all,
210
246
  [["text/uri-list", 0, 0],
211
247
  ["_NETSCAPE_URL", 0, 0]],
@@ -214,7 +250,7 @@ module Rabbit
214
250
  widget, context, x, y, selection_data, info, time = args
215
251
  uri = selection_data.data.chomp
216
252
  Gtk.idle_add do
217
- parse(Source::URI.new(nil, logger, uri))
253
+ parse(Source::URI.new(nil, uri))
218
254
  false
219
255
  end
220
256
  Gtk::Drag.finish(context, true, false, time)
@@ -242,11 +278,11 @@ module Rabbit
242
278
  @terminal.color_background = terminal_color_background
243
279
  end
244
280
  @terminal.enable_sixel = true if @terminal.respond_to?(:enable_sixel=)
245
- @notebook.add(@terminal)
281
+ @stack.add_named(@terminal, "terminal")
246
282
  pid = nil
247
283
  in_terminal = false
248
- @notebook.signal_connect(:switch_page) do |_, page,|
249
- if page == @terminal
284
+ @stack.signal_connect("notify::visible-child-name") do |_, param|
285
+ if @stack.visible_child_name == "terminal"
250
286
  if @running
251
287
  pid = @terminal.spawn if pid.nil?
252
288
  @canvas.pre_terminal unless in_terminal
@@ -259,8 +295,7 @@ module Rabbit
259
295
  end
260
296
  @terminal.signal_connect(:child_exited) do
261
297
  pid = nil
262
- terminal_page = @notebook.page_num(@terminal)
263
- if @notebook.current_page == terminal_page
298
+ if @stack.visible_child_name == "terminal"
264
299
  @canvas.activate("ToggleTerminal")
265
300
  end
266
301
  end
@@ -277,10 +312,9 @@ module Rabbit
277
312
  end
278
313
 
279
314
  def_null_methods(:icon, :icon=, :set_icon)
280
- def_null_methods(:icon_list, :icon_list=, :set_icon_list)
281
315
  def_null_methods(:update_title, :geometry, :geometry=)
282
316
 
283
- def_null_methods(:fullscreen?, :quit)
317
+ def_null_methods(:quit)
284
318
 
285
319
  def fullscreen_available?
286
320
  false
@@ -296,35 +330,9 @@ module Rabbit
296
330
  def in_terminal?
297
331
  false
298
332
  end
299
- end
300
-
301
- class EmbedFrame < Frame
302
- def update_title(new_title)
303
- end
304
-
305
- def fullscreen_available?
306
- false
307
- end
308
-
309
- def iconify_available?
310
- false
311
- end
312
333
 
313
- def toggle_terminal
314
- end
315
-
316
- def in_terminal?
334
+ def fullscreen?
317
335
  false
318
336
  end
319
-
320
- def init_gui(width, height, main_window, window_type=nil)
321
- @window = Gtk::EventBox.new
322
- @window.set_size_request(width, height)
323
- @canvas.attach_to(self, @window)
324
- @fullscreen = false
325
- @main_window = main_window
326
- @window.show
327
- @canvas.post_init_gui
328
- end
329
337
  end
330
338
  end