glimmer-dsl-swt 4.20.13.8 → 4.20.13.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/README.md +5 -5
- data/VERSION +1 -1
- data/docs/reference/GLIMMER_SAMPLES.md +24 -0
- data/docs/reference/GLIMMER_STYLE_GUIDE.md +2 -1
- data/glimmer-dsl-swt.gemspec +0 -0
- data/lib/glimmer/rake_task/scaffold.rb +14 -14
- data/lib/glimmer/swt/custom/code_text.rb +4 -4
- data/lib/glimmer/swt/custom/shape.rb +1 -1
- data/samples/elaborate/calculator.rb +2 -2
- data/samples/elaborate/contact_manager.rb +2 -2
- data/samples/elaborate/game_of_life.rb +111 -0
- data/samples/elaborate/game_of_life/model/cell.rb +72 -0
- data/samples/elaborate/game_of_life/model/grid.rb +97 -0
- data/samples/elaborate/klondike_solitaire.rb +30 -23
- data/samples/elaborate/klondike_solitaire/model/playing_card.rb +36 -0
- data/samples/elaborate/klondike_solitaire/view/empty_playing_card.rb +12 -4
- data/samples/elaborate/klondike_solitaire/view/foundation_pile.rb +4 -4
- data/samples/elaborate/klondike_solitaire/view/hidden_playing_card.rb +8 -1
- data/samples/elaborate/klondike_solitaire/view/playing_card.rb +3 -3
- data/samples/elaborate/klondike_solitaire/view/tableau.rb +4 -4
- data/samples/elaborate/login.rb +2 -2
- data/samples/elaborate/mandelbrot_fractal.rb +12 -12
- data/samples/elaborate/meta_sample.rb +2 -2
- data/samples/elaborate/metronome.rb +2 -2
- data/samples/elaborate/stock_ticker.rb +8 -8
- data/samples/elaborate/tetris.rb +4 -4
- data/samples/elaborate/tetris/view/bevel.rb +2 -2
- data/samples/elaborate/tetris/view/score_lane.rb +2 -2
- data/samples/elaborate/tic_tac_toe.rb +6 -6
- data/samples/elaborate/timer.rb +4 -4
- data/samples/elaborate/weather.rb +4 -4
- data/samples/hello/hello_button.rb +2 -2
- data/samples/hello/hello_c_combo.rb +2 -2
- data/samples/hello/hello_canvas.rb +4 -4
- data/samples/hello/hello_canvas_animation.rb +2 -2
- data/samples/hello/hello_canvas_data_binding.rb +2 -2
- data/samples/hello/hello_checkbox.rb +2 -2
- data/samples/hello/hello_checkbox_group.rb +2 -2
- data/samples/hello/hello_code_text.rb +2 -2
- data/samples/hello/hello_color_dialog.rb +2 -2
- data/samples/hello/hello_combo.rb +2 -2
- data/samples/hello/hello_computed.rb +14 -22
- data/samples/hello/hello_cool_bar.rb +2 -2
- data/samples/hello/hello_cursor.rb +2 -2
- data/samples/hello/hello_custom_shape.rb +2 -2
- data/samples/hello/hello_custom_shell.rb +2 -2
- data/samples/hello/hello_custom_widget.rb +4 -4
- data/samples/hello/hello_date_time.rb +2 -2
- data/samples/hello/hello_directory_dialog.rb +2 -2
- data/samples/hello/hello_file_dialog.rb +2 -2
- data/samples/hello/hello_font_dialog.rb +2 -2
- data/samples/hello/hello_group.rb +2 -2
- data/samples/hello/hello_list_multi_selection.rb +2 -2
- data/samples/hello/hello_list_single_selection.rb +2 -2
- data/samples/hello/hello_progress_bar.rb +2 -2
- data/samples/hello/hello_radio.rb +2 -2
- data/samples/hello/hello_radio_group.rb +2 -2
- data/samples/hello/hello_scale.rb +2 -2
- data/samples/hello/hello_spinner.rb +2 -2
- data/samples/hello/hello_table.rb +2 -2
- data/samples/hello/hello_text.rb +2 -2
- data/samples/hello/hello_tool_bar.rb +2 -2
- data/samples/hello/hello_tray_item.rb +2 -2
- data/samples/hello/hello_tree.rb +4 -4
- metadata +5 -2
@@ -0,0 +1,97 @@
|
|
1
|
+
# Copyright (c) 2007-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_relative 'cell'
|
23
|
+
|
24
|
+
class GameOfLife
|
25
|
+
module Model
|
26
|
+
class Grid
|
27
|
+
include Glimmer # included only to utilize sync_exec/async_exec
|
28
|
+
DEFAULT_ROW_COUNT = 100
|
29
|
+
DEFAULT_COLUMN_COUNT = 100
|
30
|
+
|
31
|
+
attr_reader :row_count, :column_count
|
32
|
+
attr_accessor :cell_rows, :previous_cell_rows, :playing, :speed
|
33
|
+
alias playing? playing
|
34
|
+
|
35
|
+
def initialize(row_count=DEFAULT_ROW_COUNT, column_count=DEFAULT_COLUMN_COUNT)
|
36
|
+
@row_count = row_count
|
37
|
+
@column_count = column_count
|
38
|
+
@speed = 1.0
|
39
|
+
build_cells
|
40
|
+
end
|
41
|
+
|
42
|
+
def clear!
|
43
|
+
cell_rows.each do |row|
|
44
|
+
row.each do |cell|
|
45
|
+
cell.die!
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# steps into the next generation of cells given their current neighbors
|
51
|
+
def step!
|
52
|
+
self.previous_cell_rows = cell_rows.map do |row|
|
53
|
+
row.map do |cell|
|
54
|
+
cell.clone
|
55
|
+
end
|
56
|
+
end
|
57
|
+
cell_rows.each do |row|
|
58
|
+
row.each do |cell|
|
59
|
+
cell.step!
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def toggle_playback!
|
65
|
+
if playing?
|
66
|
+
stop!
|
67
|
+
else
|
68
|
+
play!
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def play!
|
73
|
+
self.playing = true
|
74
|
+
Thread.new do
|
75
|
+
while @playing
|
76
|
+
sync_exec { step! }
|
77
|
+
sleep(1.0/@speed)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def stop!
|
83
|
+
self.playing = false
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def build_cells
|
89
|
+
@cell_rows = @row_count.times.map do |row_index|
|
90
|
+
@column_count.times.map do |column_index|
|
91
|
+
Cell.new(self, row_index, column_index)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -11,17 +11,11 @@ class KlondikeSolitaire
|
|
11
11
|
PLAYING_CARD_WIDTH = 50
|
12
12
|
PLAYING_CARD_HEIGHT = 80
|
13
13
|
PLAYING_CARD_SPACING = 5
|
14
|
+
MARGIN = 15
|
15
|
+
TABLEAU_WIDTH = 2*MARGIN + 7*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING)
|
16
|
+
TABLEAU_HEIGHT = 400
|
14
17
|
|
15
|
-
|
16
|
-
#
|
17
|
-
# options :title, :background_color
|
18
|
-
# option :width, default: 320
|
19
|
-
# option :height, default: 240
|
20
|
-
|
21
|
-
## Use before_body block to pre-initialize variables to use in body
|
22
|
-
#
|
23
|
-
#
|
24
|
-
before_body {
|
18
|
+
before_body do
|
25
19
|
@game = Model::Game.new
|
26
20
|
Display.app_name = 'Glimmer Klondike Solitaire'
|
27
21
|
@display = display {
|
@@ -32,36 +26,49 @@ class KlondikeSolitaire
|
|
32
26
|
display_about_dialog
|
33
27
|
}
|
34
28
|
}
|
35
|
-
|
36
|
-
|
37
|
-
## Use after_body block to setup observers for widgets in body
|
38
|
-
#
|
39
|
-
# after_body {
|
40
|
-
#
|
41
|
-
# }
|
29
|
+
end
|
42
30
|
|
43
|
-
## Add widget content inside custom shell body
|
44
|
-
## Top-most widget must be a shell or another custom shell
|
45
|
-
#
|
46
31
|
body {
|
47
32
|
shell(:no_resize) {
|
48
33
|
row_layout(:vertical) {
|
49
34
|
fill true
|
50
35
|
center true
|
36
|
+
margin_width 0
|
37
|
+
margin_height 0
|
38
|
+
margin_top 15
|
51
39
|
}
|
52
|
-
minimum_size
|
40
|
+
minimum_size TABLEAU_WIDTH, TABLEAU_HEIGHT
|
53
41
|
text "Glimmer Klondike Solitaire"
|
54
42
|
background :dark_green
|
55
43
|
|
56
44
|
action_panel(game: @game)
|
57
45
|
tableau(game: @game) {
|
58
46
|
layout_data {
|
59
|
-
width
|
60
|
-
height
|
47
|
+
width TABLEAU_WIDTH
|
48
|
+
height TABLEAU_HEIGHT
|
61
49
|
}
|
62
50
|
}
|
63
51
|
|
64
52
|
menu_bar {
|
53
|
+
menu {
|
54
|
+
text '&Game'
|
55
|
+
menu_item {
|
56
|
+
text '&Restart'
|
57
|
+
accelerator (OS.mac? ? :command : :ctrl), :r
|
58
|
+
|
59
|
+
on_widget_selected {
|
60
|
+
@game.restart!
|
61
|
+
}
|
62
|
+
}
|
63
|
+
menu_item {
|
64
|
+
text 'E&xit'
|
65
|
+
accelerator :alt, :f4
|
66
|
+
|
67
|
+
on_widget_selected {
|
68
|
+
body_root.close
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
65
72
|
menu {
|
66
73
|
text '&Help'
|
67
74
|
menu_item {
|
@@ -22,6 +22,34 @@ class KlondikeSolitaire
|
|
22
22
|
new(rank, suit)
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
def rank_text(rank)
|
27
|
+
case rank
|
28
|
+
when 1
|
29
|
+
'A'
|
30
|
+
when 11
|
31
|
+
'J'
|
32
|
+
when 12
|
33
|
+
'Q'
|
34
|
+
when 13
|
35
|
+
'K'
|
36
|
+
else
|
37
|
+
rank
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def suit_text(suit)
|
42
|
+
case suit
|
43
|
+
when :spades
|
44
|
+
"♠"
|
45
|
+
when :hearts
|
46
|
+
"♥"
|
47
|
+
when :clubs
|
48
|
+
"♣"
|
49
|
+
when :diamonds
|
50
|
+
"♦"
|
51
|
+
end
|
52
|
+
end
|
25
53
|
end
|
26
54
|
|
27
55
|
attr_reader :rank, :suit
|
@@ -45,6 +73,14 @@ class KlondikeSolitaire
|
|
45
73
|
def to_s
|
46
74
|
"Playing Card #{rank}#{suit.to_s[0].upcase}"
|
47
75
|
end
|
76
|
+
|
77
|
+
def suit_text
|
78
|
+
self.class.suit_text(suit)
|
79
|
+
end
|
80
|
+
|
81
|
+
def rank_text
|
82
|
+
self.class.rank_text(rank)
|
83
|
+
end
|
48
84
|
end
|
49
85
|
end
|
50
86
|
end
|
@@ -1,20 +1,28 @@
|
|
1
|
+
require_relative '../model/playing_card'
|
2
|
+
|
1
3
|
class KlondikeSolitaire
|
2
4
|
module View
|
3
5
|
class EmptyPlayingCard
|
4
6
|
include Glimmer::UI::CustomShape
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
+
options :card_x, :card_y, :suit
|
9
|
+
|
10
|
+
before_body do
|
11
|
+
self.card_x ||= 0
|
12
|
+
self.card_y ||= 0
|
13
|
+
end
|
14
|
+
|
8
15
|
body {
|
9
|
-
rectangle(
|
16
|
+
rectangle(card_x, card_y, 49, 79, 15, 15) {
|
10
17
|
foreground :gray
|
11
18
|
|
12
19
|
if suit
|
13
20
|
text {
|
14
|
-
string suit
|
21
|
+
string Model::PlayingCard.suit_text(suit)
|
15
22
|
x :default
|
16
23
|
y :default
|
17
24
|
is_transparent true
|
25
|
+
foreground Model::PlayingCard::BLACK_SUITS.include?(suit) ? :black : :red
|
18
26
|
}
|
19
27
|
end
|
20
28
|
}
|
@@ -10,12 +10,12 @@ class KlondikeSolitaire
|
|
10
10
|
|
11
11
|
attr_accessor :current_image, :model
|
12
12
|
|
13
|
-
before_body
|
13
|
+
before_body do
|
14
14
|
self.current_image = image(50, 80) {empty_playing_card(suit: suit)}
|
15
15
|
self.model = game.foundation_piles[Model::PlayingCard::SUITS.index(suit)]
|
16
|
-
|
16
|
+
end
|
17
17
|
|
18
|
-
after_body
|
18
|
+
after_body do
|
19
19
|
observe(model, 'playing_cards.last') do |last_card|
|
20
20
|
if last_card
|
21
21
|
body_root.content {
|
@@ -28,7 +28,7 @@ class KlondikeSolitaire
|
|
28
28
|
}
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
31
|
+
end
|
32
32
|
|
33
33
|
body {
|
34
34
|
shape(pile_x, pile_y) {
|
@@ -3,8 +3,15 @@ class KlondikeSolitaire
|
|
3
3
|
class HiddenPlayingCard
|
4
4
|
include Glimmer::UI::CustomShape
|
5
5
|
|
6
|
+
options :card_x, :card_y
|
7
|
+
|
8
|
+
before_body do
|
9
|
+
self.card_x ||= 0
|
10
|
+
self.card_y ||= 0
|
11
|
+
end
|
12
|
+
|
6
13
|
body {
|
7
|
-
rectangle(
|
14
|
+
rectangle(card_x, card_y, 49, 79, 15, 15) {
|
8
15
|
background :red
|
9
16
|
|
10
17
|
# border
|
@@ -5,10 +5,10 @@ class KlondikeSolitaire
|
|
5
5
|
|
6
6
|
options :card_x, :card_y, :model, :parent_pile
|
7
7
|
|
8
|
-
before_body
|
8
|
+
before_body do
|
9
9
|
self.card_x ||= 0
|
10
10
|
self.card_y ||= 0
|
11
|
-
|
11
|
+
end
|
12
12
|
|
13
13
|
body {
|
14
14
|
rectangle(card_x, card_y, 49, 79, 15, 15) {
|
@@ -21,7 +21,7 @@ class KlondikeSolitaire
|
|
21
21
|
|
22
22
|
unless model.hidden?
|
23
23
|
text {
|
24
|
-
string model ? "#{model.
|
24
|
+
string model ? "#{model.rank_text}#{model.suit_text}" : ""
|
25
25
|
x 5
|
26
26
|
y 5
|
27
27
|
foreground model ? model.color : :transparent
|
@@ -18,14 +18,14 @@ class KlondikeSolitaire
|
|
18
18
|
|
19
19
|
# row 1
|
20
20
|
@foundation_piles = Model::PlayingCard::SUITS.each_with_index.map do |suit, i|
|
21
|
-
foundation_pile(pile_x: i*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING), pile_y: 0, game: game, suit: suit)
|
21
|
+
foundation_pile(pile_x: MARGIN + i*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING), pile_y: 0, game: game, suit: suit)
|
22
22
|
end
|
23
|
-
@dealt_pile = dealt_pile(pile_x: 5*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING), pile_y: 0, model: game.dealt_pile)
|
24
|
-
@dealing_pile = dealing_pile(pile_x: 6*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING), pile_y: 0, model: game.dealing_pile)
|
23
|
+
@dealt_pile = dealt_pile(pile_x: MARGIN + 5*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING), pile_y: 0, model: game.dealt_pile)
|
24
|
+
@dealing_pile = dealing_pile(pile_x: MARGIN + 6*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING), pile_y: 0, model: game.dealing_pile)
|
25
25
|
|
26
26
|
# row 2
|
27
27
|
@column_piles = 7.times.map do |n|
|
28
|
-
column_pile(pile_x: n*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING), pile_y: PLAYING_CARD_HEIGHT + PLAYING_CARD_SPACING, model: game.column_piles[n])
|
28
|
+
column_pile(pile_x: MARGIN + n*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING), pile_y: PLAYING_CARD_HEIGHT + PLAYING_CARD_SPACING, model: game.column_piles[n])
|
29
29
|
end
|
30
30
|
|
31
31
|
on_mouse_up do |event|
|
data/samples/elaborate/login.rb
CHANGED
@@ -149,33 +149,33 @@ class MandelbrotFractal
|
|
149
149
|
|
150
150
|
option :zoom, default: 1.0
|
151
151
|
|
152
|
-
before_body
|
152
|
+
before_body do
|
153
153
|
Display.app_name = 'Mandelbrot Fractal'
|
154
154
|
# pre-calculate mandelbrot image
|
155
155
|
@mandelbrot_image = build_mandelbrot_image
|
156
|
-
|
156
|
+
end
|
157
157
|
|
158
|
-
after_body
|
159
|
-
observe(Mandelbrot, :work_in_progress)
|
158
|
+
after_body do
|
159
|
+
observe(Mandelbrot, :work_in_progress) do
|
160
160
|
update_mandelbrot_shell_title!
|
161
|
-
|
162
|
-
observe(Mandelbrot, :zoom)
|
161
|
+
end
|
162
|
+
observe(Mandelbrot, :zoom) do
|
163
163
|
update_mandelbrot_shell_title!
|
164
|
-
|
164
|
+
end
|
165
165
|
# pre-calculate zoomed mandelbrot images even before the user zooms in
|
166
166
|
puts 'Starting background calculation thread...'
|
167
|
-
@thread = Thread.new
|
167
|
+
@thread = Thread.new do
|
168
168
|
future_zoom = 1.5
|
169
|
-
loop
|
169
|
+
loop do
|
170
170
|
puts "Creating mandelbrot for background calculation at zoom: #{future_zoom}"
|
171
171
|
the_mandelbrot = Mandelbrot.for(max_iterations: color_palette.size - 1, zoom: future_zoom, background: true)
|
172
172
|
pixels = the_mandelbrot.calculate_points
|
173
173
|
build_mandelbrot_image(mandelbrot_zoom: future_zoom)
|
174
174
|
@canvas.cursor = :cross unless @canvas.disposed?
|
175
175
|
future_zoom += 0.5
|
176
|
-
|
177
|
-
|
178
|
-
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
179
|
|
180
180
|
body {
|
181
181
|
shell(:no_resize) {
|
@@ -192,13 +192,13 @@ end
|
|
192
192
|
class MetaSampleApplication
|
193
193
|
include Glimmer::UI::CustomShell
|
194
194
|
|
195
|
-
before_body
|
195
|
+
before_body do
|
196
196
|
Sample.ensure_user_glimmer_directory
|
197
197
|
selected_sample_directory = SampleDirectory.sample_directories.first
|
198
198
|
selected_sample = selected_sample_directory.samples.first
|
199
199
|
selected_sample_directory.selected_sample_name = selected_sample.name
|
200
200
|
Display.app_name = 'Glimmer Meta-Sample'
|
201
|
-
|
201
|
+
end
|
202
202
|
|
203
203
|
body {
|
204
204
|
shell(:fill_screen) {
|
@@ -65,7 +65,7 @@ class StockTicker
|
|
65
65
|
|
66
66
|
include Glimmer::UI::CustomShell
|
67
67
|
|
68
|
-
before_body
|
68
|
+
before_body do
|
69
69
|
@stocks = [
|
70
70
|
Stock.new('DELL', 81),
|
71
71
|
Stock.new('AAPL', 121),
|
@@ -126,16 +126,16 @@ class StockTicker
|
|
126
126
|
end
|
127
127
|
end
|
128
128
|
end
|
129
|
-
|
129
|
+
end
|
130
130
|
|
131
|
-
after_body
|
132
|
-
@thread = Thread.new
|
133
|
-
loop
|
131
|
+
after_body do
|
132
|
+
@thread = Thread.new do
|
133
|
+
loop do
|
134
134
|
@stocks.each(&:tick!)
|
135
135
|
sleep(0.01)
|
136
|
-
|
137
|
-
|
138
|
-
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
139
|
|
140
140
|
body {
|
141
141
|
shell {
|