glimmer-dsl-swt 0.6.1 → 0.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -2
  3. data/VERSION +1 -1
  4. data/bin/girb +1 -1
  5. data/bin/glimmer +5 -1
  6. data/icons/scaffold_app.png +0 -0
  7. data/lib/ext/glimmer/config.rb +13 -1
  8. data/lib/glimmer-dsl-swt.rb +5 -9
  9. data/lib/glimmer/Rakefile +5 -0
  10. data/lib/glimmer/data_binding/table_items_binding.rb +4 -1
  11. data/lib/glimmer/dsl/swt/cursor_expression.rb +1 -4
  12. data/lib/glimmer/dsl/swt/dsl.rb +1 -0
  13. data/lib/glimmer/dsl/swt/font_expression.rb +3 -1
  14. data/lib/glimmer/dsl/swt/image_expression.rb +21 -0
  15. data/lib/glimmer/dsl/swt/message_box_expression.rb +9 -1
  16. data/lib/glimmer/dsl/swt/widget_expression.rb +7 -7
  17. data/lib/glimmer/launcher.rb +59 -20
  18. data/lib/glimmer/package.rb +26 -9
  19. data/lib/glimmer/rake_task.rb +115 -5
  20. data/lib/glimmer/scaffold.rb +65 -32
  21. data/lib/glimmer/swt/display_proxy.rb +13 -2
  22. data/lib/glimmer/swt/image_proxy.rb +16 -23
  23. data/lib/glimmer/swt/layout_proxy.rb +2 -0
  24. data/lib/glimmer/swt/message_box_proxy.rb +23 -5
  25. data/lib/glimmer/swt/scrolled_composite_proxy.rb +6 -11
  26. data/lib/glimmer/swt/shell_proxy.rb +0 -1
  27. data/lib/glimmer/swt/table_proxy.rb +60 -2
  28. data/lib/glimmer/swt/widget_proxy.rb +72 -18
  29. data/samples/elaborate/contact_manager.rb +121 -0
  30. data/samples/elaborate/contact_manager/contact.rb +11 -0
  31. data/samples/elaborate/contact_manager/contact_manager_presenter.rb +26 -0
  32. data/samples/elaborate/contact_manager/contact_repository.rb +244 -0
  33. data/samples/elaborate/login.rb +108 -0
  34. data/samples/elaborate/tic_tac_toe.rb +55 -0
  35. data/samples/elaborate/tic_tac_toe/board.rb +124 -0
  36. data/samples/elaborate/tic_tac_toe/cell.rb +27 -0
  37. data/samples/elaborate/user_profile.rb +55 -0
  38. data/samples/hello/hello_browser.rb +8 -0
  39. data/samples/hello/hello_combo.rb +38 -0
  40. data/samples/hello/hello_computed.rb +69 -0
  41. data/samples/hello/hello_computed/contact.rb +21 -0
  42. data/samples/hello/hello_drag_and_drop.rb +29 -0
  43. data/samples/hello/hello_list_multi_selection.rb +48 -0
  44. data/samples/hello/hello_list_single_selection.rb +37 -0
  45. data/samples/hello/hello_menu_bar.rb +64 -0
  46. data/samples/hello/hello_message_box.rb +15 -0
  47. data/samples/hello/hello_pop_up_context_menu.rb +36 -0
  48. data/samples/hello/hello_tab.rb +24 -0
  49. data/samples/hello/hello_world.rb +8 -0
  50. metadata +66 -8
@@ -0,0 +1,108 @@
1
+ require "java"
2
+ require "observer"
3
+
4
+ #Presents login screen data
5
+ class LoginPresenter
6
+
7
+ attr_accessor :user_name
8
+ attr_accessor :password
9
+ attr_accessor :status
10
+
11
+ def initialize
12
+ @user_name = ""
13
+ @password = ""
14
+ @status = "Logged Out"
15
+ end
16
+
17
+ def status=(status)
18
+ @status = status
19
+
20
+ #TODO add feature to bind dependent properties to master property (2017-07-25 nested data binding)
21
+ notify_observers("logged_in")
22
+ notify_observers("logged_out")
23
+ end
24
+
25
+ def valid?
26
+ !@user_name.to_s.strip.empty? && !@password.to_s.strip.empty?
27
+ end
28
+
29
+ def logged_in
30
+ self.status == "Logged In"
31
+ end
32
+
33
+ def logged_out
34
+ !self.logged_in
35
+ end
36
+
37
+ def login
38
+ return unless valid?
39
+ self.status = "Logged In"
40
+ end
41
+
42
+ def logout
43
+ self.user_name = ""
44
+ self.password = ""
45
+ self.status = "Logged Out"
46
+ end
47
+
48
+ end
49
+
50
+ #Login screen
51
+ class Login
52
+ include Glimmer
53
+
54
+ def launch
55
+ presenter = LoginPresenter.new
56
+ @shell = shell {
57
+ text "Login"
58
+ composite {
59
+ grid_layout 2, false #two columns with differing widths
60
+
61
+ label { text "Username:" } # goes in column 1
62
+ @user_name_text = text { # goes in column 2
63
+ text bind(presenter, :user_name)
64
+ enabled bind(presenter, :logged_out)
65
+ on_key_pressed { |event|
66
+ @password_text.set_focus if event.keyCode == swt(:cr)
67
+ }
68
+ }
69
+
70
+ label { text "Password:" }
71
+ @password_text = text(:password, :border) {
72
+ text bind(presenter, :password)
73
+ enabled bind(presenter, :logged_out)
74
+ on_key_pressed { |event|
75
+ presenter.login if event.keyCode == swt(:cr)
76
+ }
77
+ }
78
+
79
+ label { text "Status:" }
80
+ label { text bind(presenter, :status) }
81
+
82
+ button {
83
+ text "Login"
84
+ enabled bind(presenter, :logged_out)
85
+ on_widget_selected { presenter.login }
86
+ on_key_pressed { |event|
87
+ presenter.login if event.keyCode == swt(:cr)
88
+ }
89
+ }
90
+
91
+ button {
92
+ text "Logout"
93
+ enabled bind(presenter, :logged_in)
94
+ on_widget_selected { presenter.logout }
95
+ on_key_pressed { |event|
96
+ if event.keyCode == swt(:cr)
97
+ presenter.logout
98
+ @user_name_text.set_focus
99
+ end
100
+ }
101
+ }
102
+ }
103
+ }
104
+ @shell.open
105
+ end
106
+ end
107
+
108
+ Login.new.launch
@@ -0,0 +1,55 @@
1
+ require_relative "tic_tac_toe/board"
2
+
3
+ class TicTacToe
4
+ include Glimmer
5
+
6
+ def initialize
7
+ @tic_tac_toe_board = Board.new
8
+ @shell = shell {
9
+ text "Tic-Tac-Toe"
10
+ minimum_size 150, 178
11
+ composite {
12
+ grid_layout 3, true
13
+ (1..3).each { |row|
14
+ (1..3).each { |column|
15
+ button {
16
+ layout_data :fill, :fill, true, true
17
+ text bind(@tic_tac_toe_board[row, column], :sign)
18
+ enabled bind(@tic_tac_toe_board[row, column], :empty)
19
+ font style: :bold, height: 20
20
+ on_widget_selected {
21
+ @tic_tac_toe_board.mark(row, column)
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
27
+ }
28
+ observe(@tic_tac_toe_board, :game_status) { |game_status|
29
+ display_win_message if game_status == Board::WIN
30
+ display_draw_message if game_status == Board::DRAW
31
+ }
32
+ end
33
+
34
+ def display_win_message
35
+ display_game_over_message("Player #{@tic_tac_toe_board.winning_sign} has won!")
36
+ end
37
+
38
+ def display_draw_message
39
+ display_game_over_message("Draw!")
40
+ end
41
+
42
+ def display_game_over_message(message_text)
43
+ message_box(@shell) {
44
+ text 'Game Over'
45
+ message message_text
46
+ }.open
47
+ @tic_tac_toe_board.reset
48
+ end
49
+
50
+ def open
51
+ @shell.open
52
+ end
53
+ end
54
+
55
+ TicTacToe.new.open
@@ -0,0 +1,124 @@
1
+ require_relative 'cell'
2
+
3
+ class TicTacToe
4
+ class Board
5
+ DRAW = :draw
6
+ IN_PROGRESS = :in_progress
7
+ WIN = :win
8
+ attr :winning_sign
9
+ attr_accessor :game_status
10
+
11
+ def initialize
12
+ @sign_state_machine = {nil => "X", "X" => "O", "O" => "X"}
13
+ build_grid
14
+ @winning_sign = Cell::EMPTY
15
+ @game_status = IN_PROGRESS
16
+ end
17
+
18
+ #row and column numbers are 1-based
19
+ def mark(row, column)
20
+ self[row, column].mark(current_sign)
21
+ game_over? #updates winning sign
22
+ end
23
+
24
+ def current_sign
25
+ @current_sign = @sign_state_machine[@current_sign]
26
+ end
27
+
28
+ def [](row, column)
29
+ @grid[row-1][column-1]
30
+ end
31
+
32
+ def game_over?
33
+ win? or draw?
34
+ end
35
+
36
+ def win?
37
+ win = (row_win? or column_win? or diagonal_win?)
38
+ self.game_status=WIN if win
39
+ win
40
+ end
41
+
42
+ def reset
43
+ (1..3).each do |row|
44
+ (1..3).each do |column|
45
+ self[row, column].reset
46
+ end
47
+ end
48
+ @winning_sign = Cell::EMPTY
49
+ @current_sign = nil
50
+ self.game_status=IN_PROGRESS
51
+ end
52
+
53
+ private
54
+
55
+ def build_grid
56
+ @grid = []
57
+ 3.times do |row_index| #0-based
58
+ @grid << []
59
+ 3.times { @grid[row_index] << Cell.new }
60
+ end
61
+ end
62
+
63
+ def row_win?
64
+ (1..3).each do |row|
65
+ if row_has_same_sign(row)
66
+ @winning_sign = self[row, 1].sign
67
+ return true
68
+ end
69
+ end
70
+ false
71
+ end
72
+
73
+ def column_win?
74
+ (1..3).each do |column|
75
+ if column_has_same_sign(column)
76
+ @winning_sign = self[1, column].sign
77
+ return true
78
+ end
79
+ end
80
+ false
81
+ end
82
+
83
+ #needs refactoring if we ever decide to make the board size dynamic
84
+ def diagonal_win?
85
+ if (self[1, 1].sign == self[2, 2].sign) and (self[2, 2].sign == self[3, 3].sign) and self[1, 1].marked
86
+ @winning_sign = self[1, 1].sign
87
+ return true
88
+ end
89
+ if (self[3, 1].sign == self[2, 2].sign) and (self[2, 2].sign == self[1, 3].sign) and self[3, 1].marked
90
+ @winning_sign = self[3, 1].sign
91
+ return true
92
+ end
93
+ false
94
+ end
95
+
96
+ def draw?
97
+ @board_full = true
98
+ 3.times do |x|
99
+ 3.times do |y|
100
+ @board_full = false if self[x, y].empty
101
+ end
102
+ end
103
+ self.game_status = DRAW if @board_full
104
+ @board_full
105
+ end
106
+
107
+ def row_has_same_sign(number)
108
+ row_sign = self[number, 1].sign
109
+ [2, 3].each do |column|
110
+ return false unless row_sign == (self[number, column].sign)
111
+ end
112
+ true if self[number, 1].marked
113
+ end
114
+
115
+ def column_has_same_sign(number)
116
+ column_sign = self[1, number].sign
117
+ [2, 3].each do |row|
118
+ return false unless column_sign == (self[row, number].sign)
119
+ end
120
+ true if self[1, number].marked
121
+ end
122
+
123
+ end
124
+ end
@@ -0,0 +1,27 @@
1
+ class TicTacToe
2
+ class Cell
3
+ EMPTY = ""
4
+ attr_accessor :sign, :empty
5
+
6
+ def initialize
7
+ reset
8
+ end
9
+
10
+ def mark(sign)
11
+ self.sign = sign
12
+ end
13
+
14
+ def reset
15
+ self.sign = EMPTY
16
+ end
17
+
18
+ def sign=(sign_symbol)
19
+ @sign = sign_symbol
20
+ self.empty = sign == EMPTY
21
+ end
22
+
23
+ def marked
24
+ !empty
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,55 @@
1
+ include Glimmer
2
+
3
+ shell {
4
+ text "User Profile"
5
+
6
+ composite {
7
+ grid_layout 2, false
8
+
9
+ group {
10
+ text "Name"
11
+ grid_layout 2, false
12
+ layout_data :fill, :fill, true, true
13
+ label {text "First"}; text {text "Bullet"}
14
+ label {text "Last"}; text {text "Tooth"}
15
+ }
16
+
17
+ group {
18
+ layout_data :fill, :fill, true, true
19
+ text "Gender"
20
+ radio {text "Male"; selection true}
21
+ radio {text "Female"}
22
+ }
23
+
24
+ group {
25
+ layout_data :fill, :fill, true, true
26
+ text "Role"
27
+ check {text "Student"; selection true}
28
+ check {text "Employee"; selection true}
29
+ }
30
+
31
+ group {
32
+ text "Experience"
33
+ row_layout
34
+ layout_data :fill, :fill, true, true
35
+ spinner {selection 5}; label {text "years"}
36
+ }
37
+
38
+ button {
39
+ text "save"
40
+ layout_data :right, :center, true, true
41
+ on_widget_selected {
42
+ message_box {
43
+ text 'Profile Saved!'
44
+ message 'User profile has been saved!'
45
+ }.open
46
+ }
47
+ }
48
+
49
+ button {
50
+ text "close"
51
+ layout_data :left, :center, true, true
52
+ on_widget_selected { exit(0) }
53
+ }
54
+ }
55
+ }.open
@@ -0,0 +1,8 @@
1
+ include Glimmer
2
+
3
+ shell {
4
+ minimum_size 1024, 860
5
+ browser {
6
+ url 'http://brightonresort.com/about'
7
+ }
8
+ }.open
@@ -0,0 +1,38 @@
1
+ class Person
2
+ attr_accessor :country, :country_options
3
+
4
+ def initialize
5
+ self.country_options=["", "Canada", "US", "Mexico"]
6
+ self.country = "Canada"
7
+ end
8
+
9
+ def reset_country
10
+ self.country = "Canada"
11
+ end
12
+ end
13
+
14
+ class HelloCombo
15
+ include Glimmer
16
+ def launch
17
+ person = Person.new
18
+
19
+ shell {
20
+ fill_layout :vertical
21
+ text 'Hello, Combo!'
22
+
23
+ combo(:read_only) {
24
+ selection bind(person, :country)
25
+ }
26
+
27
+ button {
28
+ text "Reset Selection"
29
+
30
+ on_widget_selected do
31
+ person.reset_country
32
+ end
33
+ }
34
+ }.open
35
+ end
36
+ end
37
+
38
+ HelloCombo.new.launch
@@ -0,0 +1,69 @@
1
+ require_relative 'hello_computed/contact'
2
+
3
+ class HelloComputed
4
+ include Glimmer
5
+
6
+ def initialize
7
+ @contact = Contact.new(
8
+ first_name: 'Barry',
9
+ last_name: 'McKibbin',
10
+ year_of_birth: 1985
11
+ )
12
+ end
13
+
14
+ def launch
15
+ shell {
16
+ text 'Hello, Computed!'
17
+ composite {
18
+ grid_layout {
19
+ num_columns 2
20
+ make_columns_equal_width true
21
+ horizontal_spacing 20
22
+ vertical_spacing 10
23
+ }
24
+ label {text 'First &Name: '}
25
+ text {
26
+ text bind(@contact, :first_name)
27
+ layout_data {
28
+ horizontal_alignment :fill
29
+ grab_excess_horizontal_space true
30
+ }
31
+ }
32
+ label {text '&Last Name: '}
33
+ text {
34
+ text bind(@contact, :last_name)
35
+ layout_data {
36
+ horizontal_alignment :fill
37
+ grab_excess_horizontal_space true
38
+ }
39
+ }
40
+ label {text '&Year of Birth: '}
41
+ text {
42
+ text bind(@contact, :year_of_birth)
43
+ layout_data {
44
+ horizontal_alignment :fill
45
+ grab_excess_horizontal_space true
46
+ }
47
+ }
48
+ label {text 'Name: '}
49
+ label {
50
+ text bind(@contact, :name, computed_by: [:first_name, :last_name])
51
+ layout_data {
52
+ horizontal_alignment :fill
53
+ grab_excess_horizontal_space true
54
+ }
55
+ }
56
+ label {text 'Age: '}
57
+ label {
58
+ text bind(@contact, :age, on_write: :to_i, computed_by: [:year_of_birth])
59
+ layout_data {
60
+ horizontal_alignment :fill
61
+ grab_excess_horizontal_space true
62
+ }
63
+ }
64
+ }
65
+ }.open
66
+ end
67
+ end
68
+
69
+ HelloComputed.new.launch