purple_shoes 0.0.101
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.md +56 -0
- data/VERSION +1 -0
- data/bin/pshoes +23 -0
- data/bin/pshoes.bat +2 -0
- data/lib/plugins/video.rb +88 -0
- data/lib/purple_shoes.rb +51 -0
- data/lib/shoes/anim.rb +47 -0
- data/lib/shoes/app.rb +688 -0
- data/lib/shoes/basic.rb +254 -0
- data/lib/shoes/colors.rb +149 -0
- data/lib/shoes/download.rb +26 -0
- data/lib/shoes/help.rb +473 -0
- data/lib/shoes/helper_methods.rb +295 -0
- data/lib/shoes/main.rb +96 -0
- data/lib/shoes/manual.rb +6 -0
- data/lib/shoes/ruby.rb +61 -0
- data/lib/shoes/slot.rb +104 -0
- data/lib/shoes/style.rb +41 -0
- data/lib/shoes/text.rb +46 -0
- data/lib/shoes/url.rb +14 -0
- data/lib/shoes/widget.rb +23 -0
- data/samples/class-book.yaml +387 -0
- data/samples/cy.png +0 -0
- data/samples/loogink.png +0 -0
- data/samples/potato_chopping/1258_s001.gif +0 -0
- data/samples/potato_chopping/1258_s002.gif +0 -0
- data/samples/potato_chopping/1258_s003.gif +0 -0
- data/samples/potato_chopping/1258_s004.gif +0 -0
- data/samples/potato_chopping/1258_s005.gif +0 -0
- data/samples/potato_chopping/1258_s006.gif +0 -0
- data/samples/potato_chopping/1258_s007.gif +0 -0
- data/samples/potato_chopping/1258_s008.gif +0 -0
- data/samples/potato_chopping/1258_s009.gif +0 -0
- data/samples/potato_chopping/1258_s010.gif +0 -0
- data/samples/potato_chopping/1258_s011.gif +0 -0
- data/samples/potato_chopping/1258_s012.gif +0 -0
- data/samples/potato_chopping/1258_s013.gif +0 -0
- data/samples/potato_chopping/1258_s014.gif +0 -0
- data/samples/potato_chopping/1258_s015.gif +0 -0
- data/samples/potato_chopping/1258_s016.gif +0 -0
- data/samples/potato_chopping/1258_s017.gif +0 -0
- data/samples/potato_chopping/1258_s018.gif +0 -0
- data/samples/potato_chopping/1258_s019.gif +0 -0
- data/samples/potato_chopping/1258_s020.gif +0 -0
- data/samples/potato_chopping/1258_s021.gif +0 -0
- data/samples/potato_chopping/1258_s022.gif +0 -0
- data/samples/potato_chopping/1258_s023.gif +0 -0
- data/samples/potato_chopping/1258_s024.gif +0 -0
- data/samples/potato_chopping/1258_s025.gif +0 -0
- data/samples/potato_chopping/1258_s026.gif +0 -0
- data/samples/potato_chopping/1258_s027.gif +0 -0
- data/samples/potato_chopping/1258_s028.gif +0 -0
- data/samples/potato_chopping/1258_s029.gif +0 -0
- data/samples/potato_chopping/1258_s030.gif +0 -0
- data/samples/potato_chopping/1258_s031.gif +0 -0
- data/samples/potato_chopping/1258_s032.gif +0 -0
- data/samples/potato_chopping/1258_s033.gif +0 -0
- data/samples/potato_chopping/1258_s034.gif +0 -0
- data/samples/potato_chopping/1258_s035.gif +0 -0
- data/samples/potato_chopping/1258_s036.gif +0 -0
- data/samples/potato_chopping/1258_s037.gif +0 -0
- data/samples/potato_chopping/1258_s038.gif +0 -0
- data/samples/potato_chopping/1258_s039.gif +0 -0
- data/samples/potato_chopping/1258_s040.gif +0 -0
- data/samples/potato_chopping/1258_s041.gif +0 -0
- data/samples/potato_chopping/1258_s042.gif +0 -0
- data/samples/potato_chopping/1258_s043.gif +0 -0
- data/samples/potato_chopping/1258_s044.gif +0 -0
- data/samples/potato_chopping/1258_s045.gif +0 -0
- data/samples/potato_chopping/1258_s046.gif +0 -0
- data/samples/potato_chopping/1258_s047.gif +0 -0
- data/samples/potato_chopping/1258_s048.gif +0 -0
- data/samples/potato_chopping/1258_s049.gif +0 -0
- data/samples/potato_chopping/1258_s050.gif +0 -0
- data/samples/potato_chopping/1258_s051.gif +0 -0
- data/samples/potato_chopping/1258_s052.gif +0 -0
- data/samples/potato_chopping/1258_s053.gif +0 -0
- data/samples/potato_chopping/1258_s054.gif +0 -0
- data/samples/potato_chopping/1258_s055.gif +0 -0
- data/samples/potato_chopping/1258_s056.gif +0 -0
- data/samples/potato_chopping/1258_s057.gif +0 -0
- data/samples/potato_chopping/1258_s058.gif +0 -0
- data/samples/potato_chopping/1258_s059.gif +0 -0
- data/samples/sample1.rb +30 -0
- data/samples/sample10.rb +11 -0
- data/samples/sample11.rb +12 -0
- data/samples/sample12.rb +22 -0
- data/samples/sample13.rb +15 -0
- data/samples/sample14.rb +75 -0
- data/samples/sample15.rb +20 -0
- data/samples/sample16.rb +12 -0
- data/samples/sample17.rb +12 -0
- data/samples/sample18.rb +24 -0
- data/samples/sample19.rb +39 -0
- data/samples/sample2.rb +16 -0
- data/samples/sample20.rb +26 -0
- data/samples/sample21.rb +7 -0
- data/samples/sample22.rb +13 -0
- data/samples/sample23.rb +10 -0
- data/samples/sample24.rb +22 -0
- data/samples/sample25.rb +22 -0
- data/samples/sample27.rb +19 -0
- data/samples/sample28.rb +64 -0
- data/samples/sample29.rb +12 -0
- data/samples/sample3.rb +10 -0
- data/samples/sample30.rb +30 -0
- data/samples/sample31.rb +24 -0
- data/samples/sample34.rb +29 -0
- data/samples/sample35.rb +33 -0
- data/samples/sample36.rb +48 -0
- data/samples/sample37.rb +10 -0
- data/samples/sample38.rb +14 -0
- data/samples/sample4.rb +9 -0
- data/samples/sample40.rb +19 -0
- data/samples/sample42.rb +15 -0
- data/samples/sample43.rb +26 -0
- data/samples/sample44.rb +57 -0
- data/samples/sample45.rb +12 -0
- data/samples/sample46.rb +35 -0
- data/samples/sample47.rb +20 -0
- data/samples/sample48.rb +33 -0
- data/samples/sample49.rb +33 -0
- data/samples/sample5.rb +8 -0
- data/samples/sample50.rb +326 -0
- data/samples/sample58.rb +19 -0
- data/samples/sample6.rb +11 -0
- data/samples/sample7.rb +5 -0
- data/samples/sample8.rb +9 -0
- data/samples/sample9.rb +12 -0
- data/samples/sample99.rb +4 -0
- data/samples/sounds/102719__sarge4267__explosion.mp3 +0 -0
- data/samples/sounds/145622__andybrannan__train-fog-horn-long-wyomming.aiff +0 -0
- data/samples/sounds/46492__phreaksaccount__shields1.ogg +0 -0
- data/samples/sounds/61847__simon-rue__boink-v3.wav +0 -0
- data/snapshots/sample1.png +0 -0
- data/snapshots/sample10.png +0 -0
- data/snapshots/sample11.png +0 -0
- data/snapshots/sample12.png +0 -0
- data/snapshots/sample13.png +0 -0
- data/snapshots/sample14.png +0 -0
- data/snapshots/sample15.png +0 -0
- data/snapshots/sample16.png +0 -0
- data/snapshots/sample17.png +0 -0
- data/snapshots/sample18.png +0 -0
- data/snapshots/sample19.png +0 -0
- data/snapshots/sample2.png +0 -0
- data/snapshots/sample20.png +0 -0
- data/snapshots/sample21.png +0 -0
- data/snapshots/sample22.png +0 -0
- data/snapshots/sample23.png +0 -0
- data/snapshots/sample24.png +0 -0
- data/snapshots/sample25.png +0 -0
- data/snapshots/sample27.png +0 -0
- data/snapshots/sample28.png +0 -0
- data/snapshots/sample29.png +0 -0
- data/snapshots/sample3-osx.png +0 -0
- data/snapshots/sample3.png +0 -0
- data/snapshots/sample30.png +0 -0
- data/snapshots/sample31.png +0 -0
- data/snapshots/sample33.png +0 -0
- data/snapshots/sample34.png +0 -0
- data/snapshots/sample35.png +0 -0
- data/snapshots/sample36.png +0 -0
- data/snapshots/sample37.png +0 -0
- data/snapshots/sample38.png +0 -0
- data/snapshots/sample4.png +0 -0
- data/snapshots/sample40.png +0 -0
- data/snapshots/sample42.png +0 -0
- data/snapshots/sample43.png +0 -0
- data/snapshots/sample44-linux.png +0 -0
- data/snapshots/sample44.png +0 -0
- data/snapshots/sample45.png +0 -0
- data/snapshots/sample46.png +0 -0
- data/snapshots/sample47.png +0 -0
- data/snapshots/sample48.png +0 -0
- data/snapshots/sample49.png +0 -0
- data/snapshots/sample5.png +0 -0
- data/snapshots/sample50.png +0 -0
- data/snapshots/sample58.png +0 -0
- data/snapshots/sample6.png +0 -0
- data/snapshots/sample7.png +0 -0
- data/snapshots/sample8.png +0 -0
- data/snapshots/sample9.png +0 -0
- data/snapshots/sample99.png +0 -0
- data/static/code_highlighter.js +188 -0
- data/static/code_highlighter_ruby.js +26 -0
- data/static/man-editor-notepad.png +0 -0
- data/static/man-editor-osx.png +0 -0
- data/static/man-ele-background.png +0 -0
- data/static/man-ele-border.png +0 -0
- data/static/man-ele-button.png +0 -0
- data/static/man-ele-check.png +0 -0
- data/static/man-ele-editbox.png +0 -0
- data/static/man-ele-editline.png +0 -0
- data/static/man-ele-image.png +0 -0
- data/static/man-ele-listbox.png +0 -0
- data/static/man-ele-progress.png +0 -0
- data/static/man-ele-radio.png +0 -0
- data/static/man-ele-shape.png +0 -0
- data/static/man-ele-textblock.png +0 -0
- data/static/man-ele-video.png +0 -0
- data/static/man-shot1.png +0 -0
- data/static/manual-en.txt +3969 -0
- data/static/manual-ja.txt +3882 -0
- data/static/manual.css +184 -0
- data/static/purple_shoes-icon.png +0 -0
- data/static/rshoes-icon.png +0 -0
- data/static/shoes-manual-apps.png +0 -0
- data/static/sound_jars/jl1.0.1.jar +0 -0
- data/static/sound_jars/jogg-0.0.7.jar +0 -0
- data/static/sound_jars/jorbis-0.0.15.jar +0 -0
- data/static/sound_jars/mp3spi1.9.5.jar +0 -0
- data/static/sound_jars/tritonus_share.jar +0 -0
- data/static/sound_jars/vorbisspi1.0.3.jar +0 -0
- metadata +271 -0
data/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Purple Shoes
|
|
2
|
+
==========
|
|
3
|
+
|
|
4
|
+
Porting [Green Shoes](https://github.com/ashbb/green_shoes) with **JRuby** and **SWT**.
|
|
5
|
+
|
|
6
|
+
Install JRuby and Purple Shoes for Windows
|
|
7
|
+
-----------------------------------------
|
|
8
|
+
|
|
9
|
+
- download and install [JRuby 1.6.7 Windows Executable](http://jruby.org/download)
|
|
10
|
+
- jruby --1.9 -S gem install purple_shoes
|
|
11
|
+
|
|
12
|
+
The [swt](http://rubygems.org/gems/swt) gem will be installed automatically.
|
|
13
|
+
|
|
14
|
+
Install JRuby and Purple Shoes for Linux and OS X
|
|
15
|
+
-----------------------------------------------
|
|
16
|
+
|
|
17
|
+
- install [rvm](http://beginrescueend.com/)
|
|
18
|
+
- rvm install jruby
|
|
19
|
+
- gem install purple_shoes
|
|
20
|
+
|
|
21
|
+
Look at the command line help
|
|
22
|
+
-----------------------------
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
jruby --1.9 -S pshoes -h
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
<pre>
|
|
29
|
+
Usage: pshoes (options or app.rb)
|
|
30
|
+
-m, -men Open the built-in English manual.
|
|
31
|
+
-mjp Open the built-in Japanese manual.
|
|
32
|
+
-v Display the version info.
|
|
33
|
+
-h Show this message.
|
|
34
|
+
</pre>
|
|
35
|
+
|
|
36
|
+
**Note**: If you set an environment variable like this: `set JRUBY_OPTS=--1.9`, you can do just only `pshoes -h`.
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
Note to OSX Users
|
|
40
|
+
-----------------
|
|
41
|
+
|
|
42
|
+
You'll need to pass an extra argument to JRuby's JVM for SWT to work on OSX. Your command line should look like this:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
jruby -J-XstartOnFirstThread --1.9 sample2.rb
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
Open the built-in manual
|
|
50
|
+
-----------------------
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
jruby --1.9 -S pshoes -m
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+

|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.0.101
|
data/bin/pshoes
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require File.dirname(__FILE__) + '/../lib/purple_shoes'
|
|
3
|
+
|
|
4
|
+
arg = ARGV[0]
|
|
5
|
+
path = File.expand_path(arg.gsub(/\\/, "/")) if arg
|
|
6
|
+
ARGV[0] = path
|
|
7
|
+
|
|
8
|
+
case arg
|
|
9
|
+
when '-m', '-men'
|
|
10
|
+
Shoes.show_manual
|
|
11
|
+
when '-mjp'
|
|
12
|
+
Shoes.show_manual 'Japanese'
|
|
13
|
+
when '-h', nil
|
|
14
|
+
puts "Usage: pshoes (options or app.rb)
|
|
15
|
+
-m, -men Open the built-in English manual.
|
|
16
|
+
-mjp Open the built-in Japanese manual.
|
|
17
|
+
-v Display the version info.
|
|
18
|
+
-h Show this message."
|
|
19
|
+
when '-v'
|
|
20
|
+
puts IO.read File.join(DIR, '../VERSION')
|
|
21
|
+
else
|
|
22
|
+
load path
|
|
23
|
+
end
|
data/bin/pshoes.bat
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Original code was written by pjfitzgibbons (Peter Fitzgibbons) in Brown Shoes
|
|
2
|
+
# Edited a little bit for Purple Shoes by ashbb
|
|
3
|
+
|
|
4
|
+
require File.join(DIR, '../static/sound_jars/tritonus_share.jar')
|
|
5
|
+
require File.join(DIR, '../static/sound_jars/mp3spi1.9.5.jar')
|
|
6
|
+
require File.join(DIR, '../static/sound_jars/jl1.0.1.jar')
|
|
7
|
+
require File.join(DIR, '../static/sound_jars/jogg-0.0.7.jar')
|
|
8
|
+
require File.join(DIR, '../static/sound_jars/jorbis-0.0.15.jar')
|
|
9
|
+
require File.join(DIR, '../static/sound_jars/vorbisspi1.0.3.jar')
|
|
10
|
+
|
|
11
|
+
class Shoes
|
|
12
|
+
class Video
|
|
13
|
+
JFile = java.io.File
|
|
14
|
+
import java.io.BufferedInputStream
|
|
15
|
+
import javax.sound.sampled
|
|
16
|
+
import java.io.IOException
|
|
17
|
+
|
|
18
|
+
BufferSize = 4096
|
|
19
|
+
|
|
20
|
+
def initialize args
|
|
21
|
+
@initials = args
|
|
22
|
+
args.each do |k, v|
|
|
23
|
+
instance_variable_set "@#{k}", v
|
|
24
|
+
end
|
|
25
|
+
Video.class_eval do
|
|
26
|
+
attr_accessor *args.keys
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def play
|
|
31
|
+
Thread.new do
|
|
32
|
+
audio_input_stream = AudioSystem.getAudioInputStream JFile.new(@path)
|
|
33
|
+
audio_format = audio_input_stream.getFormat
|
|
34
|
+
rawplay *decode_input_stream(audio_format, audio_input_stream)
|
|
35
|
+
audio_input_stream.close
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def decode_input_stream audio_format, audio_input_stream
|
|
40
|
+
case audio_format.encoding
|
|
41
|
+
when Java::JavazoomSpiVorbisSampledFile::VorbisEncoding, Java::JavazoomSpiMpegSampledFile::MpegEncoding
|
|
42
|
+
decoded_format = AudioFormat.new(AudioFormat::Encoding::PCM_SIGNED, audio_format.getSampleRate(), 16,
|
|
43
|
+
audio_format.getChannels(), audio_format.getChannels() * 2, audio_format.getSampleRate(), false)
|
|
44
|
+
decoded_audio_input_stream = AudioSystem.getAudioInputStream(decoded_format, audio_input_stream)
|
|
45
|
+
return decoded_format, decoded_audio_input_stream
|
|
46
|
+
else
|
|
47
|
+
return audio_format, audio_input_stream
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def rawplay(decoded_audio_format, decoded_audio_input_stream)
|
|
52
|
+
sampled_data = Java::byte[BufferSize].new
|
|
53
|
+
line = getLine(decoded_audio_format)
|
|
54
|
+
if line != nil
|
|
55
|
+
line.start()
|
|
56
|
+
bytes_read = 0, bytes_written = 0
|
|
57
|
+
while bytes_read != -1
|
|
58
|
+
bytes_read = decoded_audio_input_stream.read(sampled_data, 0, sampled_data.length)
|
|
59
|
+
if bytes_read != -1
|
|
60
|
+
bytes_written = line.write(sampled_data, 0, bytes_read)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
line.drain()
|
|
64
|
+
line.stop()
|
|
65
|
+
line.close()
|
|
66
|
+
decoded_audio_input_stream.close()
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def getLine(audioFormat)
|
|
71
|
+
res = nil
|
|
72
|
+
info = DataLine::Info.new(SourceDataLine.java_class, audioFormat)
|
|
73
|
+
res = AudioSystem.getLine(info)
|
|
74
|
+
res.open(audioFormat)
|
|
75
|
+
res
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
class Shoes
|
|
81
|
+
class App
|
|
82
|
+
def video file
|
|
83
|
+
args = {}
|
|
84
|
+
args[:real], args[:app], args[:path] = nil, self, file
|
|
85
|
+
Video.new args
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
data/lib/purple_shoes.rb
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'tmpdir'
|
|
2
|
+
require 'pathname'
|
|
3
|
+
require 'java'
|
|
4
|
+
require 'swt'
|
|
5
|
+
|
|
6
|
+
STDOUT.sync = true
|
|
7
|
+
|
|
8
|
+
Types = module Shoes; self end
|
|
9
|
+
|
|
10
|
+
module Shoes
|
|
11
|
+
DIR = Pathname.new(__FILE__).realpath.dirname.to_s
|
|
12
|
+
SHOES_VERSION = IO.read(File.join(DIR, '../VERSION')).chomp
|
|
13
|
+
BASIC_ATTRIBUTES_DEFAULT = {left: 0, top: 0, width: 0, height: 0, angle: 0, curve: 0}
|
|
14
|
+
SLOT_ATTRIBUTES_DEFAULT = {left: nil, top: nil, width: 1.0, height: 0}
|
|
15
|
+
|
|
16
|
+
KEY_NAMES = {}
|
|
17
|
+
%w[DEL ESC ALT SHIFT CTRL ARROW_UP ARROW_DOWN ARROW_LEFT ARROW_RIGHT
|
|
18
|
+
PAGE_UP PAGE_DOWN HOME END INSERT
|
|
19
|
+
F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15].each{|k| KEY_NAMES[eval("Swt::SWT::#{k}")] = k}
|
|
20
|
+
KEY_NAMES[Swt::SWT::CR] = "\n"
|
|
21
|
+
COLORS = {}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module Swt
|
|
25
|
+
include_package 'org.eclipse.swt'
|
|
26
|
+
include_package 'org.eclipse.swt.layout'
|
|
27
|
+
include_package 'org.eclipse.swt.widgets'
|
|
28
|
+
include_package 'org.eclipse.swt.graphics'
|
|
29
|
+
include_package 'org.eclipse.swt.events'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Object
|
|
33
|
+
remove_const :Shoes
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
require_relative 'shoes/ruby'
|
|
37
|
+
require_relative 'shoes/helper_methods'
|
|
38
|
+
require_relative 'shoes/colors'
|
|
39
|
+
require_relative 'shoes/basic'
|
|
40
|
+
require_relative 'shoes/main'
|
|
41
|
+
require_relative 'shoes/app'
|
|
42
|
+
require_relative 'shoes/anim'
|
|
43
|
+
require_relative 'shoes/slot'
|
|
44
|
+
require_relative 'shoes/text'
|
|
45
|
+
require_relative 'shoes/widget'
|
|
46
|
+
require_relative 'shoes/url'
|
|
47
|
+
require_relative 'shoes/style'
|
|
48
|
+
require_relative 'shoes/download'
|
|
49
|
+
require_relative 'shoes/manual'
|
|
50
|
+
|
|
51
|
+
require_relative 'plugins/video'
|
data/lib/shoes/anim.rb
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
class Shoes
|
|
2
|
+
class Anim
|
|
3
|
+
def initialize cs, n=100, repaint=true, &blk
|
|
4
|
+
@cs, @n, @repaint, @i, @blk = cs, n, repaint, 0, blk
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def run
|
|
8
|
+
if continue?
|
|
9
|
+
@blk[@i = pause? ? @i : @i+1]
|
|
10
|
+
if @cs.isDisposed
|
|
11
|
+
stop
|
|
12
|
+
return
|
|
13
|
+
elsif @repaint
|
|
14
|
+
@cs.redraw
|
|
15
|
+
end
|
|
16
|
+
Shoes.display.timerExec @n, self
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def stop
|
|
21
|
+
@stop = true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def continue?
|
|
25
|
+
!@stop
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def pause
|
|
29
|
+
@pause = !@pause
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def pause?
|
|
33
|
+
@pause
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class Timer
|
|
38
|
+
def initialize app, n=1000, &blk
|
|
39
|
+
@app, @n, @blk = app, n, blk
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def run
|
|
43
|
+
@blk.call
|
|
44
|
+
@app.flush
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/shoes/app.rb
ADDED
|
@@ -0,0 +1,688 @@
|
|
|
1
|
+
class Shoes
|
|
2
|
+
class App
|
|
3
|
+
include Mod2
|
|
4
|
+
|
|
5
|
+
def initialize args={}
|
|
6
|
+
args.each do |k, v|
|
|
7
|
+
instance_variable_set "@#{k}", v
|
|
8
|
+
end
|
|
9
|
+
App.class_eval do
|
|
10
|
+
attr_accessor *(args.keys - [:width, :height, :title])
|
|
11
|
+
end
|
|
12
|
+
init_app_vars
|
|
13
|
+
@top_slot, @cslot = nil, self
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attr_accessor :cslot, :top_slot, :contents, :mmcs, :mscs, :order, :mouse_pos, :hided
|
|
17
|
+
attr_writer :mouse_button
|
|
18
|
+
attr_reader :location
|
|
19
|
+
|
|
20
|
+
def visit url
|
|
21
|
+
if url =~ /^(http|https):\/\//
|
|
22
|
+
system "start #{url}"
|
|
23
|
+
else
|
|
24
|
+
$urls.each{|k, v| clear{init_app_vars; @location = url; v.call self, $1} if k =~ url}
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def stack args={}, &blk
|
|
29
|
+
args[:app] = self
|
|
30
|
+
Stack.new slot_attributes(args), &blk
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def flow args={}, &blk
|
|
34
|
+
args[:app] = self
|
|
35
|
+
Flow.new slot_attributes(args), &blk
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def clear &blk
|
|
39
|
+
@top_slot.clear &blk
|
|
40
|
+
aflush
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def click &blk
|
|
44
|
+
if blk
|
|
45
|
+
app = self
|
|
46
|
+
ln = Swt::Listener.new
|
|
47
|
+
class << ln; self end.
|
|
48
|
+
instance_eval do
|
|
49
|
+
define_method :handleEvent do |e|
|
|
50
|
+
blk[*app.mouse]
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
@cs.addListener Swt::SWT::MouseDown, ln unless @cs.isDisposed
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def textblock klass, font_size, *msg
|
|
58
|
+
args = msg.last.class == Hash ? msg.pop : {}
|
|
59
|
+
args = basic_attributes args
|
|
60
|
+
args[:markup] = msg.map(&:to_s).join
|
|
61
|
+
|
|
62
|
+
styles = get_styles msg
|
|
63
|
+
args[:styles] = styles unless styles.empty?
|
|
64
|
+
|
|
65
|
+
args[:size] ||= font_size
|
|
66
|
+
args[:font] ||= (@font_family or 'sans')
|
|
67
|
+
args[:stroke] ||= black
|
|
68
|
+
args[:rotate] ||= rotate
|
|
69
|
+
|
|
70
|
+
unless args[:left].zero? and args[:top].zero?
|
|
71
|
+
args[:nocontrol], args[:width] = true, width
|
|
72
|
+
layout_control = false
|
|
73
|
+
else
|
|
74
|
+
layout_control = true
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
args[:real] = (args[:create_real] or !layout_control) ? :textblock : false
|
|
78
|
+
args[:app] = self
|
|
79
|
+
|
|
80
|
+
klass.new(args).tap do |s|
|
|
81
|
+
unless s.real and layout_control
|
|
82
|
+
tl = Swt::TextLayout.new Shoes.display
|
|
83
|
+
s.real = tl
|
|
84
|
+
pl = Swt::PaintListener.new
|
|
85
|
+
s.pl = pl
|
|
86
|
+
class << pl; self end.
|
|
87
|
+
instance_eval do
|
|
88
|
+
define_method :paintControl do |e|
|
|
89
|
+
gc = e.gc
|
|
90
|
+
s.dps << gc
|
|
91
|
+
tl.setText s.markup
|
|
92
|
+
s.app.set_styles s, args
|
|
93
|
+
tl.setWidth s.width if s.width > 0
|
|
94
|
+
unless s.hided
|
|
95
|
+
Shoes.set_rotate gc, *s.rotate do
|
|
96
|
+
tl.draw gc, s.left, s.top
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
@cs.addPaintListener pl unless @cs.isDisposed
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def banner *msg; textblock Banner, 48, *msg; end
|
|
107
|
+
def title *msg; textblock Title, 34, *msg; end
|
|
108
|
+
def subtitle *msg; textblock Subtitle, 26, *msg; end
|
|
109
|
+
def tagline *msg; textblock Tagline, 18, *msg; end
|
|
110
|
+
def caption *msg; textblock Caption, 14, *msg; end
|
|
111
|
+
def para *msg; textblock Para, 12, *msg; end
|
|
112
|
+
def inscription *msg; textblock Para, 10, *msg; end
|
|
113
|
+
|
|
114
|
+
def image name, args={}, &blk
|
|
115
|
+
args = basic_attributes args
|
|
116
|
+
args[:rotate] ||= rotate
|
|
117
|
+
img = Swt::Image.new Shoes.display, name
|
|
118
|
+
args[:full_width], args[:full_height] = img.getImageData.width, img.getImageData.height
|
|
119
|
+
args[:real], args[:app] = img, self
|
|
120
|
+
|
|
121
|
+
Image.new(args).tap do |s|
|
|
122
|
+
pl = Swt::PaintListener.new
|
|
123
|
+
s.pl = pl
|
|
124
|
+
class << pl; self end.
|
|
125
|
+
instance_eval do
|
|
126
|
+
define_method :paintControl do |e|
|
|
127
|
+
gc = e.gc
|
|
128
|
+
s.dps << gc
|
|
129
|
+
unless s.hided
|
|
130
|
+
Shoes.set_rotate e.gc, *s.rotate do
|
|
131
|
+
if s.initials[:width].zero? and s.initials[:height].zero?
|
|
132
|
+
gc.drawImage img, s.left, s.top
|
|
133
|
+
else
|
|
134
|
+
s.width = s.full_width if s.width.zero?
|
|
135
|
+
s.height = s.full_height if s.height.zero?
|
|
136
|
+
gc.drawImage img, 0, 0, s.full_width, s.full_height, s.left, s.top, s.width, s.height
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
@cs.addPaintListener pl unless @cs.isDisposed
|
|
143
|
+
clickable s, &blk
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def button name, args={}
|
|
148
|
+
args = basic_attributes args
|
|
149
|
+
b = Swt::Button.new @cs, Swt::SWT::NULL
|
|
150
|
+
b.setText name
|
|
151
|
+
b.setLocation args[:left], args[:top]
|
|
152
|
+
if args[:width] > 0 and args[:height] > 0
|
|
153
|
+
b.setSize args[:width], args[:height]
|
|
154
|
+
else
|
|
155
|
+
b.pack
|
|
156
|
+
end
|
|
157
|
+
args[:real], args[:text], args[:app] = b, name, self
|
|
158
|
+
Button.new(args).tap do |s|
|
|
159
|
+
b.addSelectionListener do |e|
|
|
160
|
+
yield s
|
|
161
|
+
end if block_given?
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def radio args={}, &blk
|
|
166
|
+
args = basic_attributes args
|
|
167
|
+
args[:block] = blk
|
|
168
|
+
b = Swt::Button.new @cs, Swt::SWT::RADIO
|
|
169
|
+
b.setLocation args[:left], args[:top]
|
|
170
|
+
if args[:width] > 0 and args[:height] > 0
|
|
171
|
+
b.setSize args[:width], args[:height]
|
|
172
|
+
else
|
|
173
|
+
b.pack
|
|
174
|
+
end
|
|
175
|
+
args[:real], args[:app] = b, self
|
|
176
|
+
Radio.new(args).tap do |s|
|
|
177
|
+
b.addSelectionListener do |e|
|
|
178
|
+
blk[s] if b.getSelection
|
|
179
|
+
end if blk
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def edit_text attrs
|
|
184
|
+
klass, w, h, style, blk, attrs = attrs
|
|
185
|
+
args = attrs.last.class == Hash ? attrs.pop : {}
|
|
186
|
+
txt = attrs.first unless attrs.empty?
|
|
187
|
+
args = basic_attributes args
|
|
188
|
+
args[:width] = w if args[:width].zero?
|
|
189
|
+
args[:height] = h if args[:height].zero?
|
|
190
|
+
|
|
191
|
+
el = Swt::Text.new @cs, Swt::SWT::BORDER | style
|
|
192
|
+
el.setText txt || args[:text].to_s
|
|
193
|
+
el.setSize args[:width], args[:height]
|
|
194
|
+
args[:real], args[:app] = el, self
|
|
195
|
+
klass.new(args).tap do |s|
|
|
196
|
+
el.addModifyListener{|e| blk[s]} if blk
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def edit_line *attrs, &blk
|
|
201
|
+
edit_text [EditLine, 200, 20, Swt::SWT::SINGLE, blk, attrs]
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def edit_box *attrs, &blk
|
|
205
|
+
edit_text [EditBox, 200, 100, Swt::SWT::MULTI | Swt::SWT::WRAP, blk, attrs]
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def list_box args={}
|
|
209
|
+
args = basic_attributes args
|
|
210
|
+
args[:width] = 200 if args[:width].zero?
|
|
211
|
+
args[:height] = 20 if args[:height].zero?
|
|
212
|
+
args[:items] ||= []
|
|
213
|
+
cb = Swt::Combo.new @cs, Swt::SWT::DROP_DOWN
|
|
214
|
+
cb.setSize args[:width], args[:height]
|
|
215
|
+
cb.setItems args[:items].map(&:to_s)
|
|
216
|
+
cb.setText args[:choose].to_s
|
|
217
|
+
args[:real], args[:app] = cb, self
|
|
218
|
+
ListBox.new(args).tap do |s|
|
|
219
|
+
cb.addSelectionListener do |e|
|
|
220
|
+
yield s
|
|
221
|
+
end if block_given?
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def animate n=10, repaint=true, &blk
|
|
226
|
+
n, i = 1000 / n, 0
|
|
227
|
+
Anim.new(@cs, n, repaint, &blk).tap do |a|
|
|
228
|
+
Shoes.display.timerExec n, a
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def every n=1, &blk
|
|
233
|
+
animate 1.0/n, &blk
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def timer n=1, &blk
|
|
237
|
+
n *= 1000
|
|
238
|
+
Timer.new(self, n, &blk).tap{|t| Shoes.display.timerExec n, t}
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def motion &blk
|
|
242
|
+
@mmcs << blk
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def keypress &blk
|
|
246
|
+
kl = Swt::KeyListener.new
|
|
247
|
+
class << kl; self end.
|
|
248
|
+
instance_eval do
|
|
249
|
+
define_method(:keyPressed){|e| blk[KEY_NAMES[e.keyCode] || e.character.chr]}
|
|
250
|
+
define_method(:keyReleased){|e|}
|
|
251
|
+
end
|
|
252
|
+
@shell.addKeyListener kl
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def mouse
|
|
256
|
+
[@mouse_button, @mouse_pos[0], @mouse_pos[1]]
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def shape args={}, &blk
|
|
260
|
+
args = basic_attributes args
|
|
261
|
+
args[:strokewidth] = ( args[:strokewidth] or strokewidth or 1 )
|
|
262
|
+
args[:nocontrol] = args[:noorder] = true
|
|
263
|
+
args[:stroke] ||= stroke
|
|
264
|
+
args[:fill] ||= fill
|
|
265
|
+
args[:rotate] ||= rotate
|
|
266
|
+
args[:real], args[:app], args[:block] = :shape, self, blk
|
|
267
|
+
Shape.new(args).tap do |s|
|
|
268
|
+
pl = Swt::PaintListener.new
|
|
269
|
+
s.pl = pl
|
|
270
|
+
s.real = Swt::Path.new Shoes.display
|
|
271
|
+
class << pl; self end.
|
|
272
|
+
instance_eval do
|
|
273
|
+
define_method :paintControl do |e|
|
|
274
|
+
unless s.hided
|
|
275
|
+
gc = e.gc
|
|
276
|
+
s.dps << gc
|
|
277
|
+
gc.setAntialias Swt::SWT::ON
|
|
278
|
+
sw, pat1, pat2 = s.strokewidth, s.stroke, s.fill
|
|
279
|
+
Shoes.set_rotate gc, *s.rotate do
|
|
280
|
+
if pat2
|
|
281
|
+
Shoes.set_pattern s, gc, pat2
|
|
282
|
+
s.instance_eval &s.block
|
|
283
|
+
gc.fillPath s.real
|
|
284
|
+
end
|
|
285
|
+
if pat1
|
|
286
|
+
Shoes.set_pattern s, gc, pat1, :Foreground
|
|
287
|
+
if sw > 0
|
|
288
|
+
gc.setLineWidth sw
|
|
289
|
+
s.instance_eval &s.block
|
|
290
|
+
gc.drawPath s.real
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
@cs.addPaintListener pl unless @cs.isDisposed
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def oval *attrs, &blk
|
|
302
|
+
args = attrs.last.class == Hash ? attrs.pop : {}
|
|
303
|
+
case attrs.length
|
|
304
|
+
when 0, 1
|
|
305
|
+
when 2; args[:left], args[:top] = attrs
|
|
306
|
+
when 3; args[:left], args[:top], args[:radius] = attrs
|
|
307
|
+
else args[:left], args[:top], args[:width], args[:height] = attrs
|
|
308
|
+
end
|
|
309
|
+
args = basic_attributes args
|
|
310
|
+
args[:width].zero? ? (args[:width] = args[:radius] * 2) : (args[:radius] = args[:width]/2.0)
|
|
311
|
+
args[:height] = args[:width] if args[:height].zero?
|
|
312
|
+
args[:strokewidth] = ( args[:strokewidth] or strokewidth or 1 )
|
|
313
|
+
args[:nocontrol] = args[:noorder] = true
|
|
314
|
+
|
|
315
|
+
args[:stroke] ||= stroke
|
|
316
|
+
args[:fill] ||= fill
|
|
317
|
+
args[:rotate] ||= rotate
|
|
318
|
+
args[:real], args[:app] = :shape, self
|
|
319
|
+
Oval.new(args).tap do |s|
|
|
320
|
+
pl = Swt::PaintListener.new
|
|
321
|
+
s.pl = pl
|
|
322
|
+
class << pl; self end.
|
|
323
|
+
instance_eval do
|
|
324
|
+
define_method :paintControl do |e|
|
|
325
|
+
unless s.hided
|
|
326
|
+
gc = e.gc
|
|
327
|
+
s.dps << gc
|
|
328
|
+
gc.setAntialias Swt::SWT::ON
|
|
329
|
+
sw, pat1, pat2 = s.strokewidth, s.stroke, s.fill
|
|
330
|
+
Shoes.set_rotate gc, *s.rotate do
|
|
331
|
+
if pat2
|
|
332
|
+
Shoes.set_pattern s, gc, pat2
|
|
333
|
+
gc.fillOval s.left+sw, s.top+sw, s.width-sw*2, s.height-sw*2
|
|
334
|
+
end
|
|
335
|
+
if pat1
|
|
336
|
+
Shoes.set_pattern s, gc, pat1, :Foreground
|
|
337
|
+
if sw > 0
|
|
338
|
+
gc.setLineWidth sw
|
|
339
|
+
gc.drawOval s.left+sw/2, s.top+sw/2, s.width-sw, s.height-sw
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
@cs.addPaintListener pl unless @cs.isDisposed
|
|
347
|
+
clickable s, &blk
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
def rect *attrs, &blk
|
|
352
|
+
args = attrs.last.class == Hash ? attrs.pop : {}
|
|
353
|
+
case attrs.length
|
|
354
|
+
when 0, 1
|
|
355
|
+
when 2; args[:left], args[:top] = attrs
|
|
356
|
+
when 3; args[:left], args[:top], args[:width] = attrs
|
|
357
|
+
else args[:left], args[:top], args[:width], args[:height] = attrs
|
|
358
|
+
end
|
|
359
|
+
args[:height] = args[:width] unless args[:height]
|
|
360
|
+
args[:strokewidth] = ( args[:strokewidth] or strokewidth or 1 )
|
|
361
|
+
args[:curve] ||= 0
|
|
362
|
+
args[:nocontrol] = args[:noorder] = true
|
|
363
|
+
args = basic_attributes args
|
|
364
|
+
|
|
365
|
+
args[:stroke] ||= stroke
|
|
366
|
+
args[:fill] ||= fill
|
|
367
|
+
args[:rotate] ||= rotate
|
|
368
|
+
args[:real], args[:app] = :shape, self
|
|
369
|
+
Rect.new(args).tap do |s|
|
|
370
|
+
pl = Swt::PaintListener.new
|
|
371
|
+
s.pl = pl
|
|
372
|
+
class << pl; self end.
|
|
373
|
+
instance_eval do
|
|
374
|
+
define_method :paintControl do |e|
|
|
375
|
+
unless s.hided
|
|
376
|
+
gc = e.gc
|
|
377
|
+
s.dps << gc
|
|
378
|
+
gc.setAntialias Swt::SWT::ON
|
|
379
|
+
sw, pat1, pat2 = s.strokewidth, s.stroke, s.fill
|
|
380
|
+
Shoes.set_rotate gc, *s.rotate do
|
|
381
|
+
if pat2
|
|
382
|
+
Shoes.set_pattern s, gc, pat2
|
|
383
|
+
gc.fillRoundRectangle s.left+sw/2, s.top+sw/2, s.width-sw, s.height-sw, s.curve*2, s.curve*2
|
|
384
|
+
end
|
|
385
|
+
if pat1
|
|
386
|
+
Shoes.set_pattern s, gc, pat1, :Foreground
|
|
387
|
+
if sw > 0
|
|
388
|
+
gc.setLineWidth sw
|
|
389
|
+
gc.drawRoundRectangle s.left+sw/2, s.top+sw/2, s.width-sw, s.height-sw, s.curve*2, s.curve*2
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
@cs.addPaintListener pl unless @cs.isDisposed
|
|
397
|
+
clickable s, &blk
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def line *attrs, &blk
|
|
402
|
+
args = attrs.last.class == Hash ? attrs.pop : {}
|
|
403
|
+
case attrs.length
|
|
404
|
+
when 0, 1, 2
|
|
405
|
+
when 3; args[:sx], args[:sy], args[:ex] = attrs; args[:ey] = args[:ex]
|
|
406
|
+
else args[:sx], args[:sy], args[:ex], args[:ey] = attrs
|
|
407
|
+
end
|
|
408
|
+
sx, sy, ex, ey = args[:sx], args[:sy], args[:ex], args[:ey]
|
|
409
|
+
sw = args[:strokewidth] = ( args[:strokewidth] or strokewidth or 1 )
|
|
410
|
+
cw = hsw = sw*0.5
|
|
411
|
+
args[:width], args[:height] = (sx - ex).abs, (sy - ey).abs
|
|
412
|
+
args[:width] += cw
|
|
413
|
+
args[:height] += cw
|
|
414
|
+
args[:nocontrol] = args[:noorder] = true
|
|
415
|
+
args = basic_attributes args
|
|
416
|
+
|
|
417
|
+
if ((sx - ex) < 0 and (sy - ey) < 0) or ((sx - ex) > 0 and (sy - ey) > 0)
|
|
418
|
+
args[:left] = (sx - ex) < 0 ? sx - hsw : ex - hsw
|
|
419
|
+
args[:top] = (sy - ey) < 0 ? sy - hsw : ey - hsw
|
|
420
|
+
elsif ((sx - ex) < 0 and (sy - ey) > 0) or ((sx - ex) > 0 and (sy - ey) < 0)
|
|
421
|
+
args[:left] = (sx - ex) < 0 ? sx - hsw : ex - hsw
|
|
422
|
+
args[:top] = (sy - ey) < 0 ? sy - hsw : ey - hsw
|
|
423
|
+
elsif !(sx - ex).zero? and (sy - ey).zero?
|
|
424
|
+
args[:left] = (sx - ex) < 0 ? sx : ex
|
|
425
|
+
args[:top] = (sy - ey) < 0 ? sy - hsw : ey - hsw
|
|
426
|
+
elsif (sx - ex).zero? and !(sy - ey).zero?
|
|
427
|
+
args[:left] = (sx - ex) < 0 ? sx - hsw : ex - hsw
|
|
428
|
+
args[:top] = (sy - ey) < 0 ? sy : ey
|
|
429
|
+
else
|
|
430
|
+
args[:left] = sw
|
|
431
|
+
args[:top] = sy
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
args[:stroke] ||= stroke
|
|
435
|
+
args[:rotate] ||= rotate
|
|
436
|
+
args[:real], args[:app] = :shape, self
|
|
437
|
+
Line.new(args).tap do |s|
|
|
438
|
+
pl = Swt::PaintListener.new
|
|
439
|
+
s.pl = pl
|
|
440
|
+
class << pl; self end.
|
|
441
|
+
instance_eval do
|
|
442
|
+
define_method :paintControl do |e|
|
|
443
|
+
unless s.hided
|
|
444
|
+
gc = e.gc
|
|
445
|
+
s.dps << gc
|
|
446
|
+
gc.setAntialias Swt::SWT::ON
|
|
447
|
+
sw, pat = s.strokewidth, s.stroke
|
|
448
|
+
Shoes.set_rotate gc, *s.rotate do
|
|
449
|
+
if pat
|
|
450
|
+
Shoes.set_pattern s, gc, pat, :Foreground
|
|
451
|
+
if sw > 0
|
|
452
|
+
gc.setLineWidth sw
|
|
453
|
+
gc.drawLine s.sx, s.sy, s.ex, s.ey
|
|
454
|
+
end
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
@cs.addPaintListener pl unless @cs.isDisposed
|
|
461
|
+
clickable s, &blk
|
|
462
|
+
end
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
def star *attrs, &blk
|
|
466
|
+
args = attrs.last.class == Hash ? attrs.pop : {}
|
|
467
|
+
case attrs.length
|
|
468
|
+
when 2; args[:left], args[:top] = attrs
|
|
469
|
+
when 5; args[:left], args[:top], args[:points], args[:outer], args[:inner] = attrs
|
|
470
|
+
else
|
|
471
|
+
end
|
|
472
|
+
args[:points] ||= 10; args[:outer] ||= 100.0; args[:inner] ||= 50.0
|
|
473
|
+
args[:width] = args[:height] = args[:outer]*2.0
|
|
474
|
+
args[:strokewidth] = ( args[:strokewidth] or strokewidth or 1 )
|
|
475
|
+
args[:nocontrol] = args[:noorder] = true
|
|
476
|
+
args[:stroke] ||= stroke
|
|
477
|
+
args[:fill] ||= fill
|
|
478
|
+
args[:rotate] ||= rotate
|
|
479
|
+
args[:real], args[:app] = :shape, self
|
|
480
|
+
Star.new(args).tap do |s|
|
|
481
|
+
pl = Swt::PaintListener.new
|
|
482
|
+
s.pl = pl
|
|
483
|
+
class << pl; self end.
|
|
484
|
+
instance_eval do
|
|
485
|
+
define_method :paintControl do |e|
|
|
486
|
+
unless s.hided
|
|
487
|
+
gc = e.gc
|
|
488
|
+
s.dps << gc
|
|
489
|
+
gc.setAntialias Swt::SWT::ON
|
|
490
|
+
sw, pat1, pat2 = s.strokewidth, s.stroke, s.fill
|
|
491
|
+
outer, inner, points, left, top = s.outer, s.inner, s.points, s.left, s.top
|
|
492
|
+
polygon = []
|
|
493
|
+
polygon << left << (top + outer)
|
|
494
|
+
(1..points*2).each do |i|
|
|
495
|
+
angle = i * Math::PI / points
|
|
496
|
+
r = (i % 2 == 0) ? outer : inner
|
|
497
|
+
polygon << (left + r * Math.sin(angle)) << (top + r * Math.cos(angle))
|
|
498
|
+
end
|
|
499
|
+
Shoes.set_rotate gc, *s.rotate do
|
|
500
|
+
if pat2
|
|
501
|
+
Shoes.set_pattern s, gc, pat2
|
|
502
|
+
gc.fillPolygon polygon
|
|
503
|
+
end
|
|
504
|
+
if pat1
|
|
505
|
+
Shoes.set_pattern s, gc, pat1, :Foreground
|
|
506
|
+
if sw > 0
|
|
507
|
+
gc.setLineWidth sw
|
|
508
|
+
gc.drawPolygon polygon
|
|
509
|
+
end
|
|
510
|
+
end
|
|
511
|
+
end
|
|
512
|
+
end
|
|
513
|
+
end
|
|
514
|
+
end
|
|
515
|
+
@cs.addPaintListener pl unless @cs.isDisposed
|
|
516
|
+
clickable s, &blk
|
|
517
|
+
end
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
def rgb r, g, b, l=1.0
|
|
521
|
+
(r <= 1 and g <= 1 and b <= 1) ? [r*255, g*255, b*255, l] : [r, g, b, l]
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
%w[fill stroke strokewidth].each do |name|
|
|
525
|
+
eval "def #{name} #{name}=nil; #{name} ? @#{name}=#{name} : @#{name} end"
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
def rotate angle=nil, left=0, top=0
|
|
529
|
+
angle ? @rotate = [angle, left, top] : @rotate ||= [0, 0, 0]
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
def nostroke
|
|
533
|
+
strokewidth 0
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
def nofill
|
|
537
|
+
@fill = false
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
def gradient *attrs
|
|
541
|
+
case attrs.length
|
|
542
|
+
when 1, 2
|
|
543
|
+
pat1, pat2 = attrs
|
|
544
|
+
pat2 = pat1 unless pat2
|
|
545
|
+
return tr_color(pat1)..tr_color(pat2)
|
|
546
|
+
when 5, 6
|
|
547
|
+
pat, l, t, w, h, angle = attrs
|
|
548
|
+
angle = 0 unless angle
|
|
549
|
+
else
|
|
550
|
+
return black..black
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
pat = tr_color pat
|
|
554
|
+
color = case pat
|
|
555
|
+
when Range; [tr_color(pat.first), tr_color(pat.last)]
|
|
556
|
+
when Array; [pat, pat]
|
|
557
|
+
when String
|
|
558
|
+
return Swt::Pattern.new(Shoes.display, Swt::Image.new(Shoes.display, pat))
|
|
559
|
+
else
|
|
560
|
+
[black, black]
|
|
561
|
+
end
|
|
562
|
+
Swt::Pattern.new Shoes.display, *pattern_pos(l, t, w, h, -angle), Swt::Color.new(Shoes.display, *color[0][0, 3]), Swt::Color.new(Shoes.display, *color[1][0, 3])
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
def tr_color pat
|
|
566
|
+
if pat.is_a?(String) and pat[0] == '#'
|
|
567
|
+
color = pat[1..-1]
|
|
568
|
+
color = color.gsub(/(.)/){$1 + '0'} if color.length == 3
|
|
569
|
+
rgb *color.gsub(/(..)/).map{$1.hex}
|
|
570
|
+
else
|
|
571
|
+
pat
|
|
572
|
+
end
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
def background pat, args={}
|
|
576
|
+
args[:pattern] = pat
|
|
577
|
+
args = basic_attributes args
|
|
578
|
+
args[:curve] ||= 0
|
|
579
|
+
args[:real] = args[:create_real] ? :pattern : false
|
|
580
|
+
args[:app] = self
|
|
581
|
+
Background.new(args).tap do |s|
|
|
582
|
+
unless s.real
|
|
583
|
+
pat = s.pattern
|
|
584
|
+
pl = Swt::PaintListener.new
|
|
585
|
+
s.pl = pl
|
|
586
|
+
class << pl; self end.
|
|
587
|
+
instance_eval do
|
|
588
|
+
define_method :paintControl do |e|
|
|
589
|
+
unless s.hided
|
|
590
|
+
gc = e.gc
|
|
591
|
+
s.dps << gc
|
|
592
|
+
gc.setAntialias Swt::SWT::ON
|
|
593
|
+
Shoes.set_pattern s, gc, pat
|
|
594
|
+
gc.fillRoundRectangle s.left, s.top, s.width, s.height, s.curve*2, s.curve*2
|
|
595
|
+
end
|
|
596
|
+
end
|
|
597
|
+
end
|
|
598
|
+
@cs.addPaintListener pl unless @cs.isDisposed
|
|
599
|
+
end
|
|
600
|
+
oval 0, 0, 0, strokewidth: 0 # A monkey patch for sample 10. I don't know why this line is necessary... xx-P
|
|
601
|
+
end
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
def border pat, args={}
|
|
605
|
+
args[:pattern] = pat
|
|
606
|
+
args = basic_attributes args
|
|
607
|
+
args[:curve] ||= 0
|
|
608
|
+
args[:strokewidth] = ( args[:strokewidth] or strokewidth or 1 )
|
|
609
|
+
args[:real] = args[:create_real] ? :pattern : false
|
|
610
|
+
args[:app] = self
|
|
611
|
+
Border.new(args).tap do |s|
|
|
612
|
+
unless s.real
|
|
613
|
+
pat = s.pattern
|
|
614
|
+
sw = s.strokewidth
|
|
615
|
+
pl = Swt::PaintListener.new
|
|
616
|
+
s.pl = pl
|
|
617
|
+
class << pl; self end.
|
|
618
|
+
instance_eval do
|
|
619
|
+
define_method :paintControl do |e|
|
|
620
|
+
unless s.hided
|
|
621
|
+
gc = e.gc
|
|
622
|
+
s.dps << gc
|
|
623
|
+
gc.setAntialias Swt::SWT::ON
|
|
624
|
+
Shoes.set_pattern s, gc, pat, :Foreground
|
|
625
|
+
if sw > 0
|
|
626
|
+
gc.setLineWidth sw
|
|
627
|
+
gc.drawRoundRectangle s.left+sw/2, s.top+sw/2, s.width-sw, s.height-sw, s.curve*2, s.curve*2
|
|
628
|
+
end
|
|
629
|
+
end
|
|
630
|
+
end
|
|
631
|
+
end
|
|
632
|
+
@cs.addPaintListener pl unless @cs.isDisposed
|
|
633
|
+
end
|
|
634
|
+
end
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
def progress args={}
|
|
638
|
+
pb = Swt::ProgressBar.new @cs, Swt::SWT::SMOOTH
|
|
639
|
+
if args[:left] or args[:top]
|
|
640
|
+
args[:noorder] = args[:nocontrol] = true
|
|
641
|
+
end
|
|
642
|
+
args[:width] ||= 150
|
|
643
|
+
args[:height] ||= 16
|
|
644
|
+
args = basic_attributes args
|
|
645
|
+
pb.setSize args[:width], args[:height]
|
|
646
|
+
pb.setLocation args[:left], args[:top]
|
|
647
|
+
args[:real], args[:app] = pb, self
|
|
648
|
+
Progress.new args
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
def download name, args={}, &blk
|
|
652
|
+
Download.new name, args, &blk
|
|
653
|
+
end
|
|
654
|
+
|
|
655
|
+
def scroll_top
|
|
656
|
+
cs.getLocation.y
|
|
657
|
+
end
|
|
658
|
+
|
|
659
|
+
def scroll_top=(n)
|
|
660
|
+
cs.setLocation 0, -n
|
|
661
|
+
shell.getVerticalBar.setSelection n
|
|
662
|
+
end
|
|
663
|
+
|
|
664
|
+
def scroll_height
|
|
665
|
+
scroll_max + height
|
|
666
|
+
end
|
|
667
|
+
|
|
668
|
+
def scroll_max
|
|
669
|
+
shell.getVerticalBar.getMaximum - 10
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
def flush
|
|
673
|
+
unless @cs.isDisposed
|
|
674
|
+
Shoes.call_back_procs self
|
|
675
|
+
@cs.redraw
|
|
676
|
+
end
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
def aflush
|
|
680
|
+
@hided = true
|
|
681
|
+
Swt::Display.getDefault.asyncExec do
|
|
682
|
+
Shoes.call_back_procs self
|
|
683
|
+
@hided = false
|
|
684
|
+
@cs.redraw unless @cs.isDisposed
|
|
685
|
+
end
|
|
686
|
+
end
|
|
687
|
+
end
|
|
688
|
+
end
|