wads 0.1.2 → 0.2.2

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.
@@ -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
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wads
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.2
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-07 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
@@ -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,9 +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
92
+ - media/SampleGraph.png
93
+ - media/StocksSample.png
80
94
  - media/WadsScreenshot.png
81
- - run-sample-app
82
- - 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
83
109
  - wads.gemspec
84
110
  homepage: https://github.com/dbroemme/ruby-wads
85
111
  licenses: []
@@ -102,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
128
  - !ruby/object:Gem::Version
103
129
  version: '0'
104
130
  requirements: []
105
- rubygems_version: 3.2.15
131
+ rubygems_version: 3.2.22
106
132
  signing_key:
107
133
  specification_version: 4
108
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