kita 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +13 -0
  5. data/CHANGELOG.md +15 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +8 -0
  8. data/Gemfile.lock +120 -0
  9. data/README.md +1 -0
  10. data/Rakefile +8 -0
  11. data/bin/kita +11 -0
  12. data/kita.gemspec +35 -0
  13. data/lib/kita.rb +160 -0
  14. data/lib/kita/audio.rb +33 -0
  15. data/lib/kita/config.rb +8 -0
  16. data/lib/kita/hiragana.rb +59 -0
  17. data/lib/kita/katakana.rb +59 -0
  18. data/lib/kita/version.rb +5 -0
  19. data/snapcraft.yaml +18 -0
  20. data/sounds/he.ogg +0 -0
  21. data/sounds/he2.ogg +0 -0
  22. data/sounds/tofix.txt +2 -0
  23. data/sounds//343/201/202.ogg +0 -0
  24. data/sounds//343/201/2022.ogg +0 -0
  25. data/sounds//343/201/204.ogg +0 -0
  26. data/sounds//343/201/2042.ogg +0 -0
  27. data/sounds//343/201/206.ogg +0 -0
  28. data/sounds//343/201/2062.ogg +0 -0
  29. data/sounds//343/201/210.ogg +0 -0
  30. data/sounds//343/201/2102.ogg +0 -0
  31. data/sounds//343/201/212.ogg +0 -0
  32. data/sounds//343/201/2122.ogg +0 -0
  33. data/sounds//343/201/213.ogg +0 -0
  34. data/sounds//343/201/2132.ogg +0 -0
  35. data/sounds//343/201/214.ogg +0 -0
  36. data/sounds//343/201/2142.ogg +0 -0
  37. data/sounds//343/201/215.ogg +0 -0
  38. data/sounds//343/201/2152.ogg +0 -0
  39. data/sounds//343/201/216.ogg +0 -0
  40. data/sounds//343/201/2162.ogg +0 -0
  41. data/sounds//343/201/217.ogg +0 -0
  42. data/sounds//343/201/2172.ogg +0 -0
  43. data/sounds//343/201/220.ogg +0 -0
  44. data/sounds//343/201/2202.ogg +0 -0
  45. data/sounds//343/201/221.ogg +0 -0
  46. data/sounds//343/201/2212.ogg +0 -0
  47. data/sounds//343/201/222.ogg +0 -0
  48. data/sounds//343/201/2222.ogg +0 -0
  49. data/sounds//343/201/223.ogg +0 -0
  50. data/sounds//343/201/2232.ogg +0 -0
  51. data/sounds//343/201/223/343/202/214/343/201/257/345/214/227/343/201/247/343/201/231.ogg +0 -0
  52. data/sounds//343/201/224.ogg +0 -0
  53. data/sounds//343/201/2242.ogg +0 -0
  54. data/sounds//343/201/225.ogg +0 -0
  55. data/sounds//343/201/2252.ogg +0 -0
  56. data/sounds//343/201/226.ogg +0 -0
  57. data/sounds//343/201/2262.ogg +0 -0
  58. data/sounds//343/201/227.ogg +0 -0
  59. data/sounds//343/201/2272.ogg +0 -0
  60. data/sounds//343/201/230.ogg +0 -0
  61. data/sounds//343/201/2302.ogg +0 -0
  62. data/sounds//343/201/231.ogg +0 -0
  63. data/sounds//343/201/2312.ogg +0 -0
  64. data/sounds//343/201/232.ogg +0 -0
  65. data/sounds//343/201/2322.ogg +0 -0
  66. data/sounds//343/201/233.ogg +0 -0
  67. data/sounds//343/201/2332.ogg +0 -0
  68. data/sounds//343/201/234.ogg +0 -0
  69. data/sounds//343/201/2342.ogg +0 -0
  70. data/sounds//343/201/235.ogg +0 -0
  71. data/sounds//343/201/2352.ogg +0 -0
  72. data/sounds//343/201/236.ogg +0 -0
  73. data/sounds//343/201/2362.ogg +0 -0
  74. data/sounds//343/201/237.ogg +0 -0
  75. data/sounds//343/201/2372.ogg +0 -0
  76. data/sounds//343/201/240.ogg +0 -0
  77. data/sounds//343/201/2402.ogg +0 -0
  78. data/sounds//343/201/241.ogg +0 -0
  79. data/sounds//343/201/2412.ogg +0 -0
  80. data/sounds//343/201/242.ogg +0 -0
  81. data/sounds//343/201/2422.ogg +0 -0
  82. data/sounds//343/201/244.ogg +0 -0
  83. data/sounds//343/201/2442.ogg +0 -0
  84. data/sounds//343/201/245.ogg +0 -0
  85. data/sounds//343/201/2452.ogg +0 -0
  86. data/sounds//343/201/246.ogg +0 -0
  87. data/sounds//343/201/2462.ogg +0 -0
  88. data/sounds//343/201/247.ogg +0 -0
  89. data/sounds//343/201/2472.ogg +0 -0
  90. data/sounds//343/201/250.ogg +0 -0
  91. data/sounds//343/201/2502.ogg +0 -0
  92. data/sounds//343/201/251.ogg +0 -0
  93. data/sounds//343/201/2512.ogg +0 -0
  94. data/sounds//343/201/252.ogg +0 -0
  95. data/sounds//343/201/2522.ogg +0 -0
  96. data/sounds//343/201/253.ogg +0 -0
  97. data/sounds//343/201/2532.ogg +0 -0
  98. data/sounds//343/201/254.ogg +0 -0
  99. data/sounds//343/201/2542.ogg +0 -0
  100. data/sounds//343/201/255.ogg +0 -0
  101. data/sounds//343/201/2552.ogg +0 -0
  102. data/sounds//343/201/256.ogg +0 -0
  103. data/sounds//343/201/2562.ogg +0 -0
  104. data/sounds//343/201/257.ogg +0 -0
  105. data/sounds//343/201/2572.ogg +0 -0
  106. data/sounds//343/201/260.ogg +0 -0
  107. data/sounds//343/201/2602.ogg +0 -0
  108. data/sounds//343/201/261.ogg +0 -0
  109. data/sounds//343/201/2612.ogg +0 -0
  110. data/sounds//343/201/262.ogg +0 -0
  111. data/sounds//343/201/2622.ogg +0 -0
  112. data/sounds//343/201/263.ogg +0 -0
  113. data/sounds//343/201/2632.ogg +0 -0
  114. data/sounds//343/201/264.ogg +0 -0
  115. data/sounds//343/201/2642.ogg +0 -0
  116. data/sounds//343/201/265.ogg +0 -0
  117. data/sounds//343/201/2652.ogg +0 -0
  118. data/sounds//343/201/266.ogg +0 -0
  119. data/sounds//343/201/2662.ogg +0 -0
  120. data/sounds//343/201/267.ogg +0 -0
  121. data/sounds//343/201/2672.ogg +0 -0
  122. data/sounds//343/201/270.ogg +0 -0
  123. data/sounds//343/201/2702.ogg +0 -0
  124. data/sounds//343/201/271.ogg +0 -0
  125. data/sounds//343/201/2712.ogg +0 -0
  126. data/sounds//343/201/272.ogg +0 -0
  127. data/sounds//343/201/2722.ogg +0 -0
  128. data/sounds//343/201/273.ogg +0 -0
  129. data/sounds//343/201/2732.ogg +0 -0
  130. data/sounds//343/201/274.ogg +0 -0
  131. data/sounds//343/201/2742.ogg +0 -0
  132. data/sounds//343/201/275.ogg +0 -0
  133. data/sounds//343/201/2752.ogg +0 -0
  134. data/sounds//343/201/276.ogg +0 -0
  135. data/sounds//343/201/2762.ogg +0 -0
  136. data/sounds//343/201/277.ogg +0 -0
  137. data/sounds//343/201/2772.ogg +0 -0
  138. data/sounds//343/202/200.ogg +0 -0
  139. data/sounds//343/202/2002.ogg +0 -0
  140. data/sounds//343/202/201.ogg +0 -0
  141. data/sounds//343/202/2012.ogg +0 -0
  142. data/sounds//343/202/202.ogg +0 -0
  143. data/sounds//343/202/2022.ogg +0 -0
  144. data/sounds//343/202/204.ogg +0 -0
  145. data/sounds//343/202/2042.ogg +0 -0
  146. data/sounds//343/202/206.ogg +0 -0
  147. data/sounds//343/202/2062.ogg +0 -0
  148. data/sounds//343/202/210.ogg +0 -0
  149. data/sounds//343/202/2102.ogg +0 -0
  150. data/sounds//343/202/211.ogg +0 -0
  151. data/sounds//343/202/2112.ogg +0 -0
  152. data/sounds//343/202/212.ogg +0 -0
  153. data/sounds//343/202/2122.ogg +0 -0
  154. data/sounds//343/202/213.ogg +0 -0
  155. data/sounds//343/202/2132.ogg +0 -0
  156. data/sounds//343/202/214.ogg +0 -0
  157. data/sounds//343/202/2142.ogg +0 -0
  158. data/sounds//343/202/215.ogg +0 -0
  159. data/sounds//343/202/2152.ogg +0 -0
  160. data/sounds//343/202/217.ogg +0 -0
  161. data/sounds//343/202/2172.ogg +0 -0
  162. data/sounds//343/202/222.ogg +0 -0
  163. data/sounds//343/202/2222.ogg +0 -0
  164. data/sounds//343/202/223.ogg +0 -0
  165. data/sounds//343/202/2232.ogg +0 -0
  166. data/test-notify.rb +33 -0
  167. data/ui/builder.ui +384 -0
  168. data/ui/kita.svg +137 -0
  169. metadata +297 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cc52ea1433292c7a3c9146792e73117217f6d1ab6c640524489c0f22a30158a6
4
+ data.tar.gz: 32f74e1b6261250a6c36a9124f5ac4c5f651f9866c6665c7f949b2b43b50e6f3
5
+ SHA512:
6
+ metadata.gz: 79062cb37ecc657c208445d7a074d8fb3a8bacb32d84b1d5b94f8edbed3423e37e0d56b7cf6ad1563e7fe8daeb764d9838c8214f4d80c10cf66ee2cd70785372
7
+ data.tar.gz: e59ae6841712228838da590cf17eb093a18746f1b0073308d5b0160fa52d6dfd5659e2c649a8e753cf30158dc71f73424d72607d2925f7ff3cb7376b1863d3b7
@@ -0,0 +1,14 @@
1
+ vendor
2
+ *~
3
+ *.gem
4
+ /.bundle/
5
+ /.yardoc
6
+ /_yardoc/
7
+ /coverage/
8
+ /doc/
9
+ /pkg/
10
+ /spec/reports/
11
+ /tmp/
12
+
13
+ # rspec failure tracking
14
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,13 @@
1
+ ---
2
+ # Show URLs for each cop
3
+ AllCops:
4
+ DisplayStyleGuide: true
5
+
6
+ # Disable block-length checks for rspec
7
+ Metrics/BlockLength:
8
+ Exclude:
9
+ - 'spec/**/*.rb'
10
+
11
+ # Extend permitted line length
12
+ Layout/LineLength:
13
+ Max: 120
@@ -0,0 +1,15 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/).
6
+
7
+ ## [Unreleased]
8
+ ### Added
9
+ - Marketing banner to prompt users to upgrade to a free account
10
+
11
+ ### Changed
12
+
13
+ ## 2020-05-24
14
+ ### Added
15
+ - First release
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behaviour that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behaviour by participants include:
24
+
25
+ * The use of sexualised language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behaviour and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behaviour.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviours that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behaviour may be
58
+ reported by contacting the project team at d@nbishop.uk. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [https://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: https://contributor-covenant.org
74
+ [version]: https://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ gem 'rake', '~> 13.0'
8
+ gem 'rspec', '~> 3.9'
@@ -0,0 +1,120 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ atk (3.4.3)
5
+ glib2 (= 3.4.3)
6
+ cairo (1.16.5)
7
+ native-package-installer (>= 1.0.3)
8
+ pkg-config (>= 1.2.2)
9
+ cairo-gobject (3.4.3)
10
+ cairo (>= 1.16.2)
11
+ glib2 (= 3.4.3)
12
+ concurrent-ruby (1.1.6)
13
+ config (2.2.1)
14
+ deep_merge (~> 1.2, >= 1.2.1)
15
+ dry-validation (~> 1.0, >= 1.0.0)
16
+ deep_merge (1.2.1)
17
+ diff-lcs (1.3)
18
+ dry-configurable (0.11.5)
19
+ concurrent-ruby (~> 1.0)
20
+ dry-core (~> 0.4, >= 0.4.7)
21
+ dry-equalizer (~> 0.2)
22
+ dry-container (0.7.2)
23
+ concurrent-ruby (~> 1.0)
24
+ dry-configurable (~> 0.1, >= 0.1.3)
25
+ dry-core (0.4.9)
26
+ concurrent-ruby (~> 1.0)
27
+ dry-equalizer (0.3.0)
28
+ dry-inflector (0.2.0)
29
+ dry-initializer (3.0.3)
30
+ dry-logic (1.0.6)
31
+ concurrent-ruby (~> 1.0)
32
+ dry-core (~> 0.2)
33
+ dry-equalizer (~> 0.2)
34
+ dry-schema (1.5.1)
35
+ concurrent-ruby (~> 1.0)
36
+ dry-configurable (~> 0.8, >= 0.8.3)
37
+ dry-core (~> 0.4)
38
+ dry-equalizer (~> 0.2)
39
+ dry-initializer (~> 3.0)
40
+ dry-logic (~> 1.0)
41
+ dry-types (~> 1.4)
42
+ dry-types (1.4.0)
43
+ concurrent-ruby (~> 1.0)
44
+ dry-container (~> 0.3)
45
+ dry-core (~> 0.4, >= 0.4.4)
46
+ dry-equalizer (~> 0.3)
47
+ dry-inflector (~> 0.1, >= 0.1.2)
48
+ dry-logic (~> 1.0, >= 1.0.2)
49
+ dry-validation (1.5.0)
50
+ concurrent-ruby (~> 1.0)
51
+ dry-container (~> 0.7, >= 0.7.1)
52
+ dry-core (~> 0.4)
53
+ dry-equalizer (~> 0.2)
54
+ dry-initializer (~> 3.0)
55
+ dry-schema (~> 1.5)
56
+ ffi (1.12.2)
57
+ ffi-bit_masks (0.1.1)
58
+ ffi (~> 1.0)
59
+ gdk3 (3.4.3)
60
+ cairo-gobject (= 3.4.3)
61
+ gdk_pixbuf2 (= 3.4.3)
62
+ pango (= 3.4.3)
63
+ gdk_pixbuf2 (3.4.3)
64
+ gio2 (= 3.4.3)
65
+ gio2 (3.4.3)
66
+ gobject-introspection (= 3.4.3)
67
+ gir_ffi (0.15.2)
68
+ ffi (~> 1.8)
69
+ ffi-bit_masks (~> 0.1.1)
70
+ glib2 (3.4.3)
71
+ native-package-installer (>= 1.0.3)
72
+ pkg-config (>= 1.3.5)
73
+ gobject-introspection (3.4.3)
74
+ glib2 (= 3.4.3)
75
+ gstreamer (3.4.3)
76
+ gobject-introspection (= 3.4.3)
77
+ gtk3 (3.4.3)
78
+ atk (= 3.4.3)
79
+ gdk3 (= 3.4.3)
80
+ gdk_pixbuf2 (= 3.4.3)
81
+ gio2 (= 3.4.3)
82
+ pango (= 3.4.3)
83
+ moji (1.6)
84
+ mojinizer (0.2.2)
85
+ moji (~> 1.6)
86
+ native-package-installer (1.0.9)
87
+ pango (3.4.3)
88
+ cairo-gobject (= 3.4.3)
89
+ gobject-introspection (= 3.4.3)
90
+ pkg-config (1.4.1)
91
+ rake (13.0.1)
92
+ rspec (3.9.0)
93
+ rspec-core (~> 3.9.0)
94
+ rspec-expectations (~> 3.9.0)
95
+ rspec-mocks (~> 3.9.0)
96
+ rspec-core (3.9.2)
97
+ rspec-support (~> 3.9.3)
98
+ rspec-expectations (3.9.2)
99
+ diff-lcs (>= 1.2.0, < 2.0)
100
+ rspec-support (~> 3.9.0)
101
+ rspec-mocks (3.9.1)
102
+ diff-lcs (>= 1.2.0, < 2.0)
103
+ rspec-support (~> 3.9.0)
104
+ rspec-support (3.9.3)
105
+
106
+ PLATFORMS
107
+ ruby
108
+
109
+ DEPENDENCIES
110
+ config (~> 2.2)
111
+ gir_ffi (~> 0.15.2)
112
+ gstreamer (~> 3.4)
113
+ gtk3 (~> 3.4)
114
+ mojinizer (~> 0.2.2)
115
+ pango (~> 3.4)
116
+ rake (~> 13.0)
117
+ rspec (~> 3.9)
118
+
119
+ BUNDLED WITH
120
+ 2.1.4
@@ -0,0 +1 @@
1
+ # Kita
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ application_root_path = File.expand_path(__dir__)
5
+ require File.join(application_root_path, '../lib/kita.rb')
6
+
7
+ app = Kita::Application.new
8
+
9
+ app.run
10
+
11
+ Gtk.main
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/kita/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'kita'
7
+ spec.version = Kita::VERSION
8
+ spec.authors = ['Dan Bishop']
9
+ spec.email = ['d@nbishop.uk']
10
+
11
+ spec.summary = 'A Japanese kana learning tool.'
12
+ spec.description = 'A simple tool to help Japanese language learners with hiragana and katakana.'
13
+ spec.homepage = 'https://www.danbishop.org'
14
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
15
+
16
+ spec.metadata['homepage_uri'] = spec.homepage
17
+ spec.metadata['source_code_uri'] = 'https://github.com/danbishop/kita'
18
+ spec.metadata['changelog_uri'] = 'https://github.com/danbishop/kita/blob/master/CHANGELOG.md'
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ end
25
+ spec.bindir = 'bin'
26
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
27
+ spec.require_paths = ['lib']
28
+
29
+ spec.add_dependency 'config', '~> 2.2'
30
+ spec.add_dependency 'gir_ffi', '~> 0.15.2'
31
+ spec.add_dependency 'gstreamer', '~> 3.4'
32
+ spec.add_dependency 'gtk3', '~> 3.4'
33
+ spec.add_dependency 'mojinizer', '~> 0.2.2'
34
+ spec.add_dependency 'pango', '~> 3.4'
35
+ end
@@ -0,0 +1,160 @@
1
+ # frozen_string_literal: true
2
+ require 'gtk3'
3
+ require_relative 'kita/audio'
4
+ require_relative 'kita/config'
5
+ require_relative 'kita/hiragana'
6
+ require_relative 'kita/katakana'
7
+ require_relative 'kita/version'
8
+
9
+ module Kita
10
+ # Main application class
11
+ class Application < Gtk::Application
12
+ def initialize
13
+ super 'uk.danbishop.kita', :handles_open
14
+ builder_file = "#{File.expand_path(File.dirname(__dir__))}/ui/builder.ui"
15
+ # Construct a Gtk::Builder instance and load our UI description
16
+ @builder = Gtk::Builder.new(file: builder_file)
17
+ # Initiate Hiragana class
18
+ @hiragana = Hiragana.new
19
+ # Initiate Katakana class
20
+ @katakana = Katakana.new
21
+ @types = [@hiragana]
22
+ @button_signals = {}
23
+ @sound = Audio.new
24
+ new_question
25
+ menu_setup
26
+ setup_new_question_button
27
+ setup_repeat_button
28
+ build_main_window
29
+ end
30
+
31
+ def menu_setup
32
+ setup_hiragana_switch
33
+ setup_katakana_switch
34
+ setup_sound_switch
35
+ setup_about_box
36
+ end
37
+
38
+ def setup_about_box
39
+ about_box = @builder.get_object('about_box')
40
+ about_button = @builder.get_object('menu_about')
41
+ about_button.signal_connect('clicked') do
42
+ about_box.run
43
+ about_box.hide
44
+ end
45
+ end
46
+
47
+ def setup_new_question_button
48
+ new_question_button = @builder.get_object('new_question')
49
+ new_question_button.signal_connect('clicked') do
50
+ new_question
51
+ end
52
+ end
53
+
54
+ def setup_repeat_button
55
+ new_question_button = @builder.get_object('speak')
56
+ new_question_button.signal_connect('clicked') do
57
+ @sound.repeat
58
+ end
59
+ end
60
+
61
+ def setup_hiragana_switch
62
+ @hiragana_switch = @builder.get_object('hiragana_switch')
63
+ @hiragana_switch.signal_connect('notify::active') do
64
+ toggle_hiragana
65
+ end
66
+ end
67
+
68
+ def setup_katakana_switch
69
+ @katakana_switch = @builder.get_object('katakana_switch')
70
+ @katakana_switch.signal_connect('notify::active') do
71
+ toggle_katakana
72
+ end
73
+ end
74
+
75
+ def setup_sound_switch
76
+ @sound_switch = @builder.get_object('sound_switch')
77
+ @sound_switch.signal_connect('notify::active') do
78
+ toggle_sound
79
+ end
80
+ end
81
+
82
+ def toggle_katakana
83
+ # TODO: Switch this to using Settings
84
+ @types = []
85
+ @types << @hiragana if @hiragana_switch.active?
86
+ @types << @katakana if @katakana_switch.active?
87
+ (@hiragana_switch.set_active(true) && @types = [@hiragana]) if @types.empty?
88
+ end
89
+
90
+ def toggle_hiragana
91
+ # TODO: Switch this to using Settings
92
+ @types = []
93
+ @types << @hiragana if @hiragana_switch.active?
94
+ @types << @katakana if @katakana_switch.active?
95
+ (@katakana_switch.set_active(true) && @types = [@katakana]) if @types.empty?
96
+ end
97
+
98
+ def toggle_sound
99
+ Settings.speak = !Settings.speak
100
+ end
101
+
102
+ def build_main_window
103
+ signal_connect :activate do
104
+ # Connect signal handlers to the constructed widgets
105
+ window = @builder.get_object('window')
106
+ window.signal_connect('destroy') { Gtk.main_quit }
107
+ window.present
108
+ end
109
+ end
110
+
111
+ def new_question
112
+ reset_buttons
113
+ question = @types.sample.question
114
+ question_label = @builder.get_object('question')
115
+ question_label.set_markup("<span font='72'>#{question[:question]}</span>")
116
+ buttons = %w[a b c d]
117
+ correct_button(buttons, question)
118
+ wrong_buttons(buttons, question)
119
+ puts "Playing: #{question[:question].hiragana}"
120
+ @sound.play(question[:question].hiragana) if Settings.speak
121
+ end
122
+
123
+ def correct_button(buttons, question)
124
+ # Choose random letter and remove it from array
125
+ correct = buttons.delete(buttons.sample)
126
+ correct_button = @builder.get_object("answer_#{correct}")
127
+ correct_button.set_label(question[:answer])
128
+ correct_signal = correct_button.signal_connect('clicked') do
129
+ new_question
130
+ end
131
+ @button_signals[correct] = correct_signal
132
+ end
133
+
134
+ def wrong_buttons(buttons, question)
135
+ buttons.each_with_index do |letter, i|
136
+ button = @builder.get_object("answer_#{letter}")
137
+ button.set_label(question[:choices][i])
138
+ signal = button.signal_connect('clicked') { wrong_button_click(button) }
139
+ @button_signals[letter] = signal
140
+ end
141
+ end
142
+
143
+ def wrong_button_click(button)
144
+ button.set_sensitive(false)
145
+ label = button.child
146
+ label.set_markup("<span color='#d40000'>#{button.label} #{button.label.hiragana}</span>")
147
+ end
148
+
149
+ def reset_buttons
150
+ return nil if @button_signals.empty?
151
+
152
+ @button_signals.each do |letter, signal|
153
+ button = @builder.get_object("answer_#{letter}")
154
+ button.signal_handler_disconnect(signal)
155
+ button.set_sensitive(true)
156
+ end
157
+ @button_signals = {}
158
+ end
159
+ end
160
+ end