rabbit 3.0.0 → 3.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/data/locale/en/LC_MESSAGES/rabbit.mo +0 -0
  3. data/data/locale/ja/LC_MESSAGES/rabbit.mo +0 -0
  4. data/doc/_config.yml +2 -2
  5. data/doc/en/faq.rd +4 -2
  6. data/doc/en/news.rd +91 -0
  7. data/doc/en/sample/hiki/rabbit.hiki +0 -4
  8. data/doc/en/sample/rd/rabbit.rd +0 -4
  9. data/doc/en/usage/rabbit-slide.rd +3 -3
  10. data/doc/index.html.en +1 -1
  11. data/doc/ja/faq.rd +2 -0
  12. data/doc/ja/news.rd +90 -0
  13. data/doc/ja/sample/hiki/rabbit.hiki +0 -4
  14. data/doc/ja/sample/rd/rabbit.rd +0 -4
  15. data/doc/ja/usage/rabbit-slide.rd +3 -3
  16. data/doc/ja/users.rd +7 -0
  17. data/lib/rabbit/action/toggle.rb +7 -0
  18. data/lib/rabbit/author-configuration.rb +3 -4
  19. data/lib/rabbit/canvas.rb +11 -1
  20. data/lib/rabbit/command/rabbit-slide.rb +59 -1
  21. data/lib/rabbit/command/rabbit-slide.ui +127 -49
  22. data/lib/rabbit/command/rabbit.rb +5 -9
  23. data/lib/rabbit/element/image.rb +78 -94
  24. data/lib/rabbit/element/video.rb +3 -11
  25. data/lib/rabbit/error.rb +2 -2
  26. data/lib/rabbit/frame.rb +102 -4
  27. data/lib/rabbit/gem-pusher.rb +28 -6
  28. data/lib/rabbit/image/base.rb +97 -26
  29. data/lib/rabbit/image/dia.rb +21 -6
  30. data/lib/rabbit/image/pdf.rb +1 -4
  31. data/lib/rabbit/image/svg.rb +1 -4
  32. data/lib/rabbit/image.rb +3 -4
  33. data/lib/rabbit/info-window.rb +106 -80
  34. data/lib/rabbit/keys.rb +6 -0
  35. data/lib/rabbit/menu.rb +2 -0
  36. data/lib/rabbit/parser/ext/charty.rb +58 -0
  37. data/lib/rabbit/parser/ext/image.rb +2 -1
  38. data/lib/rabbit/parser/rd/ext/block-verbatim.rb +13 -5
  39. data/lib/rabbit/progress.rb +1 -1
  40. data/lib/rabbit/properties.rb +141 -0
  41. data/lib/rabbit/rabbit.rb +3 -1
  42. data/lib/rabbit/relative-size.rb +28 -0
  43. data/lib/rabbit/renderer/base.rb +6 -0
  44. data/lib/rabbit/renderer/display/drawing-area-base.rb +0 -1
  45. data/lib/rabbit/renderer/display/drawing-area-primitive.rb +1 -0
  46. data/lib/rabbit/renderer/display/info.rb +6 -1
  47. data/lib/rabbit/renderer/display/key-handler.rb +27 -2
  48. data/lib/rabbit/renderer/engine/cairo.rb +24 -3
  49. data/lib/rabbit/renderer/screen.rb +0 -1
  50. data/lib/rabbit/slide-configuration.rb +12 -8
  51. data/lib/rabbit/task/slide.rb +3 -3
  52. data/lib/rabbit/theme/clear-blue/clear-blue.rb +3 -1
  53. data/lib/rabbit/theme/edge-info-toolkit/edge-info-toolkit.rb +12 -2
  54. data/lib/rabbit/theme/image-slide-number/image-slide-number.rb +1 -1
  55. data/lib/rabbit/theme/slide-footer-info/slide-footer-info.rb +2 -0
  56. data/lib/rabbit/theme/tag/tag.rb +9 -2
  57. data/lib/rabbit/theme-configuration.rb +3 -4
  58. data/lib/rabbit/version.rb +1 -1
  59. data/lib/rabbit/video-window.rb +14 -3
  60. data/lib/rabbit/yaml-loader.rb +39 -0
  61. data/po/en/rabbit.edit.po +82 -64
  62. data/po/en/rabbit.po +16 -2
  63. data/po/fr/rabbit.edit.po +81 -63
  64. data/po/fr/rabbit.po +15 -1
  65. data/po/ja/rabbit.edit.po +108 -65
  66. data/po/ja/rabbit.po +19 -3
  67. data/sample/can_rabbit.rd +0 -24
  68. data/sample/rabbit-en.hiki +0 -4
  69. data/sample/rabbit-en.rd +0 -4
  70. data/sample/rabbit.hiki +0 -4
  71. data/sample/rabbit.rd +0 -4
  72. data/test/test-slide-configuration.rb +3 -2
  73. metadata +27 -24
@@ -62,7 +62,7 @@ module Rabbit
62
62
  @window.signal_handler_disconnect(@window_destroy_id)
63
63
  @window.destroy
64
64
  @window = @window_destroy_id = nil
65
- @canvas_widgets = @outer_box = nil
65
+ @canvas_widgets = @grid = nil
66
66
  GLib::Source.remove(@timer_id) if @timer_id
67
67
  @timer_id = nil
68
68
  @previous_canvas = @current_canvas = @next_canvas = nil
@@ -72,9 +72,9 @@ module Rabbit
72
72
  !@window.nil?
73
73
  end
74
74
 
75
- def moved(index)
75
+ def moved
76
76
  return unless showing?
77
- update(index)
77
+ update
78
78
  end
79
79
 
80
80
  def parsed
@@ -114,13 +114,14 @@ module Rabbit
114
114
  @window = Gtk::Window.new
115
115
  @window_destroy_id = @window.signal_connect("destroy") do
116
116
  @canvas.activate("ToggleInfoWindow")
117
+ Gdk::Event::PROPAGATE
117
118
  end
118
119
  @window.title = _("%s: Information window") % @canvas.title
119
120
  @window.set_default_size(width, height) if width and height
120
121
  if on_note_mode?
121
- init_widgets_on_note_mode(width, height)
122
+ init_widgets_on_note_mode
122
123
  else
123
- init_widgets(width, height)
124
+ init_widgets
124
125
  end
125
126
  init_menu
126
127
  attach_key(@window)
@@ -133,61 +134,91 @@ module Rabbit
133
134
  @window.add_events(event_mask)
134
135
  set_button_event(@window)
135
136
  set_scroll_event(@window)
136
- @window.add(@outer_box)
137
+ @window.add(@grid)
137
138
  end
138
139
 
139
- def init_widgets(width, height)
140
- init_timer_label(width * (1.0 / 3.0), height * (1.0 / 3.0))
141
- @outer_box = Gtk::Box.new(:vertical)
142
-
143
- current_box = Gtk::Box.new(:horizontal)
144
- @current_canvas.attach_to(nil, @window, current_box) do |container, widget|
145
- widget.set_size_request(width * (2.0 / 3.0), height * (2.0 / 3.0))
146
- container.pack_start(widget, :expand => true, :fill => false)
140
+ def init_widgets
141
+ init_timer_area
142
+ @grid = Gtk::Grid.new
143
+ @grid.column_homogeneous = true
144
+ @grid.row_homogeneous = true
145
+
146
+ base_width = 1
147
+ base_height = 1
148
+ @current_canvas.attach_to(nil, @window, @grid) do |container, widget|
149
+ container.attach(widget,
150
+ base_width,
151
+ 0,
152
+ base_width * 2,
153
+ base_height * 2)
147
154
  end
148
- @outer_box.pack_start(current_box, :expand => true, :fill => false)
149
155
 
150
- bottom_box = Gtk::Box.new(:horizontal)
151
- @previous_canvas.attach_to(nil, @window, bottom_box) do |container, widget|
152
- widget.set_size_request(width * (1.0 / 3.0), height * (1.0 / 3.0))
153
- container.pack_start(widget, :expand => false, :fill => false)
156
+ @previous_canvas.attach_to(nil, @window, @grid) do |container, widget|
157
+ container.attach(widget,
158
+ 0,
159
+ base_height * 2,
160
+ base_width,
161
+ base_height)
154
162
  end
155
- bottom_box.pack_start(@timer_label, :expand => true, :fill => false)
156
- @next_canvas.attach_to(nil, @window, bottom_box) do |container, widget|
157
- widget.set_size_request(width * (1.0 / 3.0), height * (1.0 / 3.0))
158
- container.pack_end(widget, :expand => false, :fill => false)
163
+ @next_canvas.attach_to(nil, @window, @grid) do |container, widget|
164
+ container.attach(widget,
165
+ base_width * 3,
166
+ base_height * 2,
167
+ base_width,
168
+ base_height)
159
169
  end
160
- @outer_box.pack_end(bottom_box, :expand => false, :fill => false)
161
170
 
162
- @outer_box.show
171
+ @grid.attach(@timer_area,
172
+ base_width,
173
+ base_height * 2,
174
+ base_width * 2,
175
+ base_height)
176
+
177
+ @grid.show
163
178
  end
164
179
 
165
- def init_widgets_on_note_mode(width, height)
166
- init_timer_label(width * (1.0 / 5.0), height * (2.0 / 5.0))
180
+ def init_widgets_on_note_mode
181
+ init_timer_area
167
182
  init_note_area
168
- @outer_box = Gtk::Box.new(:vertical)
169
-
170
- current_box = Gtk::Box.new(:horizontal)
171
- current_box.pack_start(@timer_label, :expand => false, :fill => false)
172
- @previous_canvas.attach_to(nil, @window, current_box) do |container, widget|
173
- widget.set_size_request(width * (1.0 / 5.0), height * (2.0 / 5.0))
174
- container.pack_start(widget, :expand => true, :fill => true, :padding => 10)
183
+ @grid = Gtk::Grid.new
184
+ @grid.column_homogeneous = true
185
+ @grid.row_homogeneous = true
186
+
187
+ base_width = 1
188
+ base_height = 4
189
+ @previous_canvas.attach_to(nil, @window, @grid) do |container, widget|
190
+ container.attach(widget,
191
+ 0,
192
+ 0,
193
+ base_width,
194
+ base_height)
175
195
  end
176
- @current_canvas.attach_to(nil, @window, current_box) do |container, widget|
177
- widget.set_size_request(width * (2.0 / 5.0), height * (2.0 / 5.0))
178
- container.pack_start(widget, :expand => true, :fill => true)
196
+ @current_canvas.attach_to(nil, @window, @grid) do |container, widget|
197
+ container.attach(widget,
198
+ base_width,
199
+ 0,
200
+ base_width * 2,
201
+ base_height)
179
202
  end
180
- @next_canvas.attach_to(nil, @window, current_box) do |container, widget|
181
- widget.set_size_request(width * (1.0 / 5.0), height * (2.0 / 5.0))
182
- container.pack_end(widget, :expand => true, :fill => true, :padding => 10)
203
+ @next_canvas.attach_to(nil, @window, @grid) do |container, widget|
204
+ container.attach(widget,
205
+ base_width * 3,
206
+ 0,
207
+ base_width,
208
+ base_height)
183
209
  end
184
- @outer_box.pack_start(current_box, :expand => false, :fill => false)
185
-
186
- bottom_box = Gtk::Box.new(:horizontal)
187
- bottom_box.pack_start(@note_area, :expand => true, :fill => true, :padding => 20)
188
- @outer_box.pack_start(bottom_box, :expand => true, :fill => true, :padding => 20)
189
210
 
190
- @outer_box.show
211
+ @grid.attach(@note_area,
212
+ 0,
213
+ base_height,
214
+ base_width * 4,
215
+ base_height)
216
+ @grid.attach(@timer_area,
217
+ 0,
218
+ base_height * 2,
219
+ base_width * 4,
220
+ 1)
221
+ @grid.show
191
222
  end
192
223
 
193
224
  def init_canvas_widgets
@@ -196,10 +227,16 @@ module Rabbit
196
227
  @next_canvas.attach_to(nil, @window, @canvas_widgets)
197
228
  end
198
229
 
199
- def init_timer_label(width, height)
200
- @timer_label = Gtk::Label.new
201
- @timer_label.justify = :center
202
- @timer_label.markup = markupped_timer_label(width, height)
230
+ def init_timer_area
231
+ @timer_area = Gtk::DrawingArea.new
232
+ @timer_area.signal_connect("draw") do |area, context|
233
+ context.set_source_rgb(1, 0, 0) if rest_time and rest_time < 0
234
+ draw_text_as_large_as_possible(area,
235
+ context,
236
+ timer_text,
237
+ alignment: :center)
238
+ Gdk::Event::PROPAGATE
239
+ end
203
240
  end
204
241
 
205
242
  def init_note_area
@@ -210,10 +247,10 @@ module Rabbit
210
247
  end
211
248
  end
212
249
 
213
- def update(index=nil)
250
+ def update
214
251
  start_timer if @timer_id.nil?
215
252
  @note_area.queue_draw if @note_area
216
- adjust_slide(index)
253
+ adjust_slide
217
254
  end
218
255
 
219
256
  def note_text
@@ -222,10 +259,14 @@ module Rabbit
222
259
  note.gsub(/\\n/, "\n")
223
260
  end
224
261
 
225
- def draw_text_as_large_as_possible(area, context, markupped_text)
262
+ def draw_text_as_large_as_possible(area,
263
+ context,
264
+ markupped_text,
265
+ options={})
226
266
  return if markupped_text.nil?
227
267
 
228
- area_width, area_height = area.window.size
268
+ area_width = area.window.width
269
+ area_height = area.window.height
229
270
 
230
271
  layout = context.create_pango_layout
231
272
  layout.context.resolution = @canvas.font_resolution
@@ -234,6 +275,9 @@ module Rabbit
234
275
  layout.attributes = attributes
235
276
  layout.width = area_width * Pango::SCALE
236
277
  layout.wrap = :word_char
278
+ layout.alignment = options[:alignment] if options.key?(:alignment)
279
+
280
+ layout.justify = options[:justify] if options.key?(:justify)
237
281
  set_as_large_as_font_description(layout, area_height)
238
282
 
239
283
  context.update_pango_layout(layout)
@@ -258,8 +302,8 @@ module Rabbit
258
302
 
259
303
  def start_timer
260
304
  @timer_id = GLib::Timeout.add(1000) do
261
- @timer_label.markup = markupped_timer_label if showing?
262
305
  if showing? and @canvas.rest_time
306
+ @timer_area.queue_draw
263
307
  GLib::Source::CONTINUE
264
308
  else
265
309
  @timer_id = nil
@@ -268,19 +312,11 @@ module Rabbit
268
312
  end
269
313
  end
270
314
 
271
- def markupped_timer_label(width=nil, height=nil)
272
- width ||= @window.size[0] * (1.0 / 3.0)
273
- height ||= @window.size[1] * (1.0 / 3.0)
274
- attrs = {}
275
- font_size = on_note_mode? ? 100 : 200
276
- attrs["font_desc"] = ((height * font_size) / Pango::SCALE).to_s
277
- rest_time = @canvas.rest_time
278
- attrs["foreground"] = "red" if rest_time and rest_time < 0
279
- PangoMarkup.new("span", attrs, timer_label).to_s
315
+ def rest_time
316
+ @canvas.rest_time || @canvas.allotted_time
280
317
  end
281
318
 
282
- def timer_label
283
- rest_time = @canvas.rest_time || @canvas.allotted_time
319
+ def timer_text
284
320
  if rest_time
285
321
  "%s%02d:%02d" % Utils.split_number_to_minute_and_second(rest_time)
286
322
  else
@@ -288,18 +324,6 @@ module Rabbit
288
324
  end
289
325
  end
290
326
 
291
- def markupped_note_text(width=nil, height=nil)
292
- height ||= @window.size[1] * (3.0 / 5.0)
293
- if @canvas.current_slide["note"]
294
- text = @canvas.current_slide["note"].gsub(/\\n/, "\n")
295
- else
296
- text = ""
297
- end
298
- attrs = {}
299
- attrs["font_desc"] = ((height * 40) / Pango::SCALE).to_s
300
- PangoMarkup.new("span", attrs, text).to_s
301
- end
302
-
303
327
  def update_source
304
328
  each do |canvas|
305
329
  source = Source::Memory.new("UTF-8", @canvas.logger)
@@ -319,10 +343,12 @@ module Rabbit
319
343
  end
320
344
  end
321
345
 
322
- def adjust_slide(base_index=nil)
323
- base_index ||= @canvas.current_index
346
+ def adjust_slide
347
+ base_index = @canvas.current_index
324
348
  @previous_canvas.move_to_if_can([base_index - 1, 0].max)
325
349
  @current_canvas.move_to_if_can(base_index)
350
+ @current_canvas.current_slide.drawing_index =
351
+ @canvas.current_slide.drawing_index
326
352
  @next_canvas.move_to_if_can([base_index + 1, @canvas.slide_size - 1].min)
327
353
  end
328
354
 
data/lib/rabbit/keys.rb CHANGED
@@ -178,5 +178,11 @@ module Rabbit
178
178
  Gdk::Keyval::KEY_t,
179
179
  ]
180
180
  end
181
+
182
+ module ShiftControlAlt
183
+ TOGGLE_TERMINAL_KEYS = [
184
+ Gdk::Keyval::KEY_t,
185
+ ]
186
+ end
181
187
  end
182
188
  end
data/lib/rabbit/menu.rb CHANGED
@@ -260,6 +260,8 @@ module Rabbit
260
260
  [:item, "ToggleSpotlight"],
261
261
  [:item, "ToggleMagnifier"],
262
262
  [:separator],
263
+ [:item, "ToggleTerminal"],
264
+ [:separator],
263
265
  [:menu, "JumpTo"],
264
266
  [:separator],
265
267
  [:item, "Previous"],
@@ -0,0 +1,58 @@
1
+ # Copyright (C) 2021 Kouhei Sutou <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 "csv"
18
+
19
+ module Rabbit
20
+ module Parser
21
+ module Ext
22
+ module Charty
23
+ include GetText
24
+
25
+ module_function
26
+ def make_image(path, prop, logger)
27
+ require "charty"
28
+ backend = prop["backend"]
29
+ ::Charty::Backends.use(backend) if backend
30
+ data = CSV.read(path, headers: true, converters: :all)
31
+ type = prop["type"]
32
+ case type
33
+ when "bar"
34
+ plotter = ::Charty.bar_plot(data: data,
35
+ x: prop["x"],
36
+ y: prop["y"],
37
+ color: prop["color"])
38
+ when "line"
39
+ plotter = ::Charty.line_plot(data: data,
40
+ x: prop["x"],
41
+ y: prop["y"],
42
+ color: prop["color"])
43
+ when "scatter"
44
+ plotter = ::Charty.scatter_plot(data: data,
45
+ x: prop["x"],
46
+ y: prop["y"],
47
+ color: prop["color"])
48
+ else
49
+ raise ArgumentError, "charty: unsupported type: #{type.inspect}"
50
+ end
51
+ image_file = Tempfile.new(["rabbit-image-charty", ".svg"])
52
+ plotter.save(image_file.path)
53
+ image_file
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -108,8 +108,9 @@ module Rabbit
108
108
  end
109
109
 
110
110
  def setup_image_file(canvas, uri, filename)
111
+ return if File.exist?(filename)
111
112
  begin
112
- open(uri, "rb") do |in_file|
113
+ URI.open(uri, "rb") do |in_file|
113
114
  File.open(filename, "wb") do |out|
114
115
  out.print(in_file.read)
115
116
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2004-2017 Kouhei Sutou <kou@cozmixng.org>
1
+ # Copyright (C) 2004-2021 Kouhei Sutou <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
@@ -26,6 +26,7 @@ require "rabbit/parser/ext/enscript"
26
26
  require "rabbit/parser/ext/tex"
27
27
  require "rabbit/parser/ext/aafigure"
28
28
  require "rabbit/parser/ext/blockdiag"
29
+ require "rabbit/parser/ext/charty"
29
30
  require "rabbit/parser/ext/coderay"
30
31
  require "rabbit/parser/ext/emacs"
31
32
  require "rabbit/parser/ext/rouge"
@@ -86,7 +87,7 @@ module Rabbit
86
87
 
87
88
  def ext_block_verb_enscript(label, source, content, visitor)
88
89
  return nil unless /\Aenscript (\w+)\z/i =~ label
89
- lang = $1.downcase.untaint
90
+ lang = $1.downcase
90
91
 
91
92
  src, prop = parse_source(source)
92
93
  logger = visitor.logger
@@ -129,7 +130,7 @@ module Rabbit
129
130
 
130
131
  def ext_block_verb_coderay(label, source, content, visitor)
131
132
  return nil unless /\Acoderay (\w+)\z/i =~ label
132
- lang = $1.downcase.untaint
133
+ lang = $1.downcase
133
134
 
134
135
  src, prop = parse_source(source)
135
136
  logger = visitor.logger
@@ -140,7 +141,7 @@ module Rabbit
140
141
 
141
142
  def ext_block_verb_emacs(label, source, content, visitor)
142
143
  return nil unless /\Aemacs(?:\s+(.+))?\z/i =~ label
143
- mode_line = $1.untaint
144
+ mode_line = $1
144
145
 
145
146
  src, prop = parse_source(source)
146
147
  logger = visitor.logger
@@ -193,7 +194,7 @@ module Rabbit
193
194
 
194
195
  def ext_block_verb_rouge(label, source, content, visitor)
195
196
  return nil unless /\Arouge (\w+)\z/i =~ label
196
- lang = $1.downcase.untaint
197
+ lang = $1.downcase
197
198
 
198
199
  src, prop = parse_source(source)
199
200
  logger = visitor.logger
@@ -201,6 +202,13 @@ module Rabbit
201
202
  result = Parser::Ext::Rouge.highlight(lang, src, logger)
202
203
  result || default_ext_block_verbatim(label, src, src, visitor)
203
204
  end
205
+
206
+ def ext_block_verb_charty(label, source, content, visitor)
207
+ return nil unless /\Acharty\z/i =~ label
208
+ make_image_from_file(source, visitor) do |src_file_path, prop|
209
+ Parser::Ext::Charty.make_image(src_file_path, prop, visitor)
210
+ end
211
+ end
204
212
  end
205
213
  end
206
214
  end
@@ -92,7 +92,7 @@ trough {
92
92
  provider = Gtk::CssProvider.new
93
93
  provider.load(:data => css)
94
94
  @bar.style_context.add_provider(provider,
95
- Gtk::StyleProvider::PRIORITY_USER)
95
+ Gtk::StyleProvider::PRIORITY_USER)
96
96
  end
97
97
  end
98
98
  end
@@ -0,0 +1,141 @@
1
+ # Copyright (C) 2020 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 "rabbit/relative-size"
18
+
19
+ module Rabbit
20
+ class Properties
21
+ include Enumerable
22
+
23
+ def initialize(data)
24
+ @data = normalize(data)
25
+ end
26
+
27
+ def [](key)
28
+ @data[normalize_key(key)]
29
+ end
30
+
31
+ def []=(key, value)
32
+ @data[normalize_key(key)] = value
33
+ end
34
+
35
+ def each(&block)
36
+ @data.each(&block)
37
+ end
38
+
39
+ def get_boolean(key, default=nil)
40
+ value = self[key]
41
+ return default if value.nil?
42
+ true_value?(value)
43
+ end
44
+
45
+ def get_integer(key, default=nil)
46
+ integer_value(self[key] || default)
47
+ end
48
+
49
+ def get_float(key, default=nil)
50
+ float_value(self[key] || default)
51
+ end
52
+
53
+ def get_size(key, filename, default=nil)
54
+ size_value(self[key] || default, filename, key)
55
+ end
56
+
57
+ def get_relative_size(key, filename, default=nil)
58
+ relative_size_value(self[key] || default,
59
+ filename,
60
+ key)
61
+ end
62
+
63
+ def respond_to_missing?(name, include_private)
64
+ @data.key?(normalize_key(name.to_s.gsub(/\?\z/, "")))
65
+ end
66
+
67
+ def method_missing(name, *args, &block)
68
+ case args.size
69
+ when 0
70
+ key = name.to_s
71
+ if key.end_with?("?")
72
+ key = key[0..-2]
73
+ is_predict = true
74
+ else
75
+ is_predict = false
76
+ end
77
+ key = normalize_key(key)
78
+ return super unless @data.key?(key)
79
+ value = @data[key]
80
+ if is_predict
81
+ true_value?(value)
82
+ else
83
+ value
84
+ end
85
+ when 1
86
+ key = name.to_s
87
+ return super unless key.end_with?("=")
88
+ key = key[0..-2]
89
+ @data[normalize_key(key)] = args[0]
90
+ else
91
+ super
92
+ end
93
+ end
94
+
95
+ private
96
+ def normalize(data)
97
+ normalized_data = {}
98
+ (data || {}).each do |key, value|
99
+ normalized_data[normalize_key(key)] = value
100
+ end
101
+ normalized_data
102
+ end
103
+
104
+ def normalize_key(key)
105
+ key.to_s.gsub(/-/, "_")
106
+ end
107
+
108
+ def true_value?(value)
109
+ value == true or value == "true"
110
+ end
111
+
112
+ def integer_value(value)
113
+ return nil if value.nil?
114
+ Integer(value, 10)
115
+ end
116
+
117
+ def float_value(value)
118
+ return nil if value.nil?
119
+ Float(value)
120
+ end
121
+
122
+ def size_value(value, filename, name)
123
+ return nil if value.nil?
124
+ begin
125
+ Integer(value, 10)
126
+ rescue ArgumentError
127
+ raise InvalidSizeError.new(filename, name, value)
128
+ end
129
+ end
130
+
131
+ def relative_size_value(value, filename, name)
132
+ return nil if value.nil?
133
+ begin
134
+ value = Float(value)
135
+ rescue ArgumentError
136
+ raise InvalidSizeError.new(filename, name, value)
137
+ end
138
+ RelativeSize.new(value)
139
+ end
140
+ end
141
+ end
data/lib/rabbit/rabbit.rb CHANGED
@@ -32,7 +32,9 @@ module Rabbit
32
32
 
33
33
  class << self
34
34
  def application
35
- @@application ||= Gtk::Application.new(nil, :handles_command_line)
35
+ @@application ||=
36
+ Gtk::Application.new("org.rabbit-shocker.Rabbit",
37
+ [:non_unique, :handles_command_line])
36
38
  end
37
39
  end
38
40
  end
@@ -0,0 +1,28 @@
1
+ # Copyright (C) 2020 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
+ module Rabbit
18
+ class RelativeSize
19
+ def initialize(size)
20
+ @size = size
21
+ end
22
+
23
+ def resolve(base_size)
24
+ return nil if base_size.nil?
25
+ ((@size / 100.0) * base_size).ceil
26
+ end
27
+ end
28
+ end
@@ -267,6 +267,12 @@ module Rabbit
267
267
  def add_gesture_action(sequence, action, &block)
268
268
  end
269
269
 
270
+ def pre_terminal
271
+ end
272
+
273
+ def post_terminal
274
+ end
275
+
270
276
  private
271
277
  def offscreen_renderer?
272
278
  false
@@ -5,7 +5,6 @@ require "rabbit/renderer/display/mask"
5
5
  require "rabbit/renderer/display/search"
6
6
  require "rabbit/renderer/display/gesture"
7
7
  require "rabbit/renderer/display/graffiti"
8
- require "rabbit/renderer/display/menu"
9
8
  require "rabbit/renderer/display/button-handler"
10
9
  require "rabbit/renderer/display/key-handler"
11
10
  require "rabbit/renderer/display/scroll-handler"
@@ -83,6 +83,7 @@ module Rabbit
83
83
 
84
84
  def post_parse
85
85
  clear_compiled_slides
86
+ update_cursor(:blank, true)
86
87
  end
87
88
 
88
89
  def pre_toggle_index_mode