flexlay.rb 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. class TilemapLayer
  2. alias orig_get_metadata get_metadata
  3. alias orig_set_metadata set_metadata
  4. def set_metadata(data)
  5. orig_set_metadata(make_metadata(data))
  6. end
  7. def get_metadata()
  8. return get_ruby_object(orig_get_metadata())
  9. end
  10. def each(x, y, width, height)
  11. data = get_data()
  12. (y..height-1).each{
  13. (x..width-1).each{
  14. yield(data[y*get_width() + x])
  15. }
  16. }
  17. end
  18. end
  19. class EditorMap
  20. alias orig_get_metadata get_metadata
  21. alias orig_set_metadata set_metadata
  22. def set_data(data)
  23. orig_set_metadata(make_metadata(data))
  24. end
  25. def get_data()
  26. return get_ruby_object(orig_get_metadata())
  27. end
  28. def set_metadata(data)
  29. orig_set_metadata(make_metadata(data))
  30. end
  31. def get_metadata()
  32. return get_ruby_object(orig_get_metadata())
  33. end
  34. end
  35. class ObjMapObject
  36. def get_data()
  37. return get_ruby_object(get_metadata())
  38. end
  39. def set_data(data)
  40. set_metadata(make_metadata(data))
  41. end
  42. end
  43. class Icon
  44. def set_callback(func)
  45. connect(sig_clicked(), func)
  46. end
  47. end
  48. class Menu
  49. alias_method :orig_add_item, :add_item
  50. def add_item(*params)
  51. if params.length == 2 then
  52. (text, func) = params
  53. i = orig_add_item(text)
  54. else
  55. (sprite, text, func) = params
  56. i = orig_add_item(sprite, text)
  57. end
  58. if func != nil
  59. connect(sig_clicked(i), func)
  60. end
  61. end
  62. end
  63. class CL_Menu
  64. def add_item(name, func)
  65. item = create_item(name)
  66. connect(item.sig_clicked(), func)
  67. end
  68. def CL_Menu.new_from_spec(menubarspec, parent)
  69. menu = CL_Menu.new(parent)
  70. menubarspec.each { |(title, *menu_spec)|
  71. menu_spec.each{ |(name, callback)|
  72. menu.add_item("#{title}/#{name}", callback)
  73. }
  74. }
  75. return menu
  76. end
  77. end
  78. class ButtonPanel
  79. attr_reader :panel, :items
  80. def initialize(x, y, width, height, horizontal, parent, &block)
  81. @panel = Panel.new(CL_Rect.new(CL_Point.new(x, y), CL_Size.new(width, height)), parent)
  82. @pos = 2
  83. @horizontal = horizontal
  84. @items = {}
  85. if block then
  86. instance_eval(&block)
  87. end
  88. end
  89. def set_position(x, y)
  90. @panel.set_position(x, y)
  91. end
  92. def set_size(w, h)
  93. @panel.set_size(w, h)
  94. end
  95. def ButtonPanel.new_from_spec(x, y, width, height, horizontal, spec, parent)
  96. buttonpanel = ButtonPanel.new(x, y, width, height, horizontal, parent)
  97. spec.each{ |(type, *data)|
  98. case type
  99. when :icon
  100. buttonpanel.items[data[0]] = buttonpanel.add_icon(data[1], data[2])
  101. when :toggle
  102. buttonpanel.items[data[0]] = buttonpanel.add_icon(data[1], data[2])
  103. when :small_icon
  104. buttonpanel.items[data[0]] = buttonpanel.add_small_icon(data[1], data[2])
  105. when :seperator
  106. buttonpanel.add_separator()
  107. else
  108. raise "ButtonPanel: Unknown type #{type}"
  109. end
  110. }
  111. return buttonpanel
  112. end
  113. def add_small_icon(image = nil, callback = nil, tooltip = "")
  114. if (@horizontal)
  115. icon = Icon.new(CL_Rect.new(CL_Point.new(@pos, 2), CL_Size.new(16, 32)),
  116. make_sprite(image), tooltip, @panel);
  117. else
  118. icon = Icon.new(CL_Rect.new(CL_Point.new(2, @pos), CL_Size.new(16, 32)),
  119. make_sprite(image), tooltip, @panel);
  120. end
  121. @pos += 16
  122. if (callback)
  123. icon.set_callback(callback)
  124. end
  125. return icon
  126. end
  127. def add_icon(image = nil, callback = nil, &block)
  128. tooltip = ""
  129. if block then
  130. callback = block
  131. end
  132. if (@horizontal)
  133. icon = Icon.new(CL_Rect.new(CL_Point.new(@pos, 2), CL_Size.new(32, 32)),
  134. make_sprite(image), tooltip, @panel);
  135. else
  136. icon = Icon.new(CL_Rect.new(CL_Point.new(2, @pos), CL_Size.new(32, 32)),
  137. make_sprite(image), tooltip, @panel);
  138. end
  139. @pos += 32
  140. if (callback)
  141. icon.set_callback(callback)
  142. end
  143. return icon
  144. end
  145. def add_separator()
  146. @pos += 16
  147. end
  148. def show(b)
  149. @panel.show(b)
  150. end
  151. end
  152. # Very simple FileDialog, mainly a placeholder until the real thing gets ready.
  153. class SimpleFileDialog
  154. @window = nil
  155. @inputbox = nil
  156. @ok_button = nil
  157. @cancel_button = nil
  158. @callback = nil
  159. def initialize(title, ok, cancel, g)
  160. @window = Window.new(CL_Rect.new(CL_Point.new(120, 200), CL_Size.new(560, 100)), title, g)
  161. @inputbox = CL_InputBox.new(CL_Rect.new(CL_Point.new(10, 10), CL_Size.new(530, 25)),
  162. @window.get_client_area())
  163. @ok_button = CL_Button.new(CL_Rect.new(CL_Point.new(490, 35), CL_Size.new(50, 25)), ok,
  164. @window.get_client_area())
  165. @cancel_button = CL_Button.new(CL_Rect.new(CL_Point.new(430, 35), CL_Size.new(50, 25)), cancel,
  166. @window.get_client_area())
  167. @window.hide()
  168. end
  169. def set_filename(filename)
  170. @inputbox.set_text(filename)
  171. end
  172. def get_filename()
  173. return @inputbox.get_text()
  174. end
  175. def run(func)
  176. connect(@ok_button.sig_clicked(), method(:on_ok))
  177. connect(@inputbox.sig_return_pressed(), method(:on_ok))
  178. connect(@cancel_button.sig_clicked(), method(:on_cancel))
  179. @callback = func
  180. @inputbox.set_focus()
  181. @window.show()
  182. end
  183. def on_ok()
  184. @window.hide();
  185. if @callback
  186. @callback.call(@inputbox.get_text())
  187. end
  188. end
  189. def on_cancel()
  190. @window.hide();
  191. end
  192. end
  193. class GenericDialog
  194. window = nil
  195. items = nil
  196. ok = nil
  197. cancel = nil
  198. callback = nil
  199. def initialize(title, gui)
  200. @items = []
  201. @window = Window.new(CL_Rect.new(CL_Point.new(100, 100), CL_Size.new(400, 100)), title, gui)
  202. @ok = CL_Button.new(CL_Rect.new(CL_Point.new(290, 35), CL_Size.new(50, 25)), "Ok",
  203. @window.get_client_area())
  204. @cancel = CL_Button.new(CL_Rect.new(CL_Point.new(230, 35), CL_Size.new(50, 25)), "Cancel",
  205. @window.get_client_area())
  206. connect(@cancel.sig_clicked(), method(:on_cancel))
  207. connect(@ok.sig_clicked(), method(:on_ok))
  208. end
  209. def on_cancel()
  210. @window.hide()
  211. end
  212. def on_ok()
  213. @window.hide()
  214. if @callback
  215. vals = []
  216. @items.each{|item|
  217. (type, label, comp) = item
  218. if type == "int"
  219. vals.push(comp.get_text().to_i)
  220. elsif type == "float"
  221. vals.push(comp.get_text().to_f)
  222. elsif type == "string"
  223. vals.push(comp.get_text())
  224. elsif type == "bool"
  225. vals.push(comp.is_checked())
  226. elsif type == "enum"
  227. comp.get_buttons().each{|button|
  228. if (button.is_checked()) then
  229. vals.push(button.get_text())
  230. break;
  231. end
  232. }
  233. end
  234. }
  235. @callback.call(*vals)
  236. end
  237. end
  238. def set_block()
  239. @callback = proc{ |*args| yield(*args) }
  240. end
  241. def set_callback(c)
  242. @callback = c
  243. end
  244. def add_label(text)
  245. @items.push(["void",
  246. CL_Label.new(CL_Point.new(10, 10), text, @window.get_client_area()),
  247. nil])
  248. update()
  249. end
  250. def add_float(name, value = 0)
  251. @items.push(["float",
  252. CL_Label.new(CL_Point.new(10, 10), name,
  253. @window.get_client_area()),
  254. CL_InputBox.new(CL_Rect.new(CL_Point.new(110, 10), CL_Size.new(200, 25)),
  255. @window.get_client_area())])
  256. @items[-1][2].set_text(value.to_s)
  257. update()
  258. end
  259. def add_bool(name, value = false)
  260. @items.push(["bool",
  261. CL_Label.new(CL_Point.new(10, 10), name,
  262. @window.get_client_area()),
  263. CL_CheckBox.new(CL_Point.new(110, 10),
  264. "",
  265. @window.get_client_area())])
  266. if value == true
  267. @items[-1][2].set_checked()
  268. end
  269. update()
  270. end
  271. def add_enum(name, types, value = "foo")
  272. group = CL_RadioGroup.new()
  273. types.each {|type|
  274. radio = CL_RadioButton.new(CL_Point.new(0, 0),
  275. type, @window.get_client_area())
  276. radio.set_checked(type == value)
  277. group.add(radio)
  278. }
  279. @items.push(["enum",
  280. CL_Label.new(CL_Point.new(10, 10), name,
  281. @window.get_client_area()),
  282. group])
  283. update()
  284. end
  285. def add_int(name, value = 0)
  286. @items.push(["int",
  287. CL_Label.new(CL_Point.new(10, 10), name,
  288. @window.get_client_area()),
  289. CL_InputBox.new(CL_Rect.new(CL_Point.new(110, 10), CL_Size.new(200, 25)),
  290. @window.get_client_area())])
  291. @items[-1][2].set_text(value.to_s)
  292. update()
  293. end
  294. def add_string(name, value = "")
  295. @items.push(["string",
  296. CL_Label.new(CL_Point.new(10, 10), name,
  297. @window.get_client_area()),
  298. CL_InputBox.new(CL_Rect.new(CL_Point.new(110, 10), CL_Size.new(200, 25)),
  299. @window.get_client_area())])
  300. @items[-1][2].set_text(value)
  301. update()
  302. end
  303. def update()
  304. y = 10
  305. @items.each { |(type, label, comp)|
  306. label.set_position(10, y)
  307. if type == "int" or type == "string" or type == "float" or type == "void" or type == "bool" then
  308. if comp then
  309. comp.set_position(110, y)
  310. end
  311. y += 25
  312. elsif type == "enum"
  313. y += 5
  314. comp.get_buttons.each {|radio|
  315. radio.set_position(110, y)
  316. y += 20
  317. }
  318. y += 5
  319. end
  320. }
  321. @cancel.set_position(200, y)
  322. @ok.set_position(260, y)
  323. @window.set_size(330, y + 60)
  324. end
  325. end
  326. # EOF #