rabbit 3.0.5 → 4.0.0

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 +54 -0
  5. data/doc/ja/news.rd +54 -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 +102 -90
  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
@@ -0,0 +1,95 @@
1
+ # Copyright (C) 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
+
17
+ require_relative "../gtk"
18
+
19
+ module Rabbit
20
+ module Renderer
21
+ class SceneBackgroundWidget < Gtk::Widget
22
+ type_register
23
+
24
+ def initialize(canvas, renderer, size)
25
+ super()
26
+ @canvas = canvas
27
+ @renderer = renderer
28
+ @size = size
29
+ end
30
+
31
+ def virtual_do_measure(orientation, for_size)
32
+ if orientation == Gtk::Orientation::HORIZONTAL
33
+ width = @size.base_width
34
+ [width, width, -1, -1]
35
+ else
36
+ height = @size.base_height
37
+ [height, height, -1, -1]
38
+ end
39
+ end
40
+
41
+ def virtual_do_snapshot(snapshot)
42
+ snapshot.save do
43
+ snapshot.scale(*@size.logical_scale)
44
+
45
+ background = @renderer.background.to_gdk_rgba
46
+ snapshot.append_color(background,
47
+ [
48
+ @size.logical_margin_left,
49
+ @size.logical_margin_top,
50
+ @size.logical_width,
51
+ @size.logical_height,
52
+ ])
53
+
54
+ return unless @size.have_logical_margin?
55
+
56
+ margin_background = @renderer.make_color("black").to_gdk_rgba
57
+ if @size.have_logical_margin_x?
58
+ snapshot.append_color(margin_background,
59
+ [
60
+ 0,
61
+ 0,
62
+ @size.logical_margin_left,
63
+ @size.logical_height,
64
+ ])
65
+ snapshot.append_color(margin_background,
66
+ [
67
+ @size.logical_margin_right +
68
+ @size.logical_width,
69
+ 0,
70
+ @size.logical_margin_left,
71
+ @size.logical_height,
72
+ ])
73
+ end
74
+ if @size.have_logical_margin_y?
75
+ snapshot.append_color(margin_background,
76
+ [
77
+ 0,
78
+ 0,
79
+ @size.logical_width,
80
+ @size.logical_margin_top,
81
+ ])
82
+ snapshot.append_color(margin_background,
83
+ [
84
+ 0,
85
+ @size.logical_margin_top +
86
+ @size.logical_height,
87
+ @size.logical_width,
88
+ @size.logical_margin_bottom,
89
+ ])
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,63 @@
1
+ # Copyright (C) 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
+
17
+ require_relative "../gtk"
18
+
19
+ module Rabbit
20
+ module Renderer
21
+ class SceneNodeWidget < Gtk::Widget
22
+ type_register
23
+
24
+ attr_reader :x
25
+ attr_reader :y
26
+ def initialize(canvas, element, x, y, width, height)
27
+ super()
28
+ @canvas = canvas
29
+ @size = @canvas.renderer.size
30
+ @element = element
31
+ @x = x
32
+ @y = y
33
+ @width = width
34
+ @height = height
35
+ end
36
+
37
+ def virtual_do_measure(orientation, for_size)
38
+ if orientation == Gtk::Orientation::VERTICAL
39
+ [@height, @height, -1, -1]
40
+ else
41
+ [@width, @width, -1, -1]
42
+ end
43
+ end
44
+
45
+ def virtual_do_snapshot(snapshot)
46
+ # For backward compatibility. Legacy DrawingArea based
47
+ # renderer. Legacy DrawingAare based renderer uses uses {x: 0,
48
+ # y: 0, width: @canvas.width, height: @canvas.height} coordinate
49
+ # for all elements. Scene based renderer uses {x: element.x, y:
50
+ # element.y, width: element.width, height: element.height} for
51
+ # each element.
52
+ @canvas.renderer.push_snapshot(snapshot, @x, @y) do
53
+ snapshot.scale(*@size.logical_scale)
54
+ snapshot.translate([
55
+ @size.logical_margin_left,
56
+ @size.logical_margin_top,
57
+ ])
58
+ @element.scene_snapshot(self, snapshot, @canvas, @width, @height)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,508 @@
1
+ # Copyright (C) 2018-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
+
17
+ require "forwardable"
18
+
19
+ require_relative "base"
20
+
21
+ require_relative "display/base"
22
+ require_relative "display/progress"
23
+ require_relative "display/mask"
24
+ require_relative "display/menu"
25
+ require_relative "display/search"
26
+ require_relative "display/gesture"
27
+ require_relative "display/graffiti"
28
+ require_relative "display/button-handler"
29
+ require_relative "display/motion-handler"
30
+ require_relative "display/scroll-handler"
31
+ require_relative "display/info"
32
+ require_relative "display/spotlight"
33
+ require_relative "display/magnifier"
34
+
35
+ require_relative "scene-background-widget"
36
+
37
+ module Rabbit
38
+ module Renderer
39
+ # This is not a real widget. This is just a wrapper to enforce
40
+ # our conventions:
41
+ #
42
+ # * We need to use real x,y not logical x,y for widget location
43
+ # * We need to adjust margin of rendering area (not element's margin)
44
+ # for GTK widget
45
+ # * We need to use real w,h not logical w,h for GTK widget size
46
+ class SceneWidget
47
+ def initialize(fixed, size)
48
+ @fixed = fixed
49
+ @size = size
50
+ end
51
+
52
+ def put(widget, x, y, w, h)
53
+ case widget
54
+ when SceneNodeWidget, SceneBackgroundWidget
55
+ # Our widgets process size by themselves
56
+ else
57
+ x += @size.logical_margin_left
58
+ y += @size.logical_margin_top
59
+ widget.set_size_request(@size.resolve_logical_x(w),
60
+ @size.resolve_logical_y(h))
61
+ end
62
+ real_x = @size.resolve_logical_x(x)
63
+ real_y = @size.resolve_logical_y(y)
64
+ @fixed.put(widget, real_x, real_y)
65
+ end
66
+ end
67
+
68
+ class Scene < Base
69
+ include Kernel # TODO: Remove me
70
+
71
+ include Display::Base
72
+
73
+ include Display::Cursor
74
+ include Display::Menu
75
+ # include Display::Graffiti
76
+ # include Display::Mask
77
+ # include Display::Progress
78
+ # include Display::Search
79
+ # include Display::Gesture
80
+ include Display::ButtonHandler
81
+ include Display::MotionHandler
82
+ include Display::ScrollHandler
83
+ include Display::Info
84
+ include Display::Spotlight
85
+ # include Display::Magnifier
86
+
87
+ attr_accessor :filename
88
+ def initialize(canvas)
89
+ super
90
+ @filename = nil
91
+ @snapshots = []
92
+ @base_xys = []
93
+ init_ui
94
+ end
95
+
96
+ def update_size(width, height)
97
+ super
98
+ compile_slides
99
+ end
100
+
101
+ def attach_to(window, container=nil)
102
+ super
103
+ if container
104
+ container.add(@stack)
105
+ else
106
+ @window.child = @stack
107
+ end
108
+ @stack.show
109
+ set_default_size(window.default_width, window.default_height)
110
+ update_size(window.default_width, window.default_height)
111
+ init_menu
112
+ attach_menu(@window)
113
+ end
114
+
115
+ def detach
116
+ detach_menu(@window)
117
+ @stack.hide
118
+ super
119
+ end
120
+
121
+ def widget
122
+ @stack
123
+ end
124
+
125
+ def queue_draw
126
+ @stack.queue_draw
127
+ queue_draw_recursive = lambda do |widget|
128
+ widget.queue_draw
129
+ if widget.respond_to?(:children)
130
+ widget.children.each do |child|
131
+ queue_draw_recursive.call(child)
132
+ end
133
+ end
134
+ end
135
+ queue_draw_recursive.call(@stack.visible_child)
136
+ end
137
+
138
+ def clear_slide
139
+ super
140
+ compile_slides
141
+ end
142
+
143
+ def post_fullscreen
144
+ update_cursor(:blank, true)
145
+ update_menu
146
+ end
147
+
148
+ def post_unfullscreen
149
+ update_cursor(nil, true)
150
+ update_menu
151
+ end
152
+
153
+ def post_iconify
154
+ update_menu
155
+ end
156
+
157
+ def post_apply_theme
158
+ clear_slide
159
+ queue_draw
160
+ update_menu
161
+ end
162
+
163
+ def post_move(old_index, index)
164
+ @stack.visible_child_name = index.to_s
165
+ update_title
166
+ update_menu
167
+ end
168
+
169
+ def post_move_in_slide(old_index, index)
170
+ queue_draw
171
+ update_menu
172
+ end
173
+
174
+ def pre_parse
175
+ end
176
+
177
+ def post_parse
178
+ update_title
179
+ end
180
+
181
+ def pre_toggle_index_mode
182
+ end
183
+
184
+ def post_toggle_index_mode
185
+ queue_draw
186
+ end
187
+
188
+ def pre_to_pixbuf(n_slides)
189
+ end
190
+
191
+ def to_pixbufing(i)
192
+ true
193
+ end
194
+
195
+ def post_to_pixbuf(canceled)
196
+ end
197
+
198
+ def index_mode_on
199
+ keep_cursor(:index)
200
+ update_cursor(nil, true)
201
+ end
202
+
203
+ def index_mode_off
204
+ restore_cursor(:index)
205
+ end
206
+
207
+ def display?
208
+ true
209
+ end
210
+
211
+ def push_snapshot(snapshot, base_x, base_y)
212
+ @snapshots << snapshot
213
+ @base_xys << [base_x, base_y]
214
+ begin
215
+ snapshot.save do
216
+ yield
217
+ end
218
+ ensure
219
+ @base_xys.pop
220
+ @snapshots.pop
221
+ end
222
+ end
223
+
224
+ def current_snapshot
225
+ @snapshots.last
226
+ end
227
+
228
+ def current_base_xy
229
+ @base_xys.last
230
+ end
231
+
232
+ def draw_pixbuf(pixbuf, x, y, params={})
233
+ x, y = adjust_xy(x, y)
234
+ width = (params[:width] || pixbuf.width).to_f
235
+ height = (params[:height] || pixbuf.height).to_f
236
+ draw_scaled_pixbuf = params[:draw_scaled_pixbuf]
237
+ draw_scaled_pixbuf = @draw_scaled_image if draw_scaled_pixbuf.nil?
238
+
239
+ snapshot = current_snapshot
240
+ snapshot.save do
241
+ # TODO: clip
242
+ snapshot.translate([x, y])
243
+
244
+ if width == pixbuf.width and height == pixbuf.height
245
+ need_scale = false
246
+ elsif draw_scaled_pixbuf
247
+ need_scale = true
248
+ else
249
+ need_scale = false
250
+ end
251
+ if need_scale
252
+ snapshot.append_scale_texture(Gdk::Texture.new(pixbuf),
253
+ :linear,
254
+ [0, 0, width, height])
255
+ else
256
+ snapshot.append_texture(Gdk::Texture.new(pixbuf),
257
+ [0, 0, width, height])
258
+ end
259
+ end
260
+ end
261
+
262
+ def draw_layout(layout, x, y, color=nil, params={})
263
+ return if params[:stroke] # TODO
264
+
265
+ x, y = adjust_xy(x, y)
266
+ snapshot = current_snapshot
267
+ snapshot.save do
268
+ snapshot.translate([x, y])
269
+ rgba = make_color(color).to_gdk_rgba
270
+ snapshot.append_layout(layout, rgba)
271
+ end
272
+ end
273
+
274
+ def create_stroke(params)
275
+ stroke = Gsk::Stroke.new(params[:line_width] || 1)
276
+ [:line_cap, :line_join].each do |name|
277
+ value = params[name]
278
+ stroke.__send__("#{name}=", value) if value
279
+ end
280
+ # TODO: dash
281
+ stroke
282
+ end
283
+
284
+ def draw_line(x1, y1, x2, y2, color=nil, params={})
285
+ return if params[:line_width] == 0
286
+
287
+ x1, y1 = adjust_xy(x1, y1)
288
+ x2, y2 = adjust_xy(x2, y2)
289
+ snapshot = current_snapshot
290
+ snapshot.save do
291
+ rgba = make_color(color).to_gdk_rgba
292
+ builder = Gsk::PathBuilder.new
293
+ builder.move_to(x1, y1)
294
+ builder.line_to(x2, y2)
295
+ stroke = create_stroke(params)
296
+ snapshot.append_stroke(builder.to_path, stroke, rgba)
297
+ end
298
+ end
299
+
300
+ def draw_rectangle(filled, x, y, w, h, color=nil, params={})
301
+ x, y = adjust_xy(x, y)
302
+ snapshot = current_snapshot
303
+ snapshot.save do
304
+ rgba = make_color(color).to_gdk_rgba
305
+ if filled
306
+ snapshot.append_color(rgba, [x, y, w, h])
307
+ else
308
+ builder = Gsk::PathBuilder.new
309
+ builder.add_rect([x, y, w, h])
310
+ stroke = create_stroke(params)
311
+ snapshot.append_stroke(builder.to_path, stroke, rgba)
312
+ end
313
+ end
314
+ end
315
+
316
+ def draw_rounded_rectangle(filled, x, y, w, h, radius, color=nil, params={})
317
+ x, y = adjust_xy(x, y)
318
+ snapshot = current_snapshot
319
+ snapshot.save do
320
+ rgba = make_color(color).to_gdk_rgba
321
+ builder = Gsk::PathBuilder.new
322
+ builder.add_rounded_rect([[x, y, w, h], radius])
323
+ path = builder.to_path
324
+ if filled
325
+ snapshot.append_fill(path, :winding, rgba)
326
+ else
327
+ stroke = create_stroke(params)
328
+ snapshot.append_stroke(path, stroke, rgba)
329
+ end
330
+ end
331
+ end
332
+
333
+ # <--w-->
334
+ # 90 degree
335
+ # +-+ -
336
+ # / \ |
337
+ # 180 degree | | 0 degree h
338
+ # \ / |
339
+ # p +-+ -
340
+ # p: (x,y)
341
+ def draw_arc(filled,
342
+ x,
343
+ y,
344
+ w,
345
+ h,
346
+ start_degree,
347
+ length_degree,
348
+ color=nil,
349
+ params={})
350
+ radius = w * 0.5
351
+ draw_arc_by_radius(filled,
352
+ x + w * 0.5,
353
+ y + h * 0.5,
354
+ radius,
355
+ start_degree,
356
+ length_degree,
357
+ color,
358
+ params)
359
+ end
360
+
361
+ # 90 degree
362
+ # +-+
363
+ # / \
364
+ # 180 degree | c | 0 degree
365
+ # \ /
366
+ # +-+
367
+ #
368
+ # c: center (center_x, center_y)
369
+ def draw_arc_by_radius(filled,
370
+ center_x,
371
+ center_y,
372
+ radius,
373
+ start_degree,
374
+ length_degree,
375
+ color=nil,
376
+ params={})
377
+ center_x, center_y = adjust_xy(center_x, center_y)
378
+ snapshot = current_snapshot
379
+ snapshot.save do
380
+ builder = Gsk::PathBuilder.new
381
+ if length_degree == 360
382
+ builder.add_circle([center_x, center_y], radius)
383
+ else
384
+ end_degree = start_degree + length_degree
385
+ # Convert to the HTML arcTo command:
386
+ # https://www.w3.org/TR/SVG11/paths.html#PathDataEllipticalArcCommands
387
+ #
388
+ # 90 degree
389
+ # +-+
390
+ # / \
391
+ # 180 degree | c | 0 degree
392
+ # end degree \ / start degree
393
+ # +-+
394
+ # ->
395
+ # +-+
396
+ # end (x,y) / \
397
+ # 180 degree | c | 0 degree
398
+ # \ / start (x0,y0)
399
+ # +-+
400
+ # 90 degree
401
+ x_axis_rotation = 0
402
+ large_arc = length_degree >= 180
403
+ positive_sweep = false
404
+ start_radian = -start_degree * (Math::PI / 180.0)
405
+ end_radian = -end_degree * (Math::PI / 180.0)
406
+ start_x = center_x + (radius * Math.cos(start_radian))
407
+ start_y = center_y + (radius * Math.sin(start_radian))
408
+ end_x = center_x + (radius * Math.cos(end_radian))
409
+ end_y = center_y + (radius * Math.sin(end_radian))
410
+ if filled
411
+ builder.move_to(center_x, center_y)
412
+ builder.line_to(start_x, start_y)
413
+ else
414
+ builder.move_to(start_x, start_y)
415
+ end
416
+ builder.svg_arc_to(radius,
417
+ radius,
418
+ x_axis_rotation,
419
+ large_arc,
420
+ positive_sweep,
421
+ center_x + (radius * Math.cos(end_radian)),
422
+ center_y + (radius * Math.sin(end_radian)))
423
+ builder.close if filled
424
+ end
425
+ path = builder.to_path
426
+ rgba = make_color(color).to_gdk_rgba
427
+ if filled
428
+ snapshot.append_fill(path, :winding, rgba)
429
+ else
430
+ snapshot.append_stroke(path, create_stroke(params), rgba)
431
+ end
432
+ end
433
+ end
434
+
435
+ def draw_poppler_page(page, x, y, params={})
436
+ x, y = adjust_xy(x, y)
437
+ w, h = page.size
438
+ width = (params[:width] || w).to_f
439
+ height = (params[:height] || h).to_f
440
+
441
+ snapshot = current_snapshot
442
+ snapshot.save do
443
+ # TODO: clip
444
+ snapshot.scale(width / w, height / h)
445
+ context = snapshot.append_cairo([x, y, w, h])
446
+ context.render_poppler_page(page)
447
+ end
448
+ end
449
+
450
+ private
451
+ def init_ui
452
+ @stack = Gtk::Stack.new
453
+ if ENV["RABBIT_SLIDE_TRANSITION"] == "yes"
454
+ @stack.transition_type = :rotate_left_right
455
+ end
456
+ set_button_event(@stack)
457
+ set_motion_event(@stack)
458
+ set_scroll_event(@stack)
459
+ end
460
+
461
+ def compile_slides
462
+ visible_child_name = @stack.visible_child_name
463
+ @stack.pages.to_a.each do |page|
464
+ @stack.remove(page.child)
465
+ end
466
+ @canvas.slides.each_with_index do |slide, i|
467
+ set_size_ratio(slide.size_ratio || @default_size_ratio)
468
+ fixed = Gtk::Fixed.new
469
+ scene_widget = SceneWidget.new(fixed, size)
470
+ background = SceneBackgroundWidget.new(@canvas, self, size)
471
+ w = size.logical_width
472
+ h = size.logical_height
473
+ scene_widget.put(background, 0, 0, w, h)
474
+ slide.setup_scene(@canvas, scene_widget, 0, 0, w, h)
475
+ @stack.add_named(fixed, i.to_s)
476
+ end
477
+ @stack.visible_child_name = visible_child_name if visible_child_name
478
+ redraw
479
+ end
480
+
481
+ # For backward compatibility. Legacy DrawingArea based
482
+ # renderer. Legacy DrawingAare based renderer uses uses {x: 0,
483
+ # y: 0, width: @canvas.width, height: @canvas.height} coordinate
484
+ # for all elements. Scene based renderer uses {x: element.x, y:
485
+ # element.y, width: element.width, height: element.height} for
486
+ # each element.
487
+ def adjust_xy(x, y)
488
+ base_x, base_y = current_base_xy
489
+ [x - base_x, y - base_y]
490
+ end
491
+
492
+ def depth
493
+ @stack.window.depth
494
+ end
495
+
496
+ def reload_theme(&callback)
497
+ callback ||= Utils.process_pending_events_proc
498
+ @canvas.activate("ReloadTheme", &callback)
499
+ end
500
+
501
+ def grab
502
+ end
503
+
504
+ def ungrab
505
+ end
506
+ end
507
+ end
508
+ end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2004-2018 Kouhei Sutou <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
@@ -14,8 +14,8 @@
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/renderer/color"
18
- require "rabbit/renderer/display"
19
- require "rabbit/renderer/offscreen"
20
- require "rabbit/renderer/printer"
21
- require "rabbit/renderer/screen"
17
+ require_relative "renderer/color"
18
+ require_relative "renderer/display"
19
+ require_relative "renderer/offscreen"
20
+ require_relative "renderer/printer"
21
+ require_relative "renderer/scene"
@@ -1,6 +1,22 @@
1
- require 'rabbit/gtk'
1
+ # Copyright (C) 2006-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.
2
16
 
3
- require 'rabbit/searcher'
17
+ require_relative "gtk"
18
+
19
+ require_relative "searcher"
4
20
 
5
21
  module Rabbit
6
22
  class SearchWindow