smalruby-editor 0.0.12 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of smalruby-editor might be problematic. Click here for more details.

Files changed (179) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -0
  3. data/.travis.yml +2 -0
  4. data/LEGAL +32 -0
  5. data/Rakefile +1 -1
  6. data/app/assets/demos/default.xml +126 -0
  7. data/app/assets/demos/rgb_led_anode.xml +83 -0
  8. data/app/assets/images/favicon.ico +0 -0
  9. data/app/assets/javascripts/application.js +18 -1
  10. data/app/assets/javascripts/block_mode.js.coffee.erb +10 -0
  11. data/app/assets/javascripts/blocks/blockly.js.coffee.erb +34 -0
  12. data/app/assets/javascripts/blocks/character.js.coffee.erb +76 -0
  13. data/app/assets/javascripts/blocks/control.js.coffee.erb +180 -0
  14. data/app/assets/javascripts/blocks/data.js.coffee.erb +6 -0
  15. data/app/assets/javascripts/blocks/etc.js.coffee.erb +6 -0
  16. data/app/assets/javascripts/blocks/events.js.coffee.erb +82 -0
  17. data/app/assets/javascripts/blocks/hardware.js.coffee.erb +313 -0
  18. data/app/assets/javascripts/blocks/looks.js.coffee.erb +163 -0
  19. data/app/assets/javascripts/blocks/motion.js.coffee.erb +297 -0
  20. data/app/assets/javascripts/blocks/operators.js.coffee.erb +279 -0
  21. data/app/assets/javascripts/blocks/pen.js.coffee.erb +6 -0
  22. data/app/assets/javascripts/blocks/ruby.js.coffee.erb +74 -0
  23. data/app/assets/javascripts/blocks/sensing.js.coffee.erb +241 -0
  24. data/app/assets/javascripts/blocks/sound.js.coffee.erb +75 -0
  25. data/{public/favicon.ico → app/assets/javascripts/collections/.keep} +0 -0
  26. data/app/assets/javascripts/collections/character_set.js.coffee +12 -0
  27. data/app/assets/javascripts/generators/ruby.js.coffee.erb +188 -0
  28. data/app/assets/javascripts/models/.keep +0 -0
  29. data/app/assets/javascripts/models/character.js.coffee +66 -0
  30. data/app/assets/javascripts/models/scene.js.coffee +5 -0
  31. data/app/assets/javascripts/models/source_code.js.coffee +64 -0
  32. data/app/assets/javascripts/routers/.keep +0 -0
  33. data/app/assets/javascripts/ruby_mode.js.coffee.erb +12 -0
  34. data/app/assets/javascripts/smalruby.js.coffee +97 -0
  35. data/app/assets/javascripts/views/.keep +0 -0
  36. data/app/assets/javascripts/views/character_modal_view.js.coffee +148 -0
  37. data/app/assets/javascripts/views/character_selector_view.js.coffee +109 -0
  38. data/app/assets/javascripts/views/main_menu_view.js.coffee +264 -0
  39. data/app/assets/stylesheets/editor.css.scss +318 -2
  40. data/app/assets/stylesheets/toolbox.css.scss.erb +62 -0
  41. data/app/assets/templates/.keep +0 -0
  42. data/app/controllers/application_controller.rb +19 -0
  43. data/app/controllers/editor_controller.rb +4 -0
  44. data/app/controllers/source_codes_controller.rb +8 -2
  45. data/app/helpers/application_helper.rb +1 -0
  46. data/app/helpers/editor_helper.rb +46 -0
  47. data/app/models/source_code.rb +49 -6
  48. data/app/views/editor/_block_tab.html.haml +53 -0
  49. data/app/views/editor/_character_modal.html.haml +53 -0
  50. data/app/views/editor/_toolbox.html.haml +384 -0
  51. data/app/views/editor/demo.html.erb +16 -0
  52. data/app/views/editor/index.html.haml +60 -0
  53. data/app/views/layouts/application.html.erb +7 -0
  54. data/config/application.rb +1 -0
  55. data/config/initializers/teaspoon.rb +79 -0
  56. data/config/routes.rb +4 -0
  57. data/lib/smalruby_editor/version.rb +1 -1
  58. data/lib/tasks/gem.rake +7 -4
  59. data/lib/tasks/release.rake +43 -0
  60. data/public/apple-touch-icon.png +0 -0
  61. data/public/blockly/media/1x1.gif +0 -0
  62. data/public/blockly/media/click.mp3 +0 -0
  63. data/public/blockly/media/click.ogg +0 -0
  64. data/public/blockly/media/click.wav +0 -0
  65. data/public/blockly/media/delete.mp3 +0 -0
  66. data/public/blockly/media/delete.ogg +0 -0
  67. data/public/blockly/media/delete.wav +0 -0
  68. data/public/blockly/media/handclosed.cur +0 -0
  69. data/public/blockly/media/handopen.cur +0 -0
  70. data/public/blockly/media/quote0.png +0 -0
  71. data/public/blockly/media/quote1.png +0 -0
  72. data/public/blockly/media/trashbody.png +0 -0
  73. data/public/blockly/media/trashlid.png +0 -0
  74. data/public/blockly/media/tree.png +0 -0
  75. data/public/browserconfig.xml +1 -0
  76. data/public/large.png +0 -0
  77. data/public/smalruby/assets/ball1.png +0 -0
  78. data/public/smalruby/assets/ball2.png +0 -0
  79. data/public/smalruby/assets/ball3.png +0 -0
  80. data/public/smalruby/assets/ball4.png +0 -0
  81. data/public/smalruby/assets/ball5.png +0 -0
  82. data/public/smalruby/assets/ball6.png +0 -0
  83. data/public/smalruby/assets/car1.png +0 -0
  84. data/public/smalruby/assets/car2.png +0 -0
  85. data/public/smalruby/assets/car3.png +0 -0
  86. data/public/smalruby/assets/car4.png +0 -0
  87. data/public/smalruby/assets/cat1.png +0 -0
  88. data/public/smalruby/assets/cat2.png +0 -0
  89. data/public/smalruby/assets/cat3.png +0 -0
  90. data/public/smalruby/assets/frog1.png +0 -0
  91. data/public/smalruby/assets/piano_do.wav +0 -0
  92. data/public/smalruby/assets/piano_do_2.wav +0 -0
  93. data/public/smalruby/assets/piano_fa.wav +0 -0
  94. data/public/smalruby/assets/piano_mi.wav +0 -0
  95. data/public/smalruby/assets/piano_ra.wav +0 -0
  96. data/public/smalruby/assets/piano_re.wav +0 -0
  97. data/public/smalruby/assets/piano_si.wav +0 -0
  98. data/public/smalruby/assets/piano_so.wav +0 -0
  99. data/public/square.png +0 -0
  100. data/public/tiny.png +0 -0
  101. data/public/wide.png +0 -0
  102. data/smalruby-editor.gemspec +4 -0
  103. data/spec/acceptance/block_mode/blocks/character/new.feature +136 -0
  104. data/spec/acceptance/block_mode/blocks/control/await.feature +20 -0
  105. data/spec/acceptance/block_mode/blocks/control/await_until.feature +39 -0
  106. data/spec/acceptance/block_mode/blocks/control/break.feature +20 -0
  107. data/spec/acceptance/block_mode/blocks/control/if.feature +68 -0
  108. data/spec/acceptance/block_mode/blocks/control/if_else.feature +78 -0
  109. data/spec/acceptance/block_mode/blocks/control/loop.feature +45 -0
  110. data/spec/acceptance/block_mode/blocks/control/next.feature +20 -0
  111. data/spec/acceptance/block_mode/blocks/control/redo.feature +20 -0
  112. data/spec/acceptance/block_mode/blocks/control/sleep.feature +41 -0
  113. data/spec/acceptance/block_mode/blocks/control/times.feature +72 -0
  114. data/spec/acceptance/block_mode/blocks/control/until.feature +68 -0
  115. data/spec/acceptance/block_mode/blocks/events/on_click.feature +75 -0
  116. data/spec/acceptance/block_mode/blocks/events/on_hit.feature +83 -0
  117. data/spec/acceptance/block_mode/blocks/events/on_key_push_or_down.feature +171 -0
  118. data/spec/acceptance/block_mode/blocks/events/on_start.feature +75 -0
  119. data/spec/acceptance/block_mode/blocks/hardware/init_hardware.feature +44 -0
  120. data/spec/acceptance/block_mode/blocks/hardware/led_off.feature +75 -0
  121. data/spec/acceptance/block_mode/blocks/hardware/led_on.feature +75 -0
  122. data/spec/acceptance/block_mode/blocks/hardware/on_sensor_change.feature +81 -0
  123. data/spec/acceptance/block_mode/blocks/hardware/rgb_led_off.feature +81 -0
  124. data/spec/acceptance/block_mode/blocks/hardware/rgb_led_on.feature +87 -0
  125. data/spec/acceptance/block_mode/blocks/hardware/sensor_value.feature +100 -0
  126. data/spec/acceptance/block_mode/blocks/looks/hide.feature +69 -0
  127. data/spec/acceptance/block_mode/blocks/looks/say.feature +106 -0
  128. data/spec/acceptance/block_mode/blocks/looks/show.feature +69 -0
  129. data/spec/acceptance/block_mode/blocks/looks/vanish.feature +69 -0
  130. data/spec/acceptance/block_mode/blocks/motion/change_x_by.feature +81 -0
  131. data/spec/acceptance/block_mode/blocks/motion/change_y_by.feature +81 -0
  132. data/spec/acceptance/block_mode/blocks/motion/move.feature +81 -0
  133. data/spec/acceptance/block_mode/blocks/motion/reach_wall.feature +98 -0
  134. data/spec/acceptance/block_mode/blocks/motion/rotate_left.feature +81 -0
  135. data/spec/acceptance/block_mode/blocks/motion/rotate_right.feature +81 -0
  136. data/spec/acceptance/block_mode/blocks/motion/self_angle.feature +92 -0
  137. data/spec/acceptance/block_mode/blocks/motion/self_x.feature +92 -0
  138. data/spec/acceptance/block_mode/blocks/motion/self_y.feature +92 -0
  139. data/spec/acceptance/block_mode/blocks/motion/set_angle.feature +81 -0
  140. data/spec/acceptance/block_mode/blocks/motion/set_x.feature +81 -0
  141. data/spec/acceptance/block_mode/blocks/motion/set_x_y.feature +95 -0
  142. data/spec/acceptance/block_mode/blocks/motion/set_y.feature +81 -0
  143. data/spec/acceptance/block_mode/blocks/motion/turn.feature +69 -0
  144. data/spec/acceptance/block_mode/blocks/motion/turn_if_reach_wall.feature +69 -0
  145. data/spec/acceptance/block_mode/blocks/sensing/character_property.feature +114 -0
  146. data/spec/acceptance/block_mode/blocks/sensing/hit.feature +110 -0
  147. data/spec/acceptance/block_mode/blocks/sensing/input_key_push_or_down.feature +91 -0
  148. data/spec/acceptance/block_mode/blocks/sensing/input_mouse_pos_x.feature +39 -0
  149. data/spec/acceptance/block_mode/blocks/sensing/input_mouse_pos_y.feature +39 -0
  150. data/spec/acceptance/block_mode/blocks/sensing/input_mouse_push_or_down.feature +91 -0
  151. data/spec/acceptance/block_mode/blocks/sensing/time_now.feature +43 -0
  152. data/spec/acceptance/block_mode/blocks/sound/play.feature +81 -0
  153. data/spec/acceptance/block_mode/demo.feature +49 -0
  154. data/spec/acceptance/{text_editor → ruby_mode}/base.feature +11 -2
  155. data/spec/acceptance/{standalone → ruby_mode}/check.feature +8 -9
  156. data/spec/acceptance/ruby_mode/download.feature +33 -0
  157. data/spec/acceptance/{text_editor → ruby_mode}/load.feature +13 -13
  158. data/spec/acceptance/standalone/run.feature +17 -0
  159. data/spec/acceptance/standalone/save.feature +6 -6
  160. data/spec/helpers/editor_helper_spec.rb +110 -10
  161. data/spec/javascripts/collections/character_set_spec.coffee +41 -0
  162. data/spec/javascripts/models/character_spec.coffee +146 -0
  163. data/spec/javascripts/models/scene_spec.coffee +15 -0
  164. data/spec/javascripts/spec_helper.js +29 -0
  165. data/spec/spec_helper.rb +3 -8
  166. data/spec/steps/block_mode_steps.rb +37 -0
  167. data/spec/steps/global_variable.rb +30 -6
  168. data/spec/steps/text_editor_steps.rb +20 -2
  169. data/spec/teaspoon_env.rb +46 -0
  170. data/vendor/assets/javascripts/blockly/blockly_compressed.js +992 -0
  171. data/vendor/assets/javascripts/blockly/blocks_compressed.js +129 -0
  172. data/vendor/assets/javascripts/blockly/msg/js/ja.js +377 -0
  173. data/vendor/assets/javascripts/jquery.blockUI.js +619 -0
  174. metadata +290 -23
  175. data/app/assets/javascripts/editor.js.coffee.erb +0 -137
  176. data/app/views/editor/index.html.erb +0 -22
  177. data/spec/acceptance/text_editor/check.feature +0 -29
  178. data/spec/acceptance/text_editor/save.feature +0 -34
  179. data/spec/support/assets.rb +0 -18
File without changes
@@ -0,0 +1,148 @@
1
+ # キャラクター設定ダイアログを表現するビュー
2
+ Smalruby.CharacterModalView = Backbone.View.extend
3
+ model: new Smalruby.Character()
4
+
5
+ events:
6
+ 'click #character-modal-costume-selector a': 'onSelectCostume'
7
+ 'click #character-modal-ok-button': 'onOk'
8
+
9
+ previewZoomLevel: 0.5
10
+
11
+ initialize: ->
12
+ @target = null
13
+
14
+ $('#character-modal-costume-selector img').on 'dragstart', (e) ->
15
+ e.preventDefault()
16
+
17
+ setPosition = (pos) =>
18
+ @model.set
19
+ x: parseInt(pos.left / @previewZoomLevel)
20
+ y: parseInt(pos.top / @previewZoomLevel)
21
+
22
+ $('#character-modal-character').draggable
23
+ containment: '#character-modal-preview'
24
+ cursor: 'move'
25
+ drag: (event, ui) ->
26
+ setPosition(ui.position)
27
+
28
+ $('#character-modal-preview').droppable
29
+ drop: (event, ui) ->
30
+ setPosition(ui.draggable.position())
31
+
32
+ @$el.find('input[name="character[name]"]').keypress (e) ->
33
+ e = window.event if !e
34
+ if e.keyCode == 13
35
+ false
36
+ else
37
+ true
38
+
39
+ self = @
40
+ @$el.find('input[name="character[name]"]').change (e) ->
41
+ self.model.set({ name: $(@).val() })
42
+ self.nameChanged = true
43
+
44
+ @$el.find('input[name="character[x]"]').change (e) ->
45
+ self.model.set({ x: $(@).val() })
46
+
47
+ @$el.find('input[name="character[y]"]').change (e) ->
48
+ self.model.set({ y: $(@).val() })
49
+
50
+ @$el.find('input[name="character[angle]"]').change (e) ->
51
+ self.model.set({ angle: $(@).val() })
52
+
53
+ @listenTo(@model, 'change:name', @onChangeName)
54
+ @listenTo(@model, 'change:x', @onChangeX)
55
+ @listenTo(@model, 'change:y', @onChangeY)
56
+ @listenTo(@model, 'change:angle', @onChangeAngle)
57
+ @listenTo(@model, 'change:costumes', @onChangeCostumes)
58
+
59
+ @onChange(@model)
60
+
61
+ render: ->
62
+ @$el.modal('show')
63
+ # HACK: ダイアログを表示して500ms程度待たないと画像のサイズが取得できなかった
64
+ f = ->
65
+ if @readImageSizeflag
66
+ img = $('#character-modal-costume-selector .active img')
67
+ if img.width() > 0
68
+ $('#character-modal-character').css
69
+ width: "#{img.width() / 2}px"
70
+ height: "#{img.height() / 2}px"
71
+ @readImageSizeflag = false
72
+ else
73
+ setTimeout(_.bind(f, @), 50)
74
+ if @readImageSizeflag
75
+ setTimeout(_.bind(f, @), 1)
76
+
77
+ onChange: (model, options)->
78
+ @onChangeName(@model, @model.get('name'))
79
+ @onChangeX(@model, @model.get('x'))
80
+ @onChangeY(@model, @model.get('y'))
81
+ @onChangeAngle(@model, @model.get('angle'))
82
+ @onChangeCostumes(@model, @model.get('costumes'))
83
+
84
+ onChangeName: (model, value, options) ->
85
+ @$el.find('input[name="character[name]"]').val(value)
86
+
87
+ onChangeX: (model, value, options) ->
88
+ @$el.find('input[name="character[x]"]').val(value)
89
+ $('#character_x_value').text(value)
90
+ $('#character-modal-character').css('left', parseInt(value * @previewZoomLevel))
91
+
92
+ onChangeY: (model, value, options) ->
93
+ @$el.find('input[name="character[y]"]').val(value)
94
+ $('#character_y_value').text(value)
95
+ $('#character-modal-character').css('top', parseInt(value * @previewZoomLevel))
96
+
97
+ onChangeAngle: (model, value, options) ->
98
+ @$el.find('input[name="character[angle]"]').val(value)
99
+ $('#character_angle_value').text("#{value}°")
100
+ rotate = "rotate(#{-value}deg)"
101
+ $('#character-modal-character').css
102
+ '-moz-transform': rotate
103
+ '-webkit-transform': rotate
104
+ transform: rotate
105
+
106
+ onChangeCostumes: (model, value, options) ->
107
+ img = $('<img>').attr
108
+ src: model.costumeUrl()
109
+ alt: model.costume()
110
+ $('#character-modal-character img').replaceWith(img)
111
+ @$el.find('#character-modal-costume-selector a.thumbnail').removeClass('active')
112
+ thumb = @$el.find("#character-modal-costume-selector img[alt=\"#{model.costume()}\"]")
113
+ thumb.parent().addClass('active')
114
+ if thumb.width() > 0
115
+ $('#character-modal-character').css
116
+ width: "#{thumb.width() / 2}px"
117
+ height: "#{thumb.height() / 2}px"
118
+ else
119
+ @readImageSizeflag = true
120
+
121
+ onSelectCostume: (e) ->
122
+ e.preventDefault()
123
+
124
+ costume = $(e.target).attr('alt') || $(e.target).find('img').attr('alt')
125
+
126
+ attrs =
127
+ costumes: [costume]
128
+
129
+ unless @nameChanged
130
+ prefix = Smalruby.Character.costumeToNamePrefix(costume)
131
+ if prefix != @model.namePrefix()
132
+ if prefix == @target.namePrefix()
133
+ attrs['name'] = @target.get('name')
134
+ else
135
+ attrs['name'] = Smalruby.Collections.CharacterSet.uniqueName(costume)
136
+
137
+ @model.set(attrs)
138
+
139
+ onOk: ->
140
+ @$el.modal('hide')
141
+ if @target
142
+ @target.set(_.clone(@model.attributes))
143
+
144
+ setCharacter: (character)->
145
+ @target = character
146
+ @model.set(_.clone(@target.attributes))
147
+ @nameChanged = false
148
+ @
@@ -0,0 +1,109 @@
1
+ # キャラクター選択を表現するビュー
2
+ Smalruby.CharacterSelectorView = Backbone.View.extend({
3
+ el: '#character-selector-tab'
4
+
5
+ initialize: ->
6
+ @klass = Smalruby.CharacterSelectorView
7
+
8
+ @listenTo(@model, name, @render) for name in ['add', 'remove', 'reset', 'change']
9
+
10
+ @templateText = $('#character-selector-template').text()
11
+
12
+ $('#add-character-button').click (e) ->
13
+ e.preventDefault()
14
+
15
+ charSet = Smalruby.Collections.CharacterSet
16
+ attrs =
17
+ if (last = _.last(charSet.models))
18
+ name: charSet.uniqueName(last.costume())
19
+ costumes: _.clone(last.get('costumes'))
20
+ else
21
+ name: charSet.uniqueName()
22
+ c = new Smalruby.Character(attrs)
23
+ charSet.add(c)
24
+
25
+ Smalruby.Views.CharacterModalView.setCharacter(c).render()
26
+
27
+ @render()
28
+
29
+ render: ->
30
+ charsEl = $('#character-selector-character-set')
31
+ charsEl.children().remove()
32
+
33
+ @model.each (character) =>
34
+ html = $(_.template(@templateText, character))
35
+ charsEl.append(html)
36
+
37
+ html.find('a.character').click (e) ->
38
+ e.preventDefault()
39
+ Smalruby.Views.CharacterModalView.setCharacter(character).render()
40
+
41
+ html.find('a.add-block-button').click (e) =>
42
+ e.preventDefault()
43
+ @addBlock_(character)
44
+
45
+ removeButton = html.find('a.remove-button')
46
+ removeButton.click (e) =>
47
+ e.preventDefault()
48
+ @removeCharacter_(character)
49
+ if character.get('using')
50
+ removeButton.hide()
51
+
52
+ rotate = "rotate(#{character.get('angle') * -1}deg)"
53
+ img = html.find('img')
54
+ img.css
55
+ '-moz-transform': rotate
56
+ '-webkit-transform': rotate
57
+ transform: rotate
58
+ img.on 'dragstart', (e) ->
59
+ e.preventDefault()
60
+
61
+
62
+ addBlock_: (character) ->
63
+ newBlock = new Blockly.Block(Blockly.mainWorkspace, 'character_new')
64
+ newBlock.setCharacter(character)
65
+ newBlock.initSvg()
66
+ newBlock.render()
67
+ @moveByNewBlock_(newBlock)
68
+ newBlock.select()
69
+
70
+ moveByNewBlock_: (newBlock) ->
71
+ metrics = Blockly.mainWorkspace.getMetrics()
72
+ newXY =
73
+ x: metrics.viewLeft + @klass.NEW_BLOCK_MARGIN.LEFT
74
+ y: metrics.viewTop + @klass.NEW_BLOCK_MARGIN.TOP
75
+
76
+ if @prevBlock
77
+ xy = @prevBlock.getRelativeToSurfaceXY()
78
+ hw = @prevBlock.getHeightWidth()
79
+ newHW = newBlock.getHeightWidth()
80
+ if xy.x == @prevXY.x && xy.y == @prevXY.y
81
+ x = xy.x
82
+ y = xy.y + hw.height + @klass.NEW_BLOCK_MARGIN.TOP
83
+ if y + newHW.height > metrics.viewTop + metrics.viewHeight
84
+ x += hw.width + @klass.NEW_BLOCK_MARGIN.LEFT
85
+ y = newXY.y
86
+ else
87
+ x = @prevXY.x
88
+ y = @prevXY.y
89
+ if x >= metrics.viewLeft &&
90
+ x + newHW.width <= metrics.viewLeft + metrics.viewWidth &&
91
+ y >= metrics.viewTop &&
92
+ y + newHW.height <= metrics.viewTop + metrics.viewHeight
93
+ newXY.x = x
94
+ newXY.y = y
95
+
96
+ newBlock.moveBy(newXY.x, newXY.y)
97
+
98
+ @prevBlock = newBlock
99
+ @prevXY = newBlock.getRelativeToSurfaceXY()
100
+
101
+ removeCharacter_: (character) ->
102
+ unless character.get('using')
103
+ Smalruby.Collections.CharacterSet.remove(character)
104
+
105
+ }, {
106
+ NEW_BLOCK_MARGIN:
107
+ LEFT: 20
108
+ TOP: 20
109
+ })
@@ -0,0 +1,264 @@
1
+ # ナビゲーションメニューを表現するビュー
2
+ Smalruby.MainMenuView = Backbone.View.extend
3
+ el: '#main-menu'
4
+
5
+ events:
6
+ 'click #run-button': 'onRun'
7
+ 'click #download-button': 'onDownload'
8
+ 'click #load-button': 'onLoad'
9
+ 'click #save-button': 'onSave'
10
+ 'click #check-button': 'onCheck'
11
+ 'click #reset-button': 'onReset'
12
+
13
+ initialize: ->
14
+ $('#filename').keypress (e) ->
15
+ e = window.event if !e
16
+ if e.keyCode == 13
17
+ $('#save-button').click()
18
+ false
19
+ else
20
+ true
21
+
22
+ $('#file-form').fileupload
23
+ dataType: 'json'
24
+ done: (e, data) ->
25
+ info = data.result.source_code
26
+ if info.error
27
+ window.errorMessage(info.filename + 'は' + info.error)
28
+ else
29
+ $('#filename').val(info.filename)
30
+ if info.filename.match(/.xml$/)
31
+ Smalruby.loadXml(info.data)
32
+ info.data = Blockly.Ruby.workspaceToCode()
33
+ window.textEditor.getSession().getDocument().setValue(info.data)
34
+ window.textEditor.moveCursorTo(0, 0)
35
+ unless window.blockMode
36
+ window.textEditor.focus()
37
+ # TODO: window.changed -> Smalruby.Models.SourceCode.changed
38
+ window.changed = false
39
+ window.successMessage('ロードしました')
40
+
41
+ onRun: (e) ->
42
+ e.preventDefault()
43
+
44
+ sourceCode = @getSourceCode()
45
+
46
+ @blockUI
47
+ title:
48
+ """
49
+ <i class="icon-play"></i>
50
+ プログラムの実行中
51
+ """
52
+ message: 'プログラムの画面に切り替えてください。'
53
+ notice:
54
+ """
55
+ プログラムをセーブ・チェックしてから実行するよ♪<br>
56
+ Escキーを押すとプログラムが終わります。
57
+ """
58
+
59
+ failedFunc = ->
60
+ $.unblockUI()
61
+ errorMessage('プログラムを実行できませんでした')
62
+
63
+ sourceCode.save2()
64
+ .done (data) ->
65
+ sourceCode.write()
66
+ .done (data) ->
67
+ afterSave = ->
68
+ Smalruby.savedFilename = sourceCode.get('filename')
69
+ window.changed = false
70
+ sourceCode.check()
71
+ .done (data) ->
72
+ if data.length > 0
73
+ failedFunc()
74
+ for errorInfo in data
75
+ do (errorInfo) ->
76
+ msg = "#{errorInfo.row}行"
77
+ if errorInfo.column > 0
78
+ msg += "、#{errorInfo.column}文字"
79
+ window.errorMessage(msg + ": #{errorInfo.message}")
80
+ else
81
+ sourceCode.run()
82
+ .done (data) ->
83
+ $.unblockUI()
84
+ if data.length > 0
85
+ for errorInfo in data
86
+ do (errorInfo) ->
87
+ msg = "#{errorInfo.row}行"
88
+ if errorInfo.column > 0
89
+ msg += "、#{errorInfo.column}文字"
90
+ errorMessage(msg + ": #{errorInfo.message}")
91
+
92
+ .fail -> failedFunc()
93
+
94
+ .fail -> failedFunc()
95
+
96
+ if data.source_code.error
97
+ if sourceCode.get('filename') == Smalruby.savedFilename ||
98
+ confirm("前に#{sourceCode.get('filename')}という名前でセーブしているけど本当にセーブしますか?\nセーブすると前に作成したプログラムは消えてしまうよ!")
99
+ sourceCode.write(true)
100
+ .done (data) ->
101
+ afterSave()
102
+ else
103
+ failedFunc()
104
+ else
105
+ afterSave()
106
+ .fail -> failedFunc()
107
+ .fail -> failedFunc()
108
+
109
+ onDownload: (e) ->
110
+ e.preventDefault()
111
+
112
+ sourceCode = @getSourceCode()
113
+
114
+ @blockUI
115
+ title:
116
+ """
117
+ プログラムのダウンロード中
118
+ """
119
+ message: 'プログラムをダウンロードしています。'
120
+ notice:
121
+ """
122
+ ダウンロードしたプログラムは、<br>
123
+ Windowsだと「ruby #{sourceCode.get('filename')}」、<br>
124
+ Macだと「rsdl #{sourceCode.get('filename')}」で実行できます。
125
+ """
126
+
127
+ sourceCode.save2()
128
+ .done (data) ->
129
+ $.unblockUI()
130
+ window.changed = false
131
+ window.successMessage('ダウンロードしました')
132
+ Smalruby.downloading = true
133
+ $('#download-link').click()
134
+ .fail ->
135
+ $.unblockUI()
136
+ window.errorMessage('ダウンロードできませんでした')
137
+
138
+ onLoad: (e) ->
139
+ e.preventDefault()
140
+
141
+ # TODO: window.changed -> Smalruby.Models.SourceCode.changed
142
+ if window.changed
143
+ return unless confirm('まだセーブしていないのでロードするとプログラムが消えてしまうよ!\nそれでもロードしますか?')
144
+ $('input#load-file[name="source_code[file]"]').click()
145
+
146
+ onSave: (e) ->
147
+ e.preventDefault()
148
+
149
+ filename = $.trim($('#filename').val())
150
+ if filename.length <= 0
151
+ window.errorMessage('セーブする前にプログラムに名前をつけてね!')
152
+ $('#filename').focus()
153
+ return
154
+
155
+ sourceCode = @getSourceCode()
156
+
157
+ @blockUI
158
+ title:
159
+ """
160
+ プログラムのセーブ中
161
+ """
162
+ message: 'プログラムをセーブしています。'
163
+ notice:
164
+ """
165
+ プログラムの名前は「#{sourceCode.get('filename')}」です。<br>
166
+ プログラムはホームディレクトリにセーブします。<br>
167
+ """
168
+
169
+ failedFunc = ->
170
+ $.unblockUI()
171
+ window.errorMessage('セーブできませんでした')
172
+
173
+ sourceCode.save2()
174
+ .done (data) ->
175
+ sourceCode.write()
176
+ .done (data) ->
177
+ afterSave = ->
178
+ $.unblockUI()
179
+ Smalruby.savedFilename = sourceCode.get('filename')
180
+ window.changed = false
181
+ window.successMessage('セーブしました')
182
+
183
+ if data.source_code.error
184
+ if sourceCode.get('filename') == Smalruby.savedFilename ||
185
+ confirm("前に#{sourceCode.get('filename')}という名前でセーブしているけど本当にセーブしますか?\nセーブすると前に作成したプログラムは消えてしまうよ!")
186
+ sourceCode.write(true)
187
+ .done (data) ->
188
+ afterSave()
189
+ else
190
+ $.unblockUI()
191
+ window.successMessage('セーブをキャンセルしました')
192
+ else
193
+ afterSave()
194
+ .fail -> failedFunc()
195
+ .fail -> failedFunc()
196
+
197
+ onCheck: (e) ->
198
+ e.preventDefault()
199
+
200
+ # TODO: 既存のシンタックスに関するエラーメッセージをcloseしておく
201
+
202
+ sourceCode = @getSourceCode()
203
+
204
+ @blockUI
205
+ title:
206
+ """
207
+ プログラムのチェック中
208
+ """
209
+ message: 'プログラムの文法をチェックしています。'
210
+ notice:
211
+ """
212
+ このチェックは簡易的なものですので、<br>
213
+ プログラムを動かすとエラーが見つかるかもしれません。
214
+ """
215
+
216
+ sourceCode.check()
217
+ .done (data) ->
218
+ $.unblockUI()
219
+ if data.length == 0
220
+ window.successMessage('チェックしました', 'ただし、プログラムを動かすとエラーが見つかるかもしれません。')
221
+ else
222
+ for errorInfo in data
223
+ do (errorInfo) ->
224
+ msg = "#{errorInfo.row}行"
225
+ if errorInfo.column > 0
226
+ msg += "、#{errorInfo.column}文字"
227
+ window.errorMessage(msg + ": #{errorInfo.message}")
228
+ .fail ->
229
+ $.unblockUI()
230
+ errorMessage('チェックできませんでした')
231
+
232
+ onReset: (e) ->
233
+ e.preventDefault()
234
+
235
+ location.reload()
236
+
237
+ getFilename: ->
238
+ $.trim($('#filename').val())
239
+
240
+ getSourceCode: ->
241
+ sourceCode = new Smalruby.SourceCode()
242
+ $('#filename').val(sourceCode.get('filename'))
243
+ sourceCode
244
+
245
+ blockUI: (options) ->
246
+ $.blockUI
247
+ message:
248
+ """
249
+ <h3>
250
+ #{options.title}
251
+ </h3>
252
+ <blockquote>
253
+ <p>
254
+ #{options.message}
255
+ </p>
256
+ <small>
257
+ #{options.notice}
258
+ </small>
259
+ </blockquote>
260
+ """
261
+ css:
262
+ border: 'none'
263
+ 'text-align': 'left'
264
+ 'padding-left': '2em'