rabbit 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
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