glimmer-dsl-libui 0.2.13 → 0.2.17

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,124 @@
1
+ # Copyright (c) 2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer-dsl-libui'
23
+
24
+ require_relative 'tetris/model/game'
25
+
26
+ class Tetris
27
+ include Glimmer
28
+
29
+ BLOCK_SIZE = 25
30
+ BEVEL_CONSTANT = 20
31
+
32
+ attr_reader :game
33
+
34
+ def initialize
35
+ @game = Model::Game.new
36
+ create_gui
37
+ register_observers
38
+ end
39
+
40
+ def launch
41
+ @game.start!
42
+ @main_window.show
43
+ end
44
+
45
+ def create_gui
46
+ @main_window = window('Glimmer Tetris', Model::Game::PLAYFIELD_WIDTH * BLOCK_SIZE, Model::Game::PLAYFIELD_HEIGHT * BLOCK_SIZE) {
47
+ playfield(playfield_width: Model::Game::PLAYFIELD_WIDTH, playfield_height: Model::Game::PLAYFIELD_HEIGHT, block_size: BLOCK_SIZE)
48
+ }
49
+ end
50
+
51
+ def register_observers
52
+ Glimmer::DataBinding::Observer.proc do |game_over|
53
+ if game_over
54
+ show_game_over_dialog
55
+ else
56
+ start_moving_tetrominos_down
57
+ end
58
+ end.observe(@game, :game_over)
59
+
60
+ Model::Game::PLAYFIELD_HEIGHT.times do |row|
61
+ Model::Game::PLAYFIELD_HEIGHT.times do |column|
62
+ Glimmer::DataBinding::Observer.proc do |new_color|
63
+ @blocks[row][column].fill = new_color
64
+ end.observe(@game.playfield[row][column], :color)
65
+ end
66
+ end
67
+ end
68
+
69
+ def playfield(playfield_width: , playfield_height: , block_size: )
70
+ area {
71
+ @blocks = playfield_height.times.map do |row|
72
+ playfield_width.times.map do |column|
73
+ block(row: row, column: column, block_size: block_size)
74
+ end
75
+ end
76
+
77
+ on_key_down do |key_event|
78
+ case key_event
79
+ in ext_key: :down
80
+ game.down!
81
+ in ext_key: :up
82
+ case game.up_arrow_action
83
+ when :instant_down
84
+ game.down!(instant: true)
85
+ when :rotate_right
86
+ game.rotate!(:right)
87
+ when :rotate_left
88
+ game.rotate!(:left)
89
+ end
90
+ in ext_key: :left
91
+ game.left!
92
+ in ext_key: :right
93
+ game.right!
94
+ in modifier: :shift
95
+ game.rotate!(:right)
96
+ in modifier: :control
97
+ game.rotate!(:left)
98
+ else
99
+ # Do Nothing
100
+ end
101
+ end
102
+ }
103
+ end
104
+
105
+ def block(row: , column: , block_size: )
106
+ path {
107
+ square(column * block_size, row * block_size, block_size)
108
+
109
+ fill Model::Block::COLOR_CLEAR
110
+ }
111
+ end
112
+
113
+ def start_moving_tetrominos_down
114
+ Glimmer::LibUI.timer(@game.delay) do
115
+ @game.down! if !@game.game_over? && !@game.paused?
116
+ end
117
+ end
118
+
119
+ def show_game_over_dialog
120
+ msg_box('Game Over', "Score: #{@game.high_scores.first.score}")
121
+ end
122
+ end
123
+
124
+ Tetris.new.launch
Binary file
@@ -33,6 +33,8 @@ module Glimmer
33
33
  end
34
34
 
35
35
  def interpret(parent, keyword, *args, &block)
36
+ @@inverted_keyword_aliases = Glimmer::LibUI::ControlProxy::KEYWORD_ALIASES.invert unless defined?(@@inverted_keyword_aliases)
37
+ keyword = @@inverted_keyword_aliases[keyword] || keyword
36
38
  Glimmer::LibUI::ControlProxy.create(keyword, parent, args, &block)
37
39
  end
38
40
 
@@ -37,6 +37,7 @@ module Glimmer
37
37
  end
38
38
 
39
39
  LISTENERS = ['on_draw', 'on_mouse_event', 'on_mouse_move', 'on_mouse_down', 'on_mouse_up', 'on_mouse_drag_start', 'on_mouse_drag', 'on_mouse_drop', 'on_mouse_crossed', 'on_mouse_enter', 'on_mouse_exit', 'on_drag_broken', 'on_key_event', 'on_key_down', 'on_key_up']
40
+
40
41
  LISTENER_ALIASES = {
41
42
  on_drawn: 'on_draw',
42
43
  on_mouse_moved: 'on_mouse_move',
@@ -49,6 +50,30 @@ module Glimmer
49
50
  on_drag_break: 'on_drag_broken',
50
51
  }
51
52
 
53
+ SHIFTED_KEY_CODE_CHARS = {
54
+ '`' => '~',
55
+ '1' => '!',
56
+ '2' => '@',
57
+ '3' => '#',
58
+ '4' => '$',
59
+ '5' => '%',
60
+ '6' => '^',
61
+ '7' => '&',
62
+ '8' => '*',
63
+ '9' => '(',
64
+ '10' => ')',
65
+ '-' => '_',
66
+ '=' => '+',
67
+ ',' => '<',
68
+ '.' => '>',
69
+ '/' => '?',
70
+ ';' => ':',
71
+ "'" => '"',
72
+ '[' => '{',
73
+ ']' => '}',
74
+ "\\" => '|',
75
+ }
76
+
52
77
  include Glimmer::FiddleConsumer
53
78
  include Parent
54
79
  prepend Transformable
@@ -164,19 +189,27 @@ module Glimmer
164
189
  end
165
190
 
166
191
  def area_key_event_hash(area_key_event)
192
+ modifiers = modifiers_to_symbols(area_key_event.Modifiers)
167
193
  {
168
- key: key_to_char(area_key_event.Key),
194
+ key: key_to_char(area_key_event.Key, modifiers),
169
195
  key_value: area_key_event.Key,
170
196
  ext_key: ext_key_to_symbol(area_key_event.ExtKey),
171
197
  ext_key_value: area_key_event.ExtKey,
172
198
  modifier: modifiers_to_symbols(area_key_event.Modifier).first,
173
- modifiers: modifiers_to_symbols(area_key_event.Modifiers),
199
+ modifiers: modifiers,
174
200
  up: Glimmer::LibUI.integer_to_boolean(area_key_event.Up),
175
201
  }
176
202
  end
177
203
 
178
- def key_to_char(key)
179
- key.chr if key > 0
204
+ def key_to_char(key, modifiers = [])
205
+ if key > 0
206
+ char = key.chr
207
+ if modifiers == [:shift]
208
+ SHIFTED_KEY_CODE_CHARS[char]
209
+ else
210
+ char
211
+ end
212
+ end
180
213
  end
181
214
 
182
215
  def ext_key_to_symbol(ext_key_value)
@@ -37,7 +37,6 @@ module Glimmer
37
37
  end
38
38
 
39
39
  def widget_proxy_class(keyword)
40
- class_name = constant_symbol(keyword)
41
40
  descendant_keyword_constant_map[keyword] || ControlProxy
42
41
  end
43
42
 
@@ -72,7 +71,7 @@ module Glimmer
72
71
  end
73
72
 
74
73
  def descendant_keyword_constant_map
75
- @descendant_keyword_constant_map ||= map_descendant_keyword_constants_for(self)
74
+ @descendant_keyword_constant_map ||= add_aliases_to_keyword_constant_map(map_descendant_keyword_constants_for(self))
76
75
  end
77
76
 
78
77
  def reset_descendant_keyword_constant_map
@@ -91,8 +90,22 @@ module Glimmer
91
90
  end
92
91
  accumulator
93
92
  end
93
+
94
+ private
95
+
96
+ def add_aliases_to_keyword_constant_map(keyword_constant_map)
97
+ KEYWORD_ALIASES.each do |keyword, alias_keyword|
98
+ keyword_constant_map[alias_keyword] = keyword_constant_map[keyword]
99
+ end
100
+ keyword_constant_map
101
+ end
94
102
  end
95
103
 
104
+ KEYWORD_ALIASES = {
105
+ 'msg_box' => 'message_box',
106
+ 'msg_box_error' => 'message_box_error',
107
+ }
108
+
96
109
  BOOLEAN_PROPERTIES = %w[
97
110
  padded
98
111
  checked
@@ -223,6 +236,7 @@ module Glimmer
223
236
  elsif ::LibUI.respond_to?("#{libui_api_keyword}_set_#{method_name.to_s.sub(/=$/, '')}") && !args.empty?
224
237
  property = method_name.to_s.sub(/=$/, '')
225
238
  args[0] = Glimmer::LibUI.boolean_to_integer(args.first) if BOOLEAN_PROPERTIES.include?(property) && (args.first.is_a?(TrueClass) || args.first.is_a?(FalseClass))
239
+ args[0] = '' if STRING_PROPERTIES.include?(property) && args.first == nil
226
240
  if property.to_s == 'checked'
227
241
  current_value = Glimmer::LibUI.integer_to_boolean(::LibUI.send("#{libui_api_keyword}_checked", @libui))
228
242
  new_value = Glimmer::LibUI.integer_to_boolean(args[0])
@@ -239,6 +253,7 @@ module Glimmer
239
253
  elsif ::LibUI.respond_to?("control_set_#{method_name.to_s.sub(/=$/, '')}")
240
254
  property = method_name.to_s.sub(/=$/, '')
241
255
  args[0] = Glimmer::LibUI.boolean_to_integer(args.first) if BOOLEAN_PROPERTIES.include?(property) && (args.first.is_a?(TrueClass) || args.first.is_a?(FalseClass))
256
+ args[0] = '' if STRING_PROPERTIES.include?(property) && args.first == nil
242
257
  ::LibUI.send("control_set_#{method_name.to_s.sub(/=$/, '')}", @libui, *args)
243
258
  elsif ::LibUI.respond_to?("control_#{method_name}") && !args.empty?
244
259
  ::LibUI.send("control_#{method_name}", @libui, *args)
@@ -36,7 +36,11 @@ module Glimmer
36
36
  if parent.is_a?(Figure) && parent.x.nil? && parent.y.nil?
37
37
  ::LibUI.draw_path_new_figure_with_arc(path_proxy.libui, *arc_args)
38
38
  else
39
- ::LibUI.draw_path_arc_to(path_proxy.libui, *arc_args)
39
+ if OS.windows? && parent.children.find {|child| child.is_a?(Arc)} == self
40
+ ::LibUI.draw_path_new_figure_with_arc(path_proxy.libui, *arc_args)
41
+ else
42
+ ::LibUI.draw_path_arc_to(path_proxy.libui, *arc_args)
43
+ end
40
44
  end
41
45
  super
42
46
  end
@@ -36,7 +36,11 @@ module Glimmer
36
36
  if parent.is_a?(Figure) && parent.x.nil? && parent.y.nil?
37
37
  ::LibUI.draw_path_new_figure_with_arc(path_proxy.libui, *arc_args)
38
38
  else
39
- ::LibUI.draw_path_arc_to(path_proxy.libui, *arc_args)
39
+ if OS.windows? && parent.children.find {|child| child.is_a?(Circle)} == self
40
+ ::LibUI.draw_path_new_figure_with_arc(path_proxy.libui, *arc_args)
41
+ else
42
+ ::LibUI.draw_path_arc_to(path_proxy.libui, *arc_args)
43
+ end
40
44
  end
41
45
  super
42
46
  end
data/lib/glimmer/libui.rb CHANGED
@@ -27,11 +27,11 @@ module Glimmer
27
27
  include Glimmer::FiddleConsumer
28
28
 
29
29
  def integer_to_boolean(int, allow_nil: true)
30
- int.nil? ? (allow_nil ? nil : false) : ((int.is_a?(TrueClass) || int.is_a?(FalseClass)) ? int : int == 1)
30
+ int.nil? ? (allow_nil ? nil : false) : ((int.is_a?(TrueClass) || int.is_a?(FalseClass)) ? int : (int.is_a?(Integer) ? int == 1 : (allow_nil ? nil : false)))
31
31
  end
32
32
 
33
33
  def boolean_to_integer(bool, allow_nil: true)
34
- bool.nil? ? (allow_nil ? nil : 0) : (bool.is_a?(Integer) ? bool : (bool == true ? 1 : 0))
34
+ bool.nil? ? (allow_nil ? nil : 0) : (bool.is_a?(Integer) ? bool : (bool.is_a?(TrueClass) || bool.is_a?(FalseClass) ? (bool == true ? 1 : 0) : (allow_nil ? nil : 0)))
35
35
  end
36
36
 
37
37
  def degrees_to_radians(degrees)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-libui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.13
4
+ version: 0.2.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-18 00:00:00.000000000 Z
11
+ date: 2021-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -190,12 +190,12 @@ dependencies:
190
190
  - - "~>"
191
191
  - !ruby/object:Gem::Version
192
192
  version: 1.4.0
193
- description: Glimmer DSL for LibUI - Prerequisite-Free Ruby Desktop Development GUI
194
- Library (No need to pre-install any prerequisites. Just install the gem and have
193
+ description: Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI
194
+ Library) - No need to pre-install any prerequisites. Just install the gem and have
195
195
  platform-independent native GUI that just works! Glimmer DSL for LibUI aims to provide
196
196
  declarative DSL syntax that visually maps to GUI control hierarchy, convention over
197
197
  configuration via smart defaults, automation of low-level details, requiring the
198
- least amount of syntax possible to build GUI, and custom control support.
198
+ least amount of syntax possible to build GUI, and custom keyword support.
199
199
  email: andy.am@gmail.com
200
200
  executables:
201
201
  - girb
@@ -233,7 +233,7 @@ files:
233
233
  - examples/basic_window.rb
234
234
  - examples/basic_window2.rb
235
235
  - examples/color_button.rb
236
- - examples/color_the_shapes.rb
236
+ - examples/color_the_circles.rb
237
237
  - examples/control_gallery.rb
238
238
  - examples/custom_draw_text.rb
239
239
  - examples/custom_draw_text2.rb
@@ -252,6 +252,11 @@ files:
252
252
  - examples/method_based_custom_keyword.rb
253
253
  - examples/midi_player.rb
254
254
  - examples/simple_notepad.rb
255
+ - examples/tetris.rb
256
+ - examples/tetris/model/block.rb
257
+ - examples/tetris/model/game.rb
258
+ - examples/tetris/model/past_game.rb
259
+ - examples/tetris/model/tetromino.rb
255
260
  - examples/timer.rb
256
261
  - glimmer-dsl-libui.gemspec
257
262
  - icons/glimmer.png