simple_gui_creator 0.1.0

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,207 @@
1
+ require 'java'
2
+
3
+ require File.dirname(__FILE__) + '/simple_gui_creator.rb' # for JFrame#close, etc., basically required as of today..
4
+
5
+ # for docs, see the README/specs
6
+ module ParseTemplate
7
+
8
+ def _dgb
9
+ require 'rubygems'
10
+ require 'ruby-debug'
11
+ debugger
12
+ end
13
+
14
+ include_package 'javax.swing'; [JFrame, JPanel, JButton, JTextArea, JLabel, UIManager, JScrollPane]
15
+ java_import java.awt.Font
16
+
17
+ class JFramer < JFrame
18
+
19
+ def initialize
20
+ super()
21
+ @panel = JPanel.new
22
+ @elements = {}
23
+ @panel.set_layout nil
24
+ add @panel # why can't I just slap these down? panel? huh?
25
+ show # this always bites me...I new it up an it just doesn't appear...
26
+ end
27
+
28
+ attr_reader :panel
29
+ attr_reader :elements
30
+ attr_accessor :original_title
31
+ attr_accessor :frame
32
+
33
+ def parse_setup_filename filename
34
+ parse_setup_string File.read(filename)
35
+ self
36
+ end
37
+
38
+ # "matches" whatever the template string looks like...
39
+ def parse_setup_string string
40
+ @frame = self # LODO refactor
41
+ @current_y = 10
42
+ @window_max_x = 100
43
+ all_lines = string.lines.to_a
44
+ all_lines.each_with_index{|line, idx|
45
+ begin
46
+ @current_x = 10
47
+ if line =~ /\t/
48
+ raise "sorry, tabs arent allowed, but you can request it"
49
+ end
50
+ button_line_regex = /\[(.*?)\]/
51
+ #>> "| [Setup Preferences:preferences] [Start:start] [Stop:stop] |" .scan button_line_regex
52
+ #=> [["Setup Preferences:preferences"], ["Start:start"], ["Stop:stop"]]
53
+
54
+ text_regex = /"([^"]+)"/ # "some text:name"
55
+ blank_line_regex = /^\s*(|\|)\s+(|\|)\s*$/ # " | | " or just empty...
56
+ title_regex = /\s*[-]+([\w ]+)[-]+\s*$/ # ----(a Title)---
57
+ @current_line_height = 25
58
+
59
+ if line =~ title_regex
60
+ @frame.set_title $1 # done :)
61
+ @frame.original_title = $1.dup.freeze # freeze...LOL
62
+ elsif line =~ blank_line_regex
63
+ @current_y += @current_line_height
64
+ elsif line =~ button_line_regex
65
+ # button, or TextArea
66
+ cur_x = 0
67
+ while cur_spot = (line[cur_x..-1] =~ button_line_regex)
68
+ cur_spot += cur_x# we had only acted on a partial line, above, so add in the part we didn't do
69
+ name = $1
70
+ end_spot = cur_spot + name.length
71
+ count_lines_below = 0
72
+ matching_blank_text_area_string = '[' + ' '*(end_spot-cur_spot) + ']'
73
+ empty_it_out = matching_blank_text_area_string.gsub(/[\[\]]/, '_') # can't actually blank it out...
74
+ for line2 in all_lines[idx+1..-1]
75
+ if line2[cur_spot..(end_spot+1)] == matching_blank_text_area_string
76
+ line2[cur_spot, end_spot-cur_spot+2] = empty_it_out # :)
77
+ count_lines_below += 1
78
+ else
79
+ break
80
+ end
81
+ end
82
+ if count_lines_below > 0
83
+ rows = count_lines_below + 1
84
+ text_area = JTextArea.new(rows, name.split(':')[0].length)
85
+ text_area.text="\n"*rows
86
+ # width?
87
+ scrollPane = JScrollPane.new(text_area)
88
+ setup_element(scrollPane, name, scrollPane.getPreferredSize.height, text_area)
89
+ else
90
+ button = JButton.new
91
+ setup_element(button, name)
92
+ end
93
+ cur_x = end_spot # creep forward within this line...
94
+ end
95
+ @current_y += @current_line_height
96
+ elsif line =~ text_regex
97
+ for name in line.scan(text_regex)
98
+ label = JLabel.new
99
+ setup_element(label, name[0])
100
+ end
101
+ @current_y += @current_line_height
102
+ end
103
+ # build in realtime LOL
104
+ @frame.set_size @window_max_x + 25, @current_y + 40
105
+ rescue
106
+ puts "Parsing failed on line #{line.inspect} number: #{idx+1}!"
107
+ raise
108
+ end
109
+ }
110
+ self
111
+ end
112
+
113
+ private
114
+
115
+ def get_text_width text
116
+ get_text_dimentia(text).width
117
+ end
118
+
119
+ def get_text_dimentia text
120
+ font = UIManager.getFont("Label.font")
121
+ frc = java.awt.font.FontRenderContext.new(font.transform, true, true)
122
+ textLayout = java.awt.font.TextLayout.new(text, font, frc)
123
+ textLayout.bounds # has #height and #width
124
+ end
125
+
126
+ def setup_element element, name, height=nil, set_text_on_this = element
127
+ abs_x = nil
128
+ abs_y = nil
129
+ #height = nil
130
+ width = nil
131
+ if name.include?(':') && !name.end_with?(':') # like "Start:start_button" or "start:button:code_name,attribs" but not "Hello:" let that through
132
+ text = name.split(':')[0..-2].join(':') # only accept last colon, so they can have text with colons in it
133
+ code_name_with_attrs = name.split(':')[-1]
134
+ if code_name_with_attrs.split(',')[0] !~ /=/
135
+ # like code_name,width=250,x=y
136
+ code_name, *attributes = code_name_with_attrs.split(',')
137
+ else
138
+ code_name = nil
139
+ attributes = code_name_with_attrs.split(',')
140
+ end
141
+ attributes_hashed = {}
142
+ attributes.each{|attr|
143
+ key, value = attr.split('=')
144
+ attributes_hashed[key.strip] = value.strip
145
+ }
146
+ if type = attributes_hashed.delete('font')
147
+ if type == "fixed_width"
148
+ set_text_on_this.font=Font.new("Monospaced", Font::PLAIN, 14)
149
+ else
150
+ raise "all we support is fixed_width font as of yet #{type} #{name}"
151
+ end
152
+ end
153
+
154
+ for name in ['abs_x', 'abs_y', 'width', 'height']
155
+ var = attributes_hashed.delete(name)
156
+ if var
157
+ if var =~ /chars$/
158
+ count = var[0..-5].to_i
159
+ var = get_text_width('m'*count) # TODO fails for height 30chars
160
+ elsif var =~ /px$/
161
+ var = var[0..-3].to_i
162
+ else
163
+ #raise "need to specify like 10px #{var} #{name}"
164
+ var = var.to_i # allow it to be clean :P
165
+ end
166
+ raise "#{var} has value of zero?" if var == 0
167
+ eval("#{name} = #{var}") # ugh
168
+ end
169
+ end
170
+ raise "unknown attributes found: #{attributes_hashed.keys.inspect} #{attributes_hashed.inspect} #{code_name}" if attributes_hashed.length > 0
171
+ else
172
+ # no code name
173
+ text = name
174
+ end
175
+ if !width
176
+ if text.blank?
177
+ raise 'cannot have blank original text without some size specifier:' + name
178
+ end
179
+ if text.strip != text
180
+ # let blank space count as "space" for now, but don't actually set it LOL
181
+ # is this good for variable spaced fonts, though?
182
+ width = get_text_width("|" + text + "|") + 35
183
+ text.strip!
184
+ else
185
+ width = get_text_width(text) + 35
186
+ end
187
+ end
188
+ set_text_on_this.text=text
189
+ abs_x ||= @current_x
190
+ abs_y ||= @current_y
191
+ height ||= 20
192
+ element.set_bounds(abs_x, abs_y, width, height)
193
+ @frame.panel.add element
194
+ if code_name
195
+ code_name.rstrip!
196
+ raise "double name not allowed #{name} #{code_name}" if @frame.elements[code_name.to_sym]
197
+ @frame.elements[code_name.to_sym] = set_text_on_this # just symbol access for now...
198
+ end
199
+ @current_x = [@current_x, abs_x + width + 5].max
200
+ @current_line_height = [@current_line_height, (abs_y + height + 5)-@current_y].max # LODO + 5 magic number? 25 - 20 hard coded? hmm...
201
+
202
+ @window_max_x = [@window_max_x, @current_x].max # have to track x, but not y
203
+ end
204
+
205
+ end
206
+
207
+ end
@@ -0,0 +1,79 @@
1
+ require 'java'
2
+
3
+ # only plays wav/pcm and midi
4
+
5
+ class PlayAudio
6
+ include_package 'javax.sound.sampled'
7
+ import java.io.File;
8
+ import java.io.IOException;
9
+ Type = javax.sound.sampled.LineEvent::Type
10
+
11
+ def initialize filename
12
+ raise 'no filename?' unless filename
13
+ @filename = filename
14
+ @done = false
15
+ end
16
+
17
+ def warmup
18
+ @audioInputStream = AudioSystem.getAudioInputStream(java.io.File.new @filename)
19
+ @clip = AudioSystem.getClip
20
+ @done = false
21
+ @clip.add_line_listener { |line_event|
22
+ if (line_event.get_type == Type::STOP || line_event.get_type == Type::CLOSE)
23
+ @done = true;
24
+ shutdown
25
+ end
26
+ }
27
+ @clip.open(@audioInputStream)
28
+ end
29
+
30
+ def start
31
+ warmup
32
+ @clip.start
33
+ end
34
+
35
+ alias play_non_blocking start
36
+
37
+ def loop
38
+ warmup
39
+ @clip.loop(Clip::LOOP_CONTINUOUSLY)
40
+ end
41
+
42
+ def join_finish
43
+ while !@done
44
+ sleep 0.01
45
+ end
46
+ end
47
+
48
+ def play_till_end
49
+ start
50
+ join_finish
51
+ end
52
+
53
+ def shutdown
54
+ @clip.close
55
+ @audioInputStream.close
56
+ end
57
+
58
+ def stop
59
+ @done = true
60
+ shutdown
61
+ end
62
+ end
63
+
64
+ if $0 == __FILE__
65
+ p = PlayAudio.new ARGV[0]
66
+ p.start
67
+ p 'playing'
68
+ sleep 2
69
+ p.stop
70
+ p.join_finish
71
+ p 'silence'
72
+ sleep 2
73
+ p 'looping'
74
+ p.loop
75
+ sleep 2
76
+ p.stop
77
+ p 'silence'
78
+ sleep 2
79
+ end
@@ -0,0 +1,42 @@
1
+ # translation from http://introcs.cs.princeton.edu/java/faq/mp3/MP3.java.html
2
+
3
+ require 'java'
4
+ require File.dirname(__FILE__) + '/../../ext/jl1.0.1.jar' # third party jlayer mp3 jar <sigh>
5
+
6
+ class PlayMp3Audio
7
+ java_import "javazoom.jl.player.Player"
8
+
9
+ def initialize filename # does not work with .wav, unfortunately...
10
+ @filename = filename
11
+ end
12
+
13
+ def start
14
+ raise 'file not found?' unless File.exist? @filename
15
+ fis = java.io.FileInputStream.new(@filename)
16
+ bstream = java.io.BufferedInputStream.new(fis)
17
+ @player = Player.new(bstream)
18
+ @thread = Thread.new {
19
+ @player.play
20
+ }
21
+ end
22
+
23
+ def join
24
+ @thread.join
25
+ end
26
+
27
+ def play_till_end
28
+ start
29
+ join
30
+ end
31
+
32
+ alias play_non_blocking start
33
+
34
+ def stop
35
+ if @player
36
+ @player.close # at least they give us this method yikes
37
+ @player = nil
38
+ end
39
+ # raising here means you didn't call
40
+ end
41
+
42
+ end
@@ -0,0 +1,33 @@
1
+ require 'java'
2
+
3
+ class RubyClip
4
+ import java.awt.datatransfer.StringSelection;
5
+ import java.awt.Toolkit;
6
+
7
+ include java.awt.datatransfer.ClipboardOwner
8
+
9
+ def self.set_clipboard to_this
10
+ stringSelection = StringSelection.new( to_this.to_s )
11
+ clipboard = Toolkit.getDefaultToolkit().getSystemClipboard()
12
+ clipboard.setContents( stringSelection, self );
13
+ end
14
+
15
+ def self.lostOwnership(aClipboard, aContents)
16
+ # ignore...
17
+ end
18
+
19
+ def self.get_clipboard_contents
20
+ clipboard = Toolkit.getDefaultToolkit().getSystemClipboard()
21
+ data = clipboard.get_contents self
22
+ data.getTransferData java.awt.datatransfer.DataFlavor::stringFlavor
23
+ end
24
+
25
+ end
26
+
27
+ if $0 == __FILE__
28
+ RubyClip.set_clipboard "from jruby1"
29
+ puts 'set clipboard contents...'
30
+ RubyClip.set_clipboard "from jruby2"
31
+ RubyClip.set_clipboard "from jruby3"
32
+ STDIN.getc
33
+ end