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.
- data/README +70 -0
- data/Rakefile +13 -0
- data/TODO +4 -0
- data/VERSION +1 -0
- data/bin/simple_gui_creator +88 -0
- data/examples/absolute_positioning.rb +12 -0
- data/ext/jl1.0.1.jar +0 -0
- data/lib/simple_gui_creator/drive_info.rb +162 -0
- data/lib/simple_gui_creator/mouse_control.rb +149 -0
- data/lib/simple_gui_creator/parse_template.rb +207 -0
- data/lib/simple_gui_creator/play_audio.rb +79 -0
- data/lib/simple_gui_creator/play_mp3_audio.rb +42 -0
- data/lib/simple_gui_creator/ruby_clip.rb +33 -0
- data/lib/simple_gui_creator/simple_gui_creator.rb +542 -0
- data/lib/simple_gui_creator/storage.rb +124 -0
- data/lib/simple_gui_creator.rb +18 -0
- data/spec/common.rb +5 -0
- data/spec/diesel.mp3 +0 -0
- data/spec/drive_info.spec.rb +75 -0
- data/spec/mouse.spec.rb +67 -0
- data/spec/parse_template.spec.rb +179 -0
- data/spec/play_mp3_audio.spec.rb +31 -0
- data/spec/ruby_clip.spec.rb +11 -0
- data/spec/run_drive_info.rb +4 -0
- data/spec/static.wav +0 -0
- data/spec/swing_helpers.spec.rb +140 -0
- data/vendor/dvdid.exe +0 -0
- data/vendor/mac_dvdid/bin/dvdid +0 -0
- data/vendor/mac_dvdid/include/dvdid/dvdid.h +67 -0
- data/vendor/mac_dvdid/include/dvdid/dvdid2.h +131 -0
- data/vendor/mac_dvdid/include/dvdid/export.h +32 -0
- data/vendor/mac_dvdid/lib/libdvdid.0.dylib +0 -0
- data/vendor/mac_dvdid/lib/libdvdid.a +0 -0
- data/vendor/mac_dvdid/lib/libdvdid.dylib +0 -0
- data/vendor/mac_dvdid/lib/libdvdid.la +41 -0
- metadata +110 -0
@@ -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
|