wads 0.1.3 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,256 @@
1
+ require 'gosu'
2
+ require_relative '../lib/wads'
3
+
4
+ include Wads
5
+
6
+ class ThemeTestApp < WadsApp
7
+ def initialize
8
+ super(800, 600, "Wads Theme Test App", ThemeTestDisplay.new)
9
+ end
10
+ end
11
+
12
+ class ThemeTestDisplay < Widget
13
+ def initialize
14
+ super(0, 0, 800, 600)
15
+ disable_border
16
+
17
+ if ARGV.length == 0
18
+ render_basic_widgets
19
+ elsif ARGV[0] == "-h" or ARGV[0] == "h" or ARGV[0] == "help"
20
+ puts "Wads Theme Tester"
21
+ puts " "
22
+ display_help
23
+ elsif ARGV[0] == "border"
24
+ render_border_layout
25
+ elsif ARGV[0] == "three"
26
+ render_top_middle_bottom_layout
27
+ elsif ARGV[0] == "header"
28
+ render_header_layout
29
+ elsif ARGV[0] == "footer"
30
+ render_footer_layout
31
+ elsif ARGV[0] == "vertical"
32
+ render_vertical_layout
33
+ elsif ARGV[0] == "horizontal"
34
+ render_horizontal_layout
35
+ elsif ARGV[0] == "eastwest"
36
+ render_east_west_layout
37
+ elsif ARGV[0] == "plot"
38
+ render_plot
39
+ elsif ARGV[0] == "form"
40
+ render_form
41
+ elsif ARGV[0] == "overlay"
42
+ render_overlay
43
+ else
44
+ puts "Argument #{ARGV[0]} is invalid."
45
+ display_help
46
+ end
47
+ end
48
+
49
+ def display_help
50
+ puts "Valid arguments are:"
51
+ puts " border show BorderLayout"
52
+ puts " three show TopMiddleBottomLayout"
53
+ puts " header show HeaderContentLayout"
54
+ puts " footer show ContentFooterLayout"
55
+ puts " vertical show VerticalColumnLayout"
56
+ puts " eastwest show EastWestLayout"
57
+ puts " plot show a simple plot using HeaderContentLayout"
58
+ puts " form test a form"
59
+ puts " overlay show an overlay widget"
60
+ exit
61
+ end
62
+
63
+ def render_basic_widgets
64
+ set_layout(LAYOUT_TOP_MIDDLE_BOTTOM)
65
+
66
+ # Example of using the layout for absolute positioning
67
+ # and then relative positioning of a child widget
68
+ # within that
69
+ image = get_layout.add_image("./media/Banner.png", { ARG_SECTION => SECTION_TOP})
70
+ image.add_text("Banner", 10, 10)
71
+
72
+ get_layout.add_text("Hello", { ARG_SECTION => SECTION_CENTER})
73
+ get_layout.add_text("There", { ARG_SECTION => SECTION_CENTER})
74
+ get_layout.add_button("Test Button", { ARG_SECTION => SECTION_CENTER}) do
75
+ puts "User hit the test button"
76
+ end
77
+
78
+ table = get_layout.add_multi_select_table(["A", "B", "C"], 4, { ARG_SECTION => SECTION_CENTER})
79
+ table.add_row(["These", "are", "values in row 1"])
80
+ table.add_row(["These", "are", "values in row 2"])
81
+ table.add_row(["These", "are", "values in row 3"])
82
+ table.add_row(["These", "are", "values in row 4"])
83
+
84
+ panel = get_layout.add_horizontal_panel({ ARG_SECTION => SECTION_BOTTOM})
85
+ panel.add_button("Exit", 380, panel.height - 30) do
86
+ WidgetResult.new(true)
87
+ end
88
+ end
89
+
90
+ def render_header_layout
91
+ set_layout(LAYOUT_HEADER_CONTENT)
92
+
93
+ header = get_layout.add_max_panel({ ARG_SECTION => SECTION_HEADER,
94
+ ARG_THEME => WadsNatureTheme.new })
95
+ header.get_layout.add_text("I am the header section",
96
+ { ARG_TEXT_ALIGN => TEXT_ALIGN_CENTER,
97
+ ARG_USE_LARGE_FONT => true})
98
+
99
+ main = get_layout.add_max_panel({ ARG_SECTION => SECTION_CONTENT,
100
+ ARG_THEME => WadsNatureTheme.new })
101
+ main.get_layout.add_document(sample_content)
102
+ table = main.get_layout.add_multi_select_table(["A", "B", "C"], 4, { ARG_SECTION => SECTION_WEST})
103
+ table.add_row(["Key1", "Value1", "ValueD"])
104
+ table.add_row(["Key2", "Value2", "ValueE"])
105
+ table.add_row(["Key3", "Value3", "ValueF"])
106
+ end
107
+
108
+ def render_border_layout
109
+ set_layout(LAYOUT_BORDER)
110
+ header = get_layout.add_max_panel({ ARG_SECTION => SECTION_NORTH})
111
+ header.get_layout.add_text("I am the header section", { ARG_TEXT_ALIGN => TEXT_ALIGN_CENTER})
112
+
113
+ west = get_layout.add_vertical_panel({ ARG_SECTION => SECTION_WEST})
114
+ west.get_layout.add_button("Do stuff") do
115
+ puts "Hit the do stuff button"
116
+ end
117
+ west.get_layout.add_button("More stuff") do
118
+ puts "Hit the more stuff button"
119
+ end
120
+
121
+ get_layout.add_document(sample_content, { ARG_SECTION => SECTION_CENTER})
122
+
123
+ east = get_layout.add_vertical_panel({ ARG_SECTION => SECTION_EAST})
124
+ east.get_layout.add_text("item1")
125
+ east.get_layout.add_text("item2")
126
+
127
+ footer = get_layout.add_max_panel({ ARG_SECTION => SECTION_SOUTH})
128
+ footer.get_layout.add_text("I am the footer section", { ARG_TEXT_ALIGN => TEXT_ALIGN_CENTER})
129
+ end
130
+
131
+ def render_top_middle_bottom_layout
132
+ set_layout(LAYOUT_TOP_MIDDLE_BOTTOM)
133
+ header = get_layout.add_max_panel({ ARG_SECTION => SECTION_TOP})
134
+ header.get_layout.add_text("I am the header section", { ARG_TEXT_ALIGN => TEXT_ALIGN_CENTER})
135
+
136
+ get_layout.add_document(sample_content, { ARG_SECTION => SECTION_MIDDLE})
137
+
138
+ footer = get_layout.add_max_panel({ ARG_SECTION => SECTION_BOTTOM})
139
+ footer.get_layout.add_text("I am the footer section", { ARG_TEXT_ALIGN => TEXT_ALIGN_CENTER})
140
+ end
141
+
142
+ def sample_content
143
+ <<~HEREDOC
144
+ This is the content section.
145
+ A document can contain multi-line text.
146
+ Typically you provide the content
147
+ using a squiggly heredoc.
148
+ HEREDOC
149
+ end
150
+
151
+ def render_footer_layout
152
+ set_layout(LAYOUT_CONTENT_FOOTER)
153
+
154
+ get_layout.add_document(sample_content, { ARG_SECTION => SECTION_CONTENT})
155
+
156
+ footer = get_layout.add_max_panel({ ARG_SECTION => SECTION_FOOTER,
157
+ ARG_THEME => WadsBrightTheme.new })
158
+ footer.get_layout.add_text("I am the footer section", { ARG_TEXT_ALIGN => TEXT_ALIGN_CENTER})
159
+ end
160
+
161
+ def render_vertical_layout
162
+ set_layout(LAYOUT_VERTICAL_COLUMN)
163
+ get_layout.add_image("./media/Banner.png")
164
+ get_layout.add_text("This is text below the image")
165
+ get_layout.add_text("Each widget will get placed below the previous in a vertical column.")
166
+ end
167
+
168
+ def render_east_west_layout
169
+ set_layout(LAYOUT_EAST_WEST)
170
+ table = get_layout.add_multi_select_table(["A", "B", ""], 4, { ARG_SECTION => SECTION_WEST})
171
+ table.add_row(["Key1", "Value1"])
172
+ table.add_row(["Key2", "Value2"])
173
+ table.add_row(["Key3", "Value3"])
174
+
175
+ get_layout.add_document(sample_content, { ARG_SECTION => SECTION_EAST})
176
+ end
177
+
178
+ def render_plot
179
+ set_layout(LAYOUT_HEADER_CONTENT)
180
+
181
+ header = get_layout.add_max_panel({ ARG_SECTION => SECTION_HEADER,
182
+ ARG_THEME => WadsBrightTheme.new })
183
+ # The zero x coord doesn't matter here because we center it below
184
+ # Centering only adjusts the x coordinate
185
+ header.add_text("This is a plot of sine (yellow) and cosine (pink) waves", 0, 35)
186
+ header.center_children
187
+ header.disable_border
188
+
189
+ plot = get_layout.add_plot({ ARG_SECTION => SECTION_CONTENT})
190
+ plot.define_range(VisibleRange.new(-5, 5, -5, 5))
191
+ plot.enable_border
192
+ x = -5
193
+ while x < 5
194
+ plot.add_data_point("Sine", x, Math.sin(x), COLOR_LIME)
195
+ plot.add_data_point("Cosine", x, Math.cos(x), COLOR_PINK)
196
+ x = x + 0.05
197
+ end
198
+
199
+ # Draw the 0 horizontal and vertical axes
200
+ plot.add_child(Line.new(plot.draw_x(0), plot.draw_y(-5), plot.draw_x(0), plot.draw_y(5), COLOR_GRAY))
201
+ plot.add_child(Line.new(plot.draw_x(-5), plot.draw_y(0), plot.draw_x(5), plot.draw_y(0), COLOR_GRAY))
202
+ end
203
+
204
+ def render_form
205
+ set_layout(LAYOUT_CONTENT_FOOTER)
206
+
207
+ content_panel = get_layout.add_max_panel({ ARG_SECTION => SECTION_CONTENT,
208
+ ARG_LAYOUT => LAYOUT_EAST_WEST,
209
+ ARG_PANEL_WIDTH => 200 })
210
+
211
+ label_panel = content_panel.add_panel(SECTION_WEST)
212
+ label_panel.get_layout.add_text("First Name", { ARG_TEXT_ALIGN => TEXT_ALIGN_RIGHT})
213
+ label_panel.get_layout.add_text("Middle Name", { ARG_TEXT_ALIGN => TEXT_ALIGN_RIGHT})
214
+ label_panel.get_layout.add_text("Last Name", { ARG_TEXT_ALIGN => TEXT_ALIGN_RIGHT})
215
+
216
+ field_panel = content_panel.add_panel(SECTION_EAST)
217
+ @first_name = field_panel.get_layout.add_text_input(200)
218
+ @middle_name = field_panel.get_layout.add_text_input(200)
219
+ @last_name = field_panel.get_layout.add_text_input(200)
220
+
221
+ footer_panel = get_layout.add_max_panel({ ARG_SECTION => SECTION_FOOTER})
222
+ footer_panel.get_layout.add_button("Display Full Name", {ARG_TEXT_ALIGN => TEXT_ALIGN_CENTER}) do
223
+ footer_panel.get_layout.add_text("The full name is #{@first_name.text} #{@middle_name.text} #{@last_name.text}.")
224
+ end
225
+ end
226
+
227
+ def render_overlay
228
+ set_layout(LAYOUT_HEADER_CONTENT)
229
+
230
+ header = get_layout.add_max_panel({ ARG_SECTION => SECTION_HEADER})
231
+ header.get_layout.add_text("I am the header section", { ARG_TEXT_ALIGN => TEXT_ALIGN_CENTER})
232
+
233
+ main = get_layout.add_max_panel({ ARG_SECTION => SECTION_CONTENT})
234
+ main.get_layout.add_document(sample_content)
235
+
236
+ main.get_layout.add_button("Display InfoBox", {ARG_TEXT_ALIGN => TEXT_ALIGN_CENTER}) do
237
+ add_overlay(create_overlay_widget)
238
+ end
239
+ end
240
+
241
+ def create_overlay_widget
242
+ InfoBox.new(100, 60, 600, 400, "Sample Overlay", overlay_content, { ARG_THEME => WadsBrightTheme.new})
243
+ end
244
+
245
+ def overlay_content
246
+ <<~HEREDOC
247
+ This is a sample overlay widget which typically
248
+ you would use to display important information
249
+ upon request. The InfoBox widget is used for
250
+ this purpose.
251
+ HEREDOC
252
+
253
+ end
254
+ end
255
+
256
+ ThemeTestApp.new.show
@@ -0,0 +1,117 @@
1
+ require 'gosu'
2
+ require_relative '../lib/wads'
3
+
4
+ include Wads
5
+
6
+ AVERAGE_RESPONSE_TIME = 284.to_f # Per humanbenchmark.com, in milliseconds
7
+ GAME_STATE_PROMPT_TO_START = 0
8
+ GAME_STATE_RED = 1
9
+ GAME_STATE_YELLOW = 2
10
+ GAME_STATE_GREEN = 3
11
+ GAME_STATE_OVER = 4
12
+
13
+
14
+ class ReactionTimeApp < WadsApp
15
+ def initialize
16
+ super(600, 400, "Reaction Time Game", ReactionTimeDisplay.new)
17
+ end
18
+ end
19
+
20
+ class ReactionTimeDisplay < Widget
21
+ def initialize
22
+ super(0, 0, 600, 400)
23
+ set_layout(LAYOUT_HEADER_CONTENT)
24
+ set_theme(WadsAquaTheme.new)
25
+ disable_border
26
+ @next_light_count = 0
27
+ @messages = []
28
+ @font = Gosu::Font.new(22)
29
+ @red_light = Gosu::Image.new("media/RedLight.png")
30
+ @yellow_light = Gosu::Image.new("media/YellowLight.png")
31
+ @green_light = Gosu::Image.new("media/GreenLight.png")
32
+ # game state 0 1 2 3 4
33
+ # state Prompt Red Yellow Green Game over
34
+ @traffic_light_images = [@red_light, @red_light, @yellow_light, @green_light, @green_light]
35
+ @traffic_light_color = GAME_STATE_PROMPT_TO_START
36
+
37
+ add_panel(SECTION_NORTH).get_layout.add_text("Reaction Time Game",
38
+ { ARG_TEXT_ALIGN => TEXT_ALIGN_CENTER,
39
+ ARG_USE_LARGE_FONT => true})
40
+
41
+ content_panel = get_layout.add_max_panel({ARG_SECTION => SECTION_CENTER,
42
+ ARG_LAYOUT => LAYOUT_EAST_WEST,
43
+ ARG_THEME => WadsAquaTheme.new,
44
+ ARG_PANEL_WIDTH => 140})
45
+ @traffic_light_image = content_panel.get_layout.add_image(@red_light,
46
+ {ARG_SECTION => SECTION_WEST})
47
+
48
+ left_side_panel = content_panel.add_panel(SECTION_EAST)
49
+ left_side_panel.disable_border
50
+ @start_button = left_side_panel.get_layout.add_button("Click to play") do
51
+ handle_button_click
52
+ end
53
+ @messages = left_side_panel.get_layout.add_document("")
54
+ end
55
+
56
+ def handle_update update_count, mouse_x, mouse_y
57
+ @traffic_light_image.img = @traffic_light_images[@traffic_light_color]
58
+
59
+ if @traffic_light_color == GAME_STATE_PROMPT_TO_START or @traffic_light_color == GAME_STATE_OVER
60
+ @start_button.visible = true
61
+
62
+ elsif @traffic_light_color == GAME_STATE_RED or
63
+ @traffic_light_color == GAME_STATE_YELLOW or
64
+ @traffic_light_color == GAME_STATE_GREEN
65
+ @messages.lines = ["Hit the space bar when the light turns green"]
66
+ @start_button.visible = false
67
+ if @mark_time.nil?
68
+ @mark_time = Time.now
69
+ @next_light_count = update_count + 60 + rand(100)
70
+ end
71
+ next_traffic_light unless update_count < @next_light_count
72
+ end
73
+ end
74
+
75
+ def handle_button_click
76
+ if @traffic_light_color == GAME_STATE_PROMPT_TO_START or @traffic_light_color == GAME_STATE_OVER
77
+ @messages.lines = []
78
+ next_traffic_light
79
+ end
80
+ end
81
+
82
+ def handle_key_press id, mouse_x, mouse_y
83
+ return WidgetResult.new(true) if id == Gosu::KbEscape
84
+
85
+ if id == Gosu::KbSpace
86
+ if @traffic_light_color < GAME_STATE_YELLOW
87
+ next_traffic_light
88
+ elsif @traffic_light_color == GAME_STATE_YELLOW
89
+ @traffic_light_color = GAME_STATE_OVER
90
+ @messages.lines = ["Sorry, you were too early"]
91
+ elsif @traffic_light_color == GAME_STATE_GREEN
92
+ time_since_green = ((Time.now - @mark_time) * 1000.to_f).round(3)
93
+ @messages.lines = ["Response time: #{time_since_green} ms"]
94
+ diff_from_average = (((time_since_green - AVERAGE_RESPONSE_TIME) / AVERAGE_RESPONSE_TIME) * 100).round
95
+ if diff_from_average > 0
96
+ @messages.lines << "#{diff_from_average}% slower than the average human"
97
+ elsif diff_from_average < 0
98
+ @messages.lines << "#{-diff_from_average}% faster than the average human"
99
+ else
100
+ @messages.lines << "Wow, that is exactly the human average."
101
+ end
102
+ @traffic_light_color = GAME_STATE_OVER
103
+ end
104
+ end
105
+ end
106
+
107
+ def next_traffic_light
108
+ if @traffic_light_color == GAME_STATE_OVER
109
+ @traffic_light_color = GAME_STATE_RED
110
+ elsif @traffic_light_color < GAME_STATE_OVER
111
+ @traffic_light_color = @traffic_light_color + 1
112
+ end
113
+ @mark_time = nil
114
+ end
115
+ end
116
+
117
+ ReactionTimeApp.new.show
data/wads.gemspec CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ["lib"]
30
30
 
31
- spec.add_dependency "gosu", "~> 1.1.0"
31
+ spec.add_dependency "gosu", ">= 1.1.0"
32
32
  spec.add_dependency "minigl", "~> 2.3.5"
33
33
  spec.add_dependency "tty-option"
34
34
 
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wads
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - dbroemme
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-16 00:00:00.000000000 Z
11
+ date: 2021-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gosu
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 1.1.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.1.0
27
27
  - !ruby/object:Gem::Dependency
@@ -69,6 +69,7 @@ files:
69
69
  - bin/setup
70
70
  - data/NASDAQ.csv
71
71
  - data/Pick4_12_21_2020.txt
72
+ - data/sample_graph.csv
72
73
  - data/starwars-episode-4-interactions.json
73
74
  - lib/wads.rb
74
75
  - lib/wads/app.rb
@@ -77,11 +78,34 @@ files:
77
78
  - lib/wads/version.rb
78
79
  - lib/wads/widgets.rb
79
80
  - media/Banner.png
81
+ - media/CircleAlpha.png
82
+ - media/CircleAqua.png
83
+ - media/CircleBlue.png
84
+ - media/CircleGray.png
85
+ - media/CircleGreen.png
86
+ - media/CirclePurple.png
87
+ - media/CircleRed.png
88
+ - media/CircleWhite.png
89
+ - media/CircleYellow.png
90
+ - media/GreenLight.png
91
+ - media/RedLight.png
80
92
  - media/SampleGraph.png
81
93
  - media/StocksSample.png
82
94
  - media/WadsScreenshot.png
83
- - run-sample-app
84
- - sample_app.rb
95
+ - media/YellowLight.png
96
+ - run-graph
97
+ - run-star-wars
98
+ - run-stocks
99
+ - run-theme-test
100
+ - samples/basic_gosu_with_graph_widget.rb
101
+ - samples/gosu_bouncing_ball.rb
102
+ - samples/gosu_hello_world.rb
103
+ - samples/gosu_reaction_time.rb
104
+ - samples/graph.rb
105
+ - samples/star_wars.rb
106
+ - samples/stocks.rb
107
+ - samples/theme_test.rb
108
+ - samples/wads_reaction_time.rb
85
109
  - wads.gemspec
86
110
  homepage: https://github.com/dbroemme/ruby-wads
87
111
  licenses: []
@@ -104,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
128
  - !ruby/object:Gem::Version
105
129
  version: '0'
106
130
  requirements: []
107
- rubygems_version: 3.2.15
131
+ rubygems_version: 3.0.3.1
108
132
  signing_key:
109
133
  specification_version: 4
110
134
  summary: Simple, easy to use data structure classes and Gosu widgets
data/run-sample-app DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- ruby sample_app.rb $1 $2 $3 $4 $5 $6 $7 $8 $9
data/sample_app.rb DELETED
@@ -1,64 +0,0 @@
1
- require_relative "lib/wads/app"
2
- require 'tty-option'
3
-
4
- class SampleAppCommand
5
- include TTY::Option
6
-
7
- usage do
8
- program "run-sample-app"
9
-
10
- command ""
11
-
12
- example <<~EOS
13
- Run the sample app to analyze stock market data in gui mode
14
- $ ./run-sample-app -s -g
15
- EOS
16
-
17
- end
18
-
19
- flag :help do
20
- short "-h"
21
- long "--help"
22
- desc "Print usage"
23
- end
24
-
25
- flag :stocks do
26
- short "-s"
27
- long "--stocks"
28
- desc "Run sample stocks analysis"
29
- end
30
-
31
- flag :lottery do
32
- short "-l"
33
- long "--lottery"
34
- desc "Run sample analysis of lottery numbers"
35
- end
36
-
37
- flag :jedi do
38
- short "-j"
39
- long "--jedi"
40
- desc "Run sample analysis of interactions between Star Wars"
41
- end
42
-
43
- flag :graph do
44
- short "-g"
45
- long "--graph"
46
- desc "Run a graph test"
47
- end
48
-
49
- flag :text do
50
- short "-t"
51
- long "--text"
52
- desc "Display text only output"
53
- end
54
-
55
- def run
56
- if params[:help]
57
- print help
58
- exit
59
- end
60
- params.to_h
61
- end
62
- end
63
-
64
- WadsSampleApp.new.parse_opts_and_run