glimmer-dsl-swt 4.20.13.6 → 4.20.13.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +5 -5
- data/VERSION +1 -1
- data/docs/reference/GLIMMER_SAMPLES.md +13 -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/lib/glimmer/swt/image_proxy.rb +1 -1
- data/samples/elaborate/calculator.rb +2 -2
- data/samples/elaborate/contact_manager.rb +2 -2
- data/samples/elaborate/klondike_solitaire.rb +93 -0
- data/samples/elaborate/klondike_solitaire/model/column_pile.rb +60 -0
- data/samples/elaborate/klondike_solitaire/model/dealing_pile.rb +33 -0
- data/samples/elaborate/klondike_solitaire/model/dealt_pile.rb +25 -0
- data/samples/elaborate/klondike_solitaire/model/foundation_pile.rb +40 -0
- data/samples/elaborate/klondike_solitaire/model/game.rb +37 -0
- data/samples/elaborate/klondike_solitaire/model/playing_card.rb +86 -0
- data/samples/elaborate/klondike_solitaire/view/action_panel.rb +30 -0
- data/samples/elaborate/klondike_solitaire/view/column_pile.rb +66 -0
- data/samples/elaborate/klondike_solitaire/view/dealing_pile.rb +36 -0
- data/samples/elaborate/klondike_solitaire/view/dealt_pile.rb +38 -0
- data/samples/elaborate/klondike_solitaire/view/empty_playing_card.rb +33 -0
- data/samples/elaborate/klondike_solitaire/view/foundation_pile.rb +59 -0
- data/samples/elaborate/klondike_solitaire/view/hidden_playing_card.rb +26 -0
- data/samples/elaborate/klondike_solitaire/view/playing_card.rb +35 -0
- data/samples/elaborate/klondike_solitaire/view/tableau.rb +41 -0
- 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 +18 -2
@@ -0,0 +1,25 @@
|
|
1
|
+
class KlondikeSolitaire
|
2
|
+
module Model
|
3
|
+
class DealtPile
|
4
|
+
def initialize(game)
|
5
|
+
@game = game
|
6
|
+
end
|
7
|
+
|
8
|
+
def reset!
|
9
|
+
playing_cards.clear
|
10
|
+
end
|
11
|
+
|
12
|
+
def push!(playing_card)
|
13
|
+
playing_cards.push(playing_card)
|
14
|
+
end
|
15
|
+
|
16
|
+
def remove!(card)
|
17
|
+
playing_cards.delete(card)
|
18
|
+
end
|
19
|
+
|
20
|
+
def playing_cards
|
21
|
+
@playing_cards ||= []
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class KlondikeSolitaire
|
2
|
+
module Model
|
3
|
+
class FoundationPile
|
4
|
+
attr_reader :suit
|
5
|
+
|
6
|
+
def initialize(game, suit)
|
7
|
+
@game = game
|
8
|
+
@suit = suit
|
9
|
+
reset!
|
10
|
+
end
|
11
|
+
|
12
|
+
def reset!
|
13
|
+
playing_cards.clear
|
14
|
+
end
|
15
|
+
|
16
|
+
# adds a card
|
17
|
+
# validates if it is a card that belongs to the suit
|
18
|
+
def add!(playing_card)
|
19
|
+
if playing_card.suit == suit &&
|
20
|
+
(
|
21
|
+
(playing_cards.empty? && playing_card.rank == 1) ||
|
22
|
+
playing_card.rank == (playing_cards.last.rank + 1)
|
23
|
+
)
|
24
|
+
playing_cards.push(playing_card)
|
25
|
+
else
|
26
|
+
raise "Cannot add #{playing_card} to #{self}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def playing_cards
|
31
|
+
@playing_cards ||= []
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
"Foundation Pile #{suit} (#{playing_cards.map {|card| "#{card.rank}#{card.suit.to_s[0].upcase}"}.join(" | ")})"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative 'playing_card'
|
2
|
+
require_relative 'dealt_pile'
|
3
|
+
require_relative 'dealing_pile'
|
4
|
+
require_relative 'column_pile'
|
5
|
+
require_relative 'foundation_pile'
|
6
|
+
|
7
|
+
class KlondikeSolitaire
|
8
|
+
module Model
|
9
|
+
class Game
|
10
|
+
COLUMN_PILE_COUNT = 7
|
11
|
+
|
12
|
+
attr_reader :deck, :dealing_pile, :dealt_pile, :column_piles, :foundation_piles
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@deck = new_deck
|
16
|
+
@dealt_pile = DealtPile.new(self)
|
17
|
+
@dealing_pile = DealingPile.new(self)
|
18
|
+
@column_piles = COLUMN_PILE_COUNT.times.map {|n| ColumnPile.new(self, n + 1)}
|
19
|
+
@foundation_piles = PlayingCard::SUITS.map {|suit| FoundationPile.new(self, suit)}
|
20
|
+
end
|
21
|
+
|
22
|
+
def restart!
|
23
|
+
@deck = new_deck
|
24
|
+
@dealt_pile.reset!
|
25
|
+
@dealing_pile.reset!
|
26
|
+
@column_piles.each(&:reset!)
|
27
|
+
@foundation_piles.each(&:reset!)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def new_deck
|
33
|
+
PlayingCard.deck.shuffle
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
class KlondikeSolitaire
|
2
|
+
module Model
|
3
|
+
class PlayingCard
|
4
|
+
SUITS = [:spades, :hearts, :clubs, :diamonds]
|
5
|
+
BLACK_SUITS = [:spades, :clubs]
|
6
|
+
RED_SUITS = [:hearts, :diamonds]
|
7
|
+
RANK_COUNT = 13
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def deck
|
11
|
+
suit_decks.flatten
|
12
|
+
end
|
13
|
+
|
14
|
+
def suit_decks
|
15
|
+
SUITS.map do |suit|
|
16
|
+
suit_deck(suit)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def suit_deck(suit)
|
21
|
+
1.upto(RANK_COUNT).map do |rank|
|
22
|
+
new(rank, suit)
|
23
|
+
end
|
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
|
53
|
+
end
|
54
|
+
|
55
|
+
attr_reader :rank, :suit
|
56
|
+
attr_accessor :hidden
|
57
|
+
alias hidden? hidden
|
58
|
+
|
59
|
+
def initialize(rank, suit, hidden = false)
|
60
|
+
@rank = rank
|
61
|
+
@suit = suit
|
62
|
+
@hidden = hidden
|
63
|
+
end
|
64
|
+
|
65
|
+
def color
|
66
|
+
if BLACK_SUITS.include?(suit)
|
67
|
+
:black
|
68
|
+
elsif RED_SUITS.include?(suit)
|
69
|
+
:red
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_s
|
74
|
+
"Playing Card #{rank}#{suit.to_s[0].upcase}"
|
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
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class KlondikeSolitaire
|
2
|
+
module View
|
3
|
+
class ActionPanel
|
4
|
+
include Glimmer::UI::CustomWidget
|
5
|
+
|
6
|
+
option :game
|
7
|
+
|
8
|
+
body {
|
9
|
+
composite {
|
10
|
+
grid_layout(1, false) {
|
11
|
+
margin_width 0
|
12
|
+
margin_height 0
|
13
|
+
}
|
14
|
+
|
15
|
+
background :dark_green
|
16
|
+
|
17
|
+
button {
|
18
|
+
layout_data :center, :center, true, false
|
19
|
+
|
20
|
+
text 'Restart Game'
|
21
|
+
|
22
|
+
on_widget_selected {
|
23
|
+
game.restart!
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require_relative '../model/column_pile'
|
2
|
+
|
3
|
+
require_relative 'playing_card'
|
4
|
+
|
5
|
+
class KlondikeSolitaire
|
6
|
+
module View
|
7
|
+
class ColumnPile
|
8
|
+
include Glimmer::UI::CustomShape
|
9
|
+
|
10
|
+
IMAGE_EMPTY = image(50, 80) {
|
11
|
+
rectangle(0, 0, 50, 80) {
|
12
|
+
background :dark_green
|
13
|
+
|
14
|
+
rectangle(0, 0, 49, 79, 15, 15) {
|
15
|
+
foreground :gray
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
options :pile_x, :pile_y, :model
|
21
|
+
|
22
|
+
after_body {
|
23
|
+
observe(model, 'playing_cards.last.hidden') do
|
24
|
+
build_column_pile(model.playing_cards)
|
25
|
+
end
|
26
|
+
build_column_pile(model.playing_cards)
|
27
|
+
}
|
28
|
+
|
29
|
+
body {
|
30
|
+
shape(pile_x, pile_y) {
|
31
|
+
on_drop do |drop_event|
|
32
|
+
begin
|
33
|
+
card_shape = drop_event.dragged_shape.get_data('custom_shape')
|
34
|
+
card = card_shape.model
|
35
|
+
model.add!(card)
|
36
|
+
card_parent_pile = card_shape.parent_pile
|
37
|
+
card_source_model = card_parent_pile.model
|
38
|
+
cards = card_source_model.remove!(card)
|
39
|
+
if cards.is_a?(Array) # if it is a column pile
|
40
|
+
cards[1..-1].each do |card|
|
41
|
+
model.add!(card)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
drop_event.dragged_shape.dispose
|
45
|
+
rescue => e
|
46
|
+
# pd e
|
47
|
+
drop_event.doit = false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
def build_column_pile(playing_cards)
|
54
|
+
body_root.shapes.to_a.each(&:dispose)
|
55
|
+
current_parent = body_root
|
56
|
+
playing_cards.each_with_index do |card, i|
|
57
|
+
current_parent.content {
|
58
|
+
current_parent = playing_card(card_x: 0, card_y: 20, model: card, parent_pile: self) {
|
59
|
+
drag_source true unless card.hidden?
|
60
|
+
}.body_root
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative '../model/dealing_pile'
|
2
|
+
|
3
|
+
require_relative 'empty_playing_card'
|
4
|
+
require_relative 'hidden_playing_card'
|
5
|
+
|
6
|
+
class KlondikeSolitaire
|
7
|
+
module View
|
8
|
+
class DealingPile
|
9
|
+
include Glimmer::UI::CustomShape
|
10
|
+
|
11
|
+
options :pile_x, :pile_y, :model
|
12
|
+
|
13
|
+
after_body {
|
14
|
+
observe(model, 'playing_cards.empty?') do |empty_value|
|
15
|
+
body_root.shapes.to_a.each(&:dispose)
|
16
|
+
if empty_value
|
17
|
+
body_root.content {
|
18
|
+
empty_playing_card
|
19
|
+
}
|
20
|
+
else
|
21
|
+
body_root.content {
|
22
|
+
hidden_playing_card
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
}
|
27
|
+
|
28
|
+
body {
|
29
|
+
shape(pile_x, pile_y) {
|
30
|
+
hidden_playing_card
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative '../model/dealt_pile'
|
2
|
+
|
3
|
+
require_relative 'empty_playing_card'
|
4
|
+
require_relative 'playing_card'
|
5
|
+
|
6
|
+
class KlondikeSolitaire
|
7
|
+
module View
|
8
|
+
class DealtPile
|
9
|
+
include Glimmer::UI::CustomShape
|
10
|
+
|
11
|
+
options :pile_x, :pile_y, :model
|
12
|
+
|
13
|
+
after_body do
|
14
|
+
observe(model, 'playing_cards.empty?') do |empty_value|
|
15
|
+
if empty_value
|
16
|
+
body_root.shapes.to_a.dup.each(&:dispose)
|
17
|
+
body_root.content {
|
18
|
+
empty_playing_card
|
19
|
+
}
|
20
|
+
else
|
21
|
+
body_root.content {
|
22
|
+
playing_card(model: model.playing_cards.last, parent_pile: self) {
|
23
|
+
drag_source true
|
24
|
+
}
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
body {
|
31
|
+
shape(pile_x, pile_y) {
|
32
|
+
empty_playing_card
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative '../model/playing_card'
|
2
|
+
|
3
|
+
class KlondikeSolitaire
|
4
|
+
module View
|
5
|
+
class EmptyPlayingCard
|
6
|
+
include Glimmer::UI::CustomShape
|
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
|
+
|
15
|
+
body {
|
16
|
+
rectangle(card_x, card_y, 49, 79, 15, 15) {
|
17
|
+
foreground :gray
|
18
|
+
|
19
|
+
if suit
|
20
|
+
text {
|
21
|
+
string Model::PlayingCard.suit_text(suit)
|
22
|
+
x :default
|
23
|
+
y :default
|
24
|
+
is_transparent true
|
25
|
+
foreground Model::PlayingCard::BLACK_SUITS.include?(suit) ? :black : :red
|
26
|
+
}
|
27
|
+
end
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require_relative '../model/playing_card'
|
2
|
+
require_relative '../model/foundation_pile'
|
3
|
+
|
4
|
+
class KlondikeSolitaire
|
5
|
+
module View
|
6
|
+
class FoundationPile
|
7
|
+
include Glimmer::UI::CustomShape
|
8
|
+
|
9
|
+
options :pile_x, :pile_y, :game, :suit
|
10
|
+
|
11
|
+
attr_accessor :current_image, :model
|
12
|
+
|
13
|
+
before_body do
|
14
|
+
self.current_image = image(50, 80) {empty_playing_card(suit: suit)}
|
15
|
+
self.model = game.foundation_piles[Model::PlayingCard::SUITS.index(suit)]
|
16
|
+
end
|
17
|
+
|
18
|
+
after_body do
|
19
|
+
observe(model, 'playing_cards.last') do |last_card|
|
20
|
+
if last_card
|
21
|
+
body_root.content {
|
22
|
+
playing_card(model: last_card)
|
23
|
+
}
|
24
|
+
else
|
25
|
+
body_root.clear_shapes
|
26
|
+
body_root.content {
|
27
|
+
empty_playing_card(suit: suit)
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
body {
|
34
|
+
shape(pile_x, pile_y) {
|
35
|
+
empty_playing_card(suit: suit)
|
36
|
+
|
37
|
+
on_drop do |drop_event|
|
38
|
+
begin
|
39
|
+
# TODO make sure one cannot drag a column pile of cards here
|
40
|
+
card_shape = drop_event.dragged_shape.get_data('custom_shape')
|
41
|
+
card = card_shape.model
|
42
|
+
card_parent_pile = card_shape.parent_pile
|
43
|
+
card_source_model = card_parent_pile.model
|
44
|
+
raise 'Cannot accept multiple cards' if card_source_model.playing_cards.index(card) != (card_source_model.playing_cards.size - 1)
|
45
|
+
model.add!(card)
|
46
|
+
card_source_model.remove!(card)
|
47
|
+
drop_event.dragged_shape.dispose
|
48
|
+
rescue => e
|
49
|
+
# pd e
|
50
|
+
drop_event.doit = false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
}
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|