ffi-efl 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -36,6 +36,8 @@ module Efl
36
36
  enum :evas_button_flags, [ :evas_button_none, 0, :evas_button_double_click, :evas_button_triple_click ]
37
37
  # typedef enum _Evas_Event_Flags {...} Evas_Event_Flags;
38
38
  enum :evas_event_flags, [ :evas_event_flag_none, 0, :evas_event_flag_on_hold, :evas_event_flag_on_scroll ]
39
+ # typedef enum _Evas_Touch_Point_State {...} Evas_Touch_Point_State;
40
+ enum :evas_touch_point_state, [ :evas_touch_point_down, :evas_touch_point_up, :evas_touch_point_move, :evas_touch_point_still, :evas_touch_point_cancel ]
39
41
  # typedef enum _Evas_Font_Hinting_Flags {...} Evas_Font_Hinting_Flags;
40
42
  enum :evas_font_hinting_flags, [ :evas_font_hinting_none, :evas_font_hinting_auto, :evas_font_hinting_bytecode ]
41
43
  # typedef enum _Evas_Colorspace {...} Evas_Colorspace;
@@ -136,6 +138,9 @@ module Efl
136
138
  # typedef struct _Evas_Native_Surface Evas_Native_Surface;
137
139
  typedef :pointer, :evas_native_surface
138
140
  typedef :pointer, :evas_native_surface_p
141
+ # typedef struct _Evas_Video_Surface Evas_Video_Surface;
142
+ typedef :pointer, :evas_video_surface
143
+ typedef :pointer, :evas_video_surface_p
139
144
  # typedef unsigned long long Evas_Modifier_Mask;
140
145
  typedef :ulong_long, :evas_modifier_mask
141
146
  # typedef int Evas_Coord;
@@ -213,6 +218,10 @@ module Efl
213
218
  typedef :pointer, :evas_cserve_config_p
214
219
  #
215
220
  # CALLBACKS
221
+ # typedef void (*Evas_Video_Cb) (void *data, Evas_Object *obj, const Evas_Video_Surface *surface);
222
+ callback :evas_video_cb, [ :void_p, :evas_object_p, :evas_video_surface_p ], :void
223
+ # typedef void (*Evas_Video_Coord_Cb) (void *data, Evas_Object *obj, const Evas_Video_Surface *surface, Evas_Coord a, Evas_Coord b);
224
+ callback :evas_video_coord_cb, [ :void_p, :evas_object_p, :evas_video_surface_p, :int, :int ], :void
216
225
  # typedef void (*Evas_Smart_Cb) (void *data, Evas_Object *obj, void *event_info);
217
226
  callback :evas_smart_cb, [ :void_p, :evas_object_p, :void_p ], :void
218
227
  # typedef void (*Evas_Event_Cb) (void *data, Evas *e, void *event_info);
@@ -408,6 +417,8 @@ module Efl
408
417
  [ :evas_image_cache_set, [ :evas_p, :int ], :void ],
409
418
  # EAPI int evas_image_cache_get (const Evas *e);
410
419
  [ :evas_image_cache_get, [ :evas_p ], :int ],
420
+ # EAPI Eina_Bool evas_image_max_size_get (const Evas *e, int *maxw, int *maxh);
421
+ [ :evas_image_max_size_get, [ :evas_p, :int_p, :int_p ], :eina_bool ],
411
422
  # EAPI void evas_font_hinting_set (Evas *e, Evas_Font_Hinting_Flags hinting);
412
423
  [ :evas_font_hinting_set, [ :evas_p, :evas_font_hinting_flags ], :void ],
413
424
  # EAPI Evas_Font_Hinting_Flags evas_font_hinting_get (const Evas *e);
@@ -510,6 +521,10 @@ module Efl
510
521
  [ :evas_object_propagate_events_set, [ :evas_object_p, :eina_bool ], :void ],
511
522
  # EAPI Eina_Bool evas_object_propagate_events_get (const Evas_Object *obj);
512
523
  [ :evas_object_propagate_events_get, [ :evas_object_p ], :eina_bool ],
524
+ # EAPI void evas_object_freeze_events_set(Evas_Object *obj, Eina_Bool freeze);
525
+ [ :evas_object_freeze_events_set, [ :evas_object_p, :eina_bool ], :void ],
526
+ # EAPI Eina_Bool evas_object_freeze_events_get(const Evas_Object *obj);
527
+ [ :evas_object_freeze_events_get, [ :evas_object_p ], :eina_bool ],
513
528
  # EAPI void evas_object_map_enable_set (Evas_Object *obj, Eina_Bool enabled);
514
529
  [ :evas_object_map_enable_set, [ :evas_object_p, :eina_bool ], :void ],
515
530
  # EAPI Eina_Bool evas_object_map_enable_get (const Evas_Object *obj);
@@ -798,6 +813,10 @@ module Efl
798
813
  [ :evas_object_image_native_surface_set, [ :evas_object_p, :evas_native_surface_p ], :void ],
799
814
  # EAPI Evas_Native_Surface *evas_object_image_native_surface_get (const Evas_Object *obj);
800
815
  [ :evas_object_image_native_surface_get, [ :evas_object_p ], :evas_native_surface_p ],
816
+ # EAPI void evas_object_image_video_surface_set (Evas_Object *obj, Evas_Video_Surface *surf);
817
+ [ :evas_object_image_video_surface_set, [ :evas_object_p, :evas_video_surface_p ], :void ],
818
+ # EAPI const Evas_Video_Surface *evas_object_image_video_surface_get (const Evas_Object *obj);
819
+ [ :evas_object_image_video_surface_get, [ :evas_object_p ], :evas_video_surface_p ],
801
820
  # EAPI void evas_object_image_scale_hint_set (Evas_Object *obj, Evas_Image_Scale_Hint hint);
802
821
  [ :evas_object_image_scale_hint_set, [ :evas_object_p, :evas_image_scale_hint ], :void ],
803
822
  # EAPI Evas_Image_Scale_Hint evas_object_image_scale_hint_get (const Evas_Object *obj);
@@ -1326,6 +1345,14 @@ module Efl
1326
1345
  [ :evas_object_key_grab, [ :evas_object_p, :string, :ulong_long, :ulong_long, :eina_bool ], :eina_bool ],
1327
1346
  # EAPI void evas_object_key_ungrab (Evas_Object *obj, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers);
1328
1347
  [ :evas_object_key_ungrab, [ :evas_object_p, :string, :ulong_long, :ulong_long ], :void ],
1348
+ # EAPI unsigned int evas_touch_point_list_count(Evas *e);
1349
+ [ :evas_touch_point_list_count, [ :evas_p ], :uint ],
1350
+ # EAPI void evas_touch_point_list_nth_xy_get(Evas *e, unsigned int n, Evas_Coord *x, Evas_Coord *y);
1351
+ [ :evas_touch_point_list_nth_xy_get, [ :evas_p, :uint, :int_p, :int_p ], :void ],
1352
+ # EAPI int evas_touch_point_list_nth_id_get(Evas *e, unsigned int n);
1353
+ [ :evas_touch_point_list_nth_id_get, [ :evas_p, :uint ], :int ],
1354
+ # EAPI Evas_Touch_Point_State evas_touch_point_list_nth_state_get(Evas *e, unsigned int n);
1355
+ [ :evas_touch_point_list_nth_state_get, [ :evas_p, :uint ], :evas_touch_point_state ],
1329
1356
  ]
1330
1357
  #
1331
1358
  attach_fcts fcts
@@ -5,7 +5,7 @@ require 'efl/eina_list'
5
5
  require 'efl/ecore_evas'
6
6
  require './spec/helper'
7
7
  #
8
- describe Efl::EcoreEvas do
8
+ describe 'Efl::EcoreEvas' do
9
9
  #
10
10
  before(:all) do
11
11
  EcoreEvas = Efl::EcoreEvas
@@ -7,7 +7,7 @@ require 'efl/eina_list'
7
7
  require 'efl/eina_rectangle'
8
8
  require 'efl/ecore_getopt'
9
9
  #
10
- describe Efl::EcoreGetopt do
10
+ describe 'Efl::EcoreGetopt' do
11
11
  #
12
12
  after(:all) do
13
13
  Efl::Ecore.shutdown
@@ -3,7 +3,7 @@
3
3
  #
4
4
  require 'efl/ecore_input'
5
5
  #
6
- describe Efl::EcoreInput do
6
+ describe 'Efl::EcoreInput' do
7
7
  #
8
8
  before(:all) do
9
9
  EcoreInput = Efl::EcoreInput
data/spec/ecore_spec.rb CHANGED
@@ -130,7 +130,7 @@ describe "Efl::Ecore #{Efl::Ecore.version.full}" do
130
130
  e2.free
131
131
  end
132
132
  #
133
- describe Efl::Ecore::REcorePipe do
133
+ describe 'Efl::Ecore::REcorePipe' do
134
134
  #
135
135
  it 'should write and read data from pipe' do
136
136
  data = FFI::MemoryPointer.from_string("none")
data/spec/edje_spec.rb CHANGED
@@ -94,7 +94,7 @@ describe "Efl::Edje #{Efl::Edje.version.full}" do
94
94
  # TODO edje_color_class*
95
95
  # TODO edje_text_class*
96
96
  #
97
- describe Efl::Edje::REdje do
97
+ describe 'Efl::Edje::REdje' do
98
98
  before(:all) do
99
99
  Efl::Evas.init
100
100
  realize_evas
data/spec/eet_spec.rb CHANGED
@@ -42,7 +42,7 @@ describe "Efl::Eet #{Efl::Eet.version.full}" do
42
42
  Native.enum_type(:eet_file_mode)[:eet_file_mode_read_write].should == 2
43
43
  end
44
44
  #
45
- describe Efl::Eet::REetFile do
45
+ describe 'Efl::Eet::REetFile' do
46
46
  #
47
47
  it "should open and close" do
48
48
  f = REetFile.open FP, Native.enum_type(:eet_file_mode)[:eet_file_mode_write]
@@ -83,7 +83,7 @@ describe "Efl::Eet #{Efl::Eet.version.full}" do
83
83
  f = REetFile.open FP, :eet_file_mode_read_write
84
84
  f.write 'configg', 'test key'
85
85
  f.read('configg').should == 'test key'
86
- # f.close #leave it to FFI::AutoPointer
86
+ f.close
87
87
  end
88
88
  #
89
89
  it "should write in block" do
@@ -4,7 +4,7 @@
4
4
  require 'efl'
5
5
  require 'efl/eina_hash'
6
6
  #
7
- describe Efl::EinaHash do
7
+ describe 'Efl::EinaHash' do
8
8
  #
9
9
  before(:all) do
10
10
  REinaHash = Efl::EinaHash::REinaHash
@@ -4,7 +4,7 @@
4
4
  require 'efl/eina'
5
5
  require 'efl/eina_list'
6
6
  #
7
- describe Efl::EinaList do
7
+ describe 'Efl::EinaList' do
8
8
  #
9
9
  before(:all) do
10
10
  REinaList = Efl::EinaList::REinaList
@@ -5,7 +5,7 @@ require 'efl/eina'
5
5
  require 'efl/eina_log'
6
6
  require './spec/helper'
7
7
  #
8
- describe Efl::EinaLog do
8
+ describe 'Efl::EinaLog' do
9
9
  before(:all) do
10
10
  Efl::Eina.init
11
11
  EinaLog = Efl::EinaLog
data/spec/elm_spec.rb CHANGED
@@ -25,7 +25,7 @@ describe "Efl::Elm #{Efl::Elm.version.full}" do
25
25
  Elm.shutdown.should == @init
26
26
  end
27
27
  #
28
- describe Efl::Elm::ElmWin do
28
+ describe 'Efl::Elm::ElmWin' do
29
29
  before(:each) {
30
30
  realize_win
31
31
  }
@@ -179,7 +179,7 @@ describe "Efl::Elm #{Efl::Elm.version.full}" do
179
179
  # TODO EAPI void elm_win_illume_command_send(Evas_Object *obj, Elm_Illume_Command command, void *params);;
180
180
  # TODO EAPI Ecore_X_Window elm_win_xwindow_get(const Evas_Object *obj);
181
181
  #
182
- describe Efl::Elm::ElmInWin do
182
+ describe 'Efl::Elm::ElmInWin' do
183
183
  it "activate, content set/get/unset" do
184
184
  @iwin = @win.inwin_add
185
185
  o1 = @win.evas.object_rectangle_add
@@ -200,7 +200,7 @@ describe "Efl::Elm #{Efl::Elm.version.full}" do
200
200
  end
201
201
  end
202
202
  #
203
- describe Efl::Elm::ElmBg do
203
+ describe 'Efl::Elm::ElmBg' do
204
204
  before(:all) {
205
205
  realize_win
206
206
  }
@@ -242,7 +242,7 @@ describe "Efl::Elm #{Efl::Elm.version.full}" do
242
242
  end
243
243
  end
244
244
  #
245
- describe Efl::Elm::ElmLabel do
245
+ describe 'Efl::Elm::ElmLabel' do
246
246
  #
247
247
  before(:all) {
248
248
  realize_win
@@ -292,7 +292,7 @@ describe "Efl::Elm #{Efl::Elm.version.full}" do
292
292
  end
293
293
  end
294
294
  #
295
- describe Efl::Elm::ElmPager do
295
+ describe 'Efl::Elm::ElmPager' do
296
296
  #
297
297
  before(:all) {
298
298
  realize_win
@@ -323,7 +323,7 @@ describe "Efl::Elm #{Efl::Elm.version.full}" do
323
323
  end
324
324
  end
325
325
  #
326
- describe Efl::Elm::ElmPanel do
326
+ describe 'Efl::Elm::ElmPanel' do
327
327
  #
328
328
  before(:all) {
329
329
  realize_win
data/spec/evas_spec.rb CHANGED
@@ -58,7 +58,7 @@ describe "Efl::Evas #{Efl::Evas.version.full}" do
58
58
  Evas.async_events_process.should == 0
59
59
  end
60
60
  #
61
- describe Efl::Evas::REvas do
61
+ describe 'Efl::Evas::REvas' do
62
62
  before(:all) do
63
63
  realize_evas
64
64
  end
@@ -294,7 +294,7 @@ describe "Efl::Evas #{Efl::Evas.version.full}" do
294
294
  # TODO evas_objects_at_xy_get, evas_objects_in_rectangle_get, evas_object_bottom_get, evas_object_top_get
295
295
  end
296
296
  #
297
- describe Efl::Evas::REvasObject do
297
+ describe 'Efl::Evas::REvasObject' do
298
298
  #
299
299
  before(:all) do
300
300
  realize_evas
@@ -556,7 +556,7 @@ describe "Efl::Evas #{Efl::Evas.version.full}" do
556
556
  #
557
557
  end
558
558
  #
559
- describe Efl::Evas::REvasLine do
559
+ describe 'Efl::Evas::REvasLine' do
560
560
  #
561
561
  before(:all) do
562
562
  realize_evas
@@ -572,7 +572,7 @@ describe "Efl::Evas #{Efl::Evas.version.full}" do
572
572
  end
573
573
  end
574
574
  #
575
- describe Efl::Evas::REvasPolygon do
575
+ describe 'Efl::Evas::REvasPolygon' do
576
576
  #
577
577
  before(:all) do
578
578
  realize_evas
@@ -594,7 +594,7 @@ describe "Efl::Evas #{Efl::Evas.version.full}" do
594
594
  end
595
595
  end
596
596
  #
597
- describe Efl::Evas::REvasText do
597
+ describe 'Efl::Evas::REvasText' do
598
598
  #
599
599
  before(:all) do
600
600
  realize_evas
@@ -702,7 +702,7 @@ describe "Efl::Evas #{Efl::Evas.version.full}" do
702
702
  #
703
703
  end
704
704
  #
705
- describe Efl::Evas::REvasBox do
705
+ describe 'Efl::Evas::REvasBox' do
706
706
  #
707
707
  before(:all) do
708
708
  realize_evas
@@ -188,7 +188,8 @@ class TestWin < Elm::ElmWin
188
188
  @fr.content = lb
189
189
  lb.show
190
190
  end
191
- Elm::ElmToggle.new self do |tg|
191
+ Elm::ElmCheck.new self do |tg|
192
+ tg.style = 'toggle'
192
193
  tg.text = 'UI-Mirroring:'
193
194
  tg.state = Native.elm_mirrored_get
194
195
  tg.smart_callback_add 'changed', method(:tg_changed)
@@ -237,7 +238,7 @@ class TestWin < Elm::ElmWin
237
238
  end
238
239
  #
239
240
  def tg_changed data, evas_obj, event_info
240
- Native.elm_mirrored_set Native.elm_toggle_state_get evas_obj
241
+ Native.elm_mirrored_set Native.elm_check_state_get evas_obj
241
242
  end
242
243
  #
243
244
  def index_changed data, evas_obj, event_info
@@ -0,0 +1,73 @@
1
+ #! /usr/bin/env ruby
2
+ # -*- coding: UTF-8 -*-
3
+ #
4
+ module Tests
5
+ #
6
+ class TestAnchorBlock < Efl::Elm::ElmWin
7
+ def initialize name, title, fct
8
+ super nil, name
9
+ self.title = title
10
+ self.autodel = true
11
+ self.send fct
12
+ @bg.size_hint_min = 160, 160
13
+ @bg.size_hint_max = 640, 640
14
+ self.resize 320, 230
15
+ self.show
16
+ end
17
+ def simple
18
+ @bg = Elm::ElmBg.new self do |bg|
19
+ bg.size_hint_weight_expand
20
+ self.resize_object_add bg
21
+ bg.show
22
+ end
23
+ @sc = Elm::ElmScroller.new self do |sc|
24
+ sc.size_hint_weight_expand
25
+ self.resize_object_add sc
26
+ end
27
+ # evas_object_smart_callback_add(sc, "edge_left", my_anchorblock_edge_left, NULL);
28
+ # evas_object_smart_callback_add(sc, "edge_right", my_anchorblock_edge_right, NULL);
29
+ # evas_object_smart_callback_add(sc, "edge_top", my_anchorblock_edge_top, NULL);
30
+ # evas_object_smart_callback_add(sc, "edge_bottom", my_anchorblock_edge_bottom, NULL);
31
+ # evas_object_smart_callback_add(sc, "scroll", my_anchorblock_scroll, NULL);
32
+ @bx = Elm::ElmBox.new self do |bx|
33
+ bx.size_hint_weight_set Evas::EVAS_HINT_EXPAND, 0.0
34
+ bx.size_hint_align_fill
35
+ bx.show
36
+ end
37
+ ico = Elm::ElmIcon.new self do |ic|
38
+ ic.file = "#{PACKAGE_DATA_DIR}/image/logo_small.png"
39
+ end
40
+ end
41
+ def cb_radio_changed data, evas_obj, event_info
42
+ @o_bg.option = Elm::ElmRadio.new(evas_obj).value
43
+ end
44
+ def cb_overlay_changed data, evas_obj, event_info
45
+ if Elm::ElmCheck.new(evas_obj).state
46
+ over = @o_bg.parent_widget.evas.edje_object_add
47
+ over.file = "#{PACKAGE_DATA_DIR}/objects/test.edj", "bg_overlay"
48
+ @o_bg.overlay = over
49
+ else
50
+ @o_bg.overlay = FFI::Pointer::NULL
51
+ end
52
+ end
53
+ def cb_color_changed data, evas_obj, event_info
54
+ case Elm::ElmSpinner.new(evas_obj).value
55
+ when 1.0
56
+ @o_bg.color = 255, 255, 255
57
+ when 2.0
58
+ @o_bg.color = 255, 0, 0
59
+ when 3.0
60
+ @o_bg.color = 0, 0, 255
61
+ when 4.0
62
+ @o_bg.color = 0, 255, 0
63
+ end
64
+ end
65
+ end
66
+ #
67
+ def self.test_anchorblock
68
+ TestAnchorBlock.new 'anchorblock', 'Anchorblock', :simple
69
+ end
70
+ #
71
+ end
72
+ #
73
+ # EOF
@@ -145,7 +145,7 @@ module Tests
145
145
  def self.test_bg_options
146
146
  TestBg.new 'bg-options', 'Bg Options', :options_bg
147
147
  end
148
- #
148
+ #
149
149
  end
150
150
  #
151
151
  # EOF
@@ -0,0 +1,114 @@
1
+ #! /usr/bin/env ruby
2
+ # -*- coding: UTF-8 -*-
3
+ #
4
+ module Tests
5
+ #
6
+ class TestBg < Efl::Elm::ElmWin
7
+ def initialize name, title, fct
8
+ super nil, name
9
+ self.title = title
10
+ self.autodel = true
11
+ @bg = Elm::ElmBg.new self do |bg|
12
+ bg.size_hint_weight_expand
13
+ self.resize_object_add bg
14
+ bg.show
15
+ end
16
+ self.send fct
17
+ self.resize 320, 480
18
+ self.show
19
+ end
20
+ #
21
+ def __create_butt_ico txt=nil, do_icon=true
22
+ if do_icon
23
+ ico = Elm::ElmIcon.new self
24
+ ico.file = "#{PACKAGE_DATA_DIR}/images/logo_small.png", nil
25
+ else
26
+ ico = nil
27
+ end
28
+ bt = Efl::Elm::ElmButton.new self
29
+ bt.text = txt unless txt.nil?
30
+ bt.icon = ico if ico
31
+ bt.smart_callback_add "clicked", method(:bt_clicked_cb)
32
+ bt.smart_callback_add "unpressed", method(:bt_unpressed_cb)
33
+ @bx.pack_end bt
34
+ @buttons << bt
35
+ ico.show if ico
36
+ bt.show
37
+ [bt,ico]
38
+ end
39
+ #
40
+ def buttons
41
+ @scr = Efl::Elm::ElmScroller.new self do |scr|
42
+ scr.bounce = false, true
43
+ scr.policy = :elm_scroller_policy_off, :elm_scroller_policy_auto
44
+ self.resize_object_add scr
45
+ scr.size_hint_weight_expand
46
+ scr.show
47
+ end
48
+ @bx = Efl::Elm::ElmBox.new self do |bx|
49
+ bx.size_hint_weight_expand
50
+ @scr.content = bx
51
+ bx.show
52
+ end
53
+ #
54
+ @buttons = []
55
+ #
56
+ bt,ico = __create_butt_ico "Icon sized to button"
57
+ ico.size_hint_aspect = :evas_aspect_control_vertical, 1, 1
58
+ #
59
+ bt,ico = __create_butt_ico "Icon no scale"
60
+ ico.scale = false, false
61
+ #
62
+ bt,ico = __create_butt_ico "Disabled Button"
63
+ bt.disabled = true
64
+ ico.size_hint_aspect = :evas_aspect_control_vertical, 1, 1
65
+ #
66
+ bt,ico = __create_butt_ico
67
+ bt.disabled = true
68
+ ico.size_hint_aspect = :evas_aspect_control_vertical, 1, 1
69
+ #
70
+ bt,ico = __create_butt_ico "Label Only", false
71
+ bt.smart_callback_add "repeated", method(:bt_repeated_cb)
72
+ bt.autorepeat = true
73
+ bt.autorepeat_gap_timeout = 0.5
74
+ bt.autorepeat_initial_timeout = 2.0
75
+ #
76
+ bt,ico = __create_butt_ico
77
+ ico.scale = false, false
78
+ #
79
+ bt,ico = __create_butt_ico "Anchor style", false
80
+ bt.style = "anchor"
81
+ #
82
+ bt,ico = __create_butt_ico
83
+ ico.size_hint_aspect = :evas_aspect_control_vertical, 1, 1
84
+ bt.style = "anchor"
85
+ #
86
+ bt,ico = __create_butt_ico
87
+ ico.size_hint_aspect = :evas_aspect_control_vertical, 1, 1
88
+ bt.style = "anchor"
89
+ bt.disabled = true
90
+ bt.access_info_set "This is some custom text describing this widget"
91
+ end
92
+ #
93
+ def bt_clicked_cb data, evas_obj, event_info
94
+ idx = @buttons.index @buttons.find { |b| b.to_ptr==evas_obj }
95
+ puts "clicked event on Button: #{idx+1}"
96
+ end
97
+ #
98
+ def bt_unpressed_cb data, evas_obj, event_info
99
+ idx = @buttons.index @buttons.find { |b| b.to_ptr==evas_obj }
100
+ puts "unpressed event on Button: #{idx+1}"
101
+ end
102
+ #
103
+ def bt_repeated_cb data, evas_obj, event_info
104
+ @count = ((@count||=0)+1)%1000
105
+ Efl::Elm::ElmButton.new(evas_obj).text = "count = #{@count}"
106
+ end
107
+ end
108
+ #
109
+ def self.test_button
110
+ TestBg.new 'buttons', 'Buttons', :buttons
111
+ end
112
+ end
113
+ #
114
+ # EOF