jrubyfx-openjfx.patch 1.2.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +202 -0
- data/README.md +121 -0
- data/bin/jrubyfx-compile +32 -0
- data/bin/jrubyfx-generator +98 -0
- data/bin/jrubyfx-jarify +115 -0
- data/lib/jrubyfx.rb +41 -0
- data/lib/jrubyfx/application.rb +42 -0
- data/lib/jrubyfx/compiler_app.rb +51 -0
- data/lib/jrubyfx/controller.rb +375 -0
- data/lib/jrubyfx/core_ext/border_pane.rb +30 -0
- data/lib/jrubyfx/core_ext/column_constraints.rb +43 -0
- data/lib/jrubyfx/core_ext/drag_event.rb +32 -0
- data/lib/jrubyfx/core_ext/duration.rb +30 -0
- data/lib/jrubyfx/core_ext/effects.rb +32 -0
- data/lib/jrubyfx/core_ext/exts.yml +57 -0
- data/lib/jrubyfx/core_ext/file_chooser.rb +63 -0
- data/lib/jrubyfx/core_ext/geometry.rb +27 -0
- data/lib/jrubyfx/core_ext/grid_pane.rb +30 -0
- data/lib/jrubyfx/core_ext/image_view.rb +25 -0
- data/lib/jrubyfx/core_ext/media_player.rb +25 -0
- data/lib/jrubyfx/core_ext/observable_value.rb +158 -0
- data/lib/jrubyfx/core_ext/pagination.rb +28 -0
- data/lib/jrubyfx/core_ext/path.rb +37 -0
- data/lib/jrubyfx/core_ext/precompiled.rb +1883 -0
- data/lib/jrubyfx/core_ext/progress_indicator.rb +41 -0
- data/lib/jrubyfx/core_ext/radial_gradient.rb +37 -0
- data/lib/jrubyfx/core_ext/region.rb +42 -0
- data/lib/jrubyfx/core_ext/rotate.rb +39 -0
- data/lib/jrubyfx/core_ext/stage.rb +89 -0
- data/lib/jrubyfx/core_ext/table_view.rb +31 -0
- data/lib/jrubyfx/core_ext/timeline.rb +56 -0
- data/lib/jrubyfx/core_ext/transition.rb +26 -0
- data/lib/jrubyfx/core_ext/tree_view.rb +40 -0
- data/lib/jrubyfx/core_ext/xy_chart.rb +53 -0
- data/lib/jrubyfx/dsl.rb +330 -0
- data/lib/jrubyfx/dsl_control.rb +28 -0
- data/lib/jrubyfx/dsl_map.rb +273 -0
- data/lib/jrubyfx/imports.rb +324 -0
- data/lib/jrubyfx/java_fx_impl.rb +144 -0
- data/lib/jrubyfx/module.rb +178 -0
- data/lib/jrubyfx/part_imports.rb +141 -0
- data/lib/jrubyfx/utils.rb +86 -0
- data/lib/jrubyfx/utils/__ignore_java_stupid_rdoc.rb +30 -0
- data/lib/jrubyfx/utils/common_converters.rb +223 -0
- data/lib/jrubyfx/utils/common_utils.rb +72 -0
- data/lib/jrubyfx/utils/string_utils.rb +48 -0
- data/lib/jrubyfx/version.rb +4 -0
- data/lib/jrubyfx_tasks.rb +183 -0
- metadata +145 -0
@@ -0,0 +1,178 @@
|
|
1
|
+
=begin
|
2
|
+
JRubyFX - Write JavaFX and FXML in Ruby
|
3
|
+
Copyright (C) 2013 The JRubyFX Team
|
4
|
+
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
you may not use this file except in compliance with the License.
|
7
|
+
You may obtain a copy of the License at
|
8
|
+
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
See the License for the specific language governing permissions and
|
15
|
+
limitations under the License.
|
16
|
+
=end
|
17
|
+
|
18
|
+
require_relative 'utils/common_utils'
|
19
|
+
|
20
|
+
# This module contains useful methods for defining JavaFX code. Include it in your
|
21
|
+
# class to use it, and the JRubyFX::FXImports. JRubyFX::Application and JRubyFX::Controller already include it.
|
22
|
+
module JRubyFX
|
23
|
+
include JRubyFX::FXImports
|
24
|
+
include JRubyFX::Utils::CommonUtils
|
25
|
+
|
26
|
+
##
|
27
|
+
# call-seq:
|
28
|
+
# with(obj, hash) => obj
|
29
|
+
# with(obj) { block } => obj
|
30
|
+
# with(obj, hash) { block }=> obj
|
31
|
+
#
|
32
|
+
# Set properties (e.g. setters) on the passed in object plus also invoke
|
33
|
+
# any block passed against this object.
|
34
|
+
# === Examples
|
35
|
+
#
|
36
|
+
# with(grid, vgap: 2, hgap: 2) do
|
37
|
+
# set_pref_size(500, 400)
|
38
|
+
# children << location << go << view
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
def with(obj, properties = {}, &block)
|
42
|
+
puts "Warning: calling 'with' on a nil object from #{caller[0]}" if obj.nil?
|
43
|
+
populate_properties(obj, properties)
|
44
|
+
|
45
|
+
if block_given?
|
46
|
+
# cache the proxy - http://wiki.jruby.org/Persistence
|
47
|
+
obj.class.__persistent__ = true if obj.class.ancestors.include? JavaProxy
|
48
|
+
obj.extend(JRubyFX)
|
49
|
+
obj.instance_eval(&block)
|
50
|
+
end
|
51
|
+
|
52
|
+
obj
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# call-seq:
|
57
|
+
# run_later { block }
|
58
|
+
#
|
59
|
+
# Convenience method so anything can safely schedule to run on JavaFX
|
60
|
+
# main thread.
|
61
|
+
def run_later(&block)
|
62
|
+
Java::javafx.application.Platform.run_later &block
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# call-seq:
|
67
|
+
# build(class) => obj
|
68
|
+
# build(class, hash) => obj
|
69
|
+
# build(class) { block } => obj
|
70
|
+
# build(class, hash) { block } => obj
|
71
|
+
#
|
72
|
+
# Create "build" a new JavaFX instance with the provided class and
|
73
|
+
# set properties (e.g. setters) on that new instance plus also invoke
|
74
|
+
# any block passed against this new instance. This also can build a proc
|
75
|
+
# or lambda form in which case the return value of the block will be what
|
76
|
+
# is used to set the additional properties on.
|
77
|
+
# === Examples
|
78
|
+
#
|
79
|
+
# grid = build(GridPane, vgap: 2, hgap: 2) do
|
80
|
+
# set_pref_size(500, 400)
|
81
|
+
# children << location << go << view
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# build(proc { Foo.new }, vgap: 2, hgap: 2)
|
85
|
+
#
|
86
|
+
def build(klass, *args, &block)
|
87
|
+
args, properties = split_args_from_properties(*args)
|
88
|
+
|
89
|
+
obj = if klass.kind_of? Proc
|
90
|
+
klass.call(*args)
|
91
|
+
else
|
92
|
+
klass.new(*attempt_conversion(klass, :new, *args))
|
93
|
+
end
|
94
|
+
|
95
|
+
with(obj, properties, &block)
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.included(mod)
|
99
|
+
mod.extend(JRubyFX::FXMLClassUtils)
|
100
|
+
mod.extend(JRubyFX::FXImports)
|
101
|
+
end
|
102
|
+
|
103
|
+
module FXMLClassUtils
|
104
|
+
def fxml_raw_accessor(symbol_name, type=java::lang::String)
|
105
|
+
# TODO: RDoc
|
106
|
+
# TODO: somebody clean this up
|
107
|
+
# TODO: _reader and _writer
|
108
|
+
send(:define_method, symbol_name.id2name.snake_case + "=") do |val|
|
109
|
+
instance_variable_set("@#{symbol_name}", val)
|
110
|
+
end
|
111
|
+
send(:define_method, symbol_name.id2name.snake_case) do
|
112
|
+
instance_variable_get("@#{symbol_name}")
|
113
|
+
end
|
114
|
+
send(:define_method, symbol_name.id2name.snake_case + "GetType") do
|
115
|
+
return type.java_class
|
116
|
+
end
|
117
|
+
camel = symbol_name.id2name
|
118
|
+
camel = camel[0].upcase + camel[1..-1]
|
119
|
+
send(:define_method, "set" + camel) do |val|
|
120
|
+
instance_variable_set("@#{symbol_name}", val)
|
121
|
+
end
|
122
|
+
send(:define_method, "get" + camel) do
|
123
|
+
instance_variable_get("@#{symbol_name}")
|
124
|
+
end
|
125
|
+
send(:define_method, symbol_name.id2name + "GetType") do
|
126
|
+
return type.java_class
|
127
|
+
end
|
128
|
+
end
|
129
|
+
def fxml_accessor(symbol_name,ptype=Java::javafx.beans.property.SimpleStringProperty, type=nil)
|
130
|
+
# TODO: RDoc
|
131
|
+
# TODO: somebody clean this up
|
132
|
+
# TODO: _reader and _writer ? maybe? not?
|
133
|
+
pname = symbol_name.id2name + "Property"
|
134
|
+
raise "#{ptype} does not inherit from Property." unless ptype.ancestors.include? Java::javafx.beans.property.Property
|
135
|
+
unless type
|
136
|
+
type = ptype.java_class.java_instance_methods.find_all{|x|x.name == "getValue"}.map{|x|x.return_type}.find_all{|x|x != java.lang.Object.java_class}
|
137
|
+
if type.length != 1
|
138
|
+
raise "Unknown property type. Please manually supply a type or report this as a bug"
|
139
|
+
end
|
140
|
+
type = type[0]
|
141
|
+
else
|
142
|
+
type = type.java_class
|
143
|
+
end
|
144
|
+
send(:define_method, symbol_name.id2name.snake_case + "=") do |val|
|
145
|
+
send(pname).setValue val
|
146
|
+
end
|
147
|
+
send(:define_method, symbol_name.id2name.snake_case) do
|
148
|
+
send(pname).getValue
|
149
|
+
end
|
150
|
+
send(:define_method, symbol_name.id2name.snake_case + "GetType") do
|
151
|
+
return type
|
152
|
+
end
|
153
|
+
camel = symbol_name.id2name
|
154
|
+
camel = camel[0].upcase + camel[1..-1]
|
155
|
+
send(:define_method, "set" + camel) do |val|
|
156
|
+
send(pname).setValue val
|
157
|
+
end
|
158
|
+
send(:define_method, "get" + camel) do
|
159
|
+
send(pname).getValue
|
160
|
+
end
|
161
|
+
send(:define_method, symbol_name.id2name + "GetType") do
|
162
|
+
return type
|
163
|
+
end
|
164
|
+
send(:define_method, pname) do
|
165
|
+
unless instance_variable_get("@#{symbol_name}")
|
166
|
+
instance_variable_set("@#{symbol_name}", ptype.new(self, symbol_name.to_s))
|
167
|
+
end
|
168
|
+
return instance_variable_get("@#{symbol_name}")
|
169
|
+
end
|
170
|
+
send(:define_method, pname.snake_case) do
|
171
|
+
send(pname)
|
172
|
+
end
|
173
|
+
add_method_signature pname, [ptype]
|
174
|
+
add_method_signature "set" + camel, [java.lang.Void, type]
|
175
|
+
add_method_signature "get" + camel, [type]
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
=begin
|
2
|
+
JRubyFX - Write JavaFX and FXML in Ruby
|
3
|
+
Copyright (C) 2013 The JRubyFX Team
|
4
|
+
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
you may not use this file except in compliance with the License.
|
7
|
+
You may obtain a copy of the License at
|
8
|
+
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
See the License for the specific language governing permissions and
|
15
|
+
limitations under the License.
|
16
|
+
=end
|
17
|
+
|
18
|
+
require_relative 'utils'
|
19
|
+
|
20
|
+
# Update load path to include the JavaFX runtime and fail nicely if we can't find it
|
21
|
+
begin
|
22
|
+
if ENV['JFX_DIR']
|
23
|
+
$LOAD_PATH << ENV['JFX_DIR']
|
24
|
+
else #should we check for 1.7 vs 1.8? oh well, adding extra paths won't hurt anybody (maybe performance loading)
|
25
|
+
jfx_path = ENV_JAVA["sun.boot.library.path"]
|
26
|
+
$LOAD_PATH << if jfx_path.include? ":\\" and !jfx_path.include? "/" # can be tricked, but should work fine
|
27
|
+
#windows
|
28
|
+
jfx_path.gsub(/\\bin[\\]*$/i, "\\lib")
|
29
|
+
else
|
30
|
+
# *nix
|
31
|
+
jfx_path.gsub(/[\/\\][amdix345678_]+$/, "") # strip i386 or amd64 (including variants). TODO: ARM
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Java 8 (after ea-b75) and above has JavaFX as part of the normal distib, only require it if we are 7 or below
|
36
|
+
jre = ENV_JAVA["java.runtime.version"].match %r{^(?<version>(?<major>\d+)\.(?<minor>\d+))\.(?<patch>\d+)(_\d+)?-?(?<release>ea|u\d)?(-?b(?<build>\d+))?}
|
37
|
+
# add OpenJFX support if follow instruction from https://openjfx.io
|
38
|
+
if ENV['JFX_DIR'] or
|
39
|
+
jre[:version].to_f < 1.8 or
|
40
|
+
(jre[:version].to_f == 1.8 and jre[:release] == 'ea' and jre[:build].to_i < 75)
|
41
|
+
require 'jfxrt.jar'
|
42
|
+
elsif ENV['PATH_TO_FX'] # support the OpenJFX installation as in https://openjfx.io/openjfx-docs/#install-javafx as of 15th May 2020
|
43
|
+
Dir.glob(File.join(ENV['PATH_TO_FX'],"*.jar")).each do |jar|
|
44
|
+
require jar
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Java 8 at some point requires explicit toolkit/platform initialization
|
49
|
+
# before any controls can be loaded.
|
50
|
+
JRubyFX.load_fx
|
51
|
+
|
52
|
+
# Attempt to load a javafx class
|
53
|
+
Java.javafx.application.Application
|
54
|
+
rescue LoadError, NameError
|
55
|
+
# Advice user too about the OpenJFX support
|
56
|
+
puts "JavaFX runtime not found. Please install Java 7u6 or newer, set environment variable JFX_DIR to the folder that contains jfxrt.jar or set the environment variable PATH_TO_FX that points to the OpenJFX libraries"
|
57
|
+
puts "If you have Java 7u6 or later, this is a bug. Please report to the issue tracker on github. Include your OS version, 32/64bit, and architecture (x86, ARM, PPC, etc)"
|
58
|
+
exit -1
|
59
|
+
end
|
60
|
+
|
61
|
+
module JRubyFX
|
62
|
+
# If you need JavaFX, just include this module. Its sole purpose in life is to
|
63
|
+
# import all JavaFX stuff, plus a few useful Java classes (like Void)
|
64
|
+
module FXImports
|
65
|
+
|
66
|
+
# If something is missing, just java_import it in your code.
|
67
|
+
# And then ask us to put it in this list
|
68
|
+
###### IMPORTANT LINE ##### (see rakefile, this is a magic line, don't delete)
|
69
|
+
|
70
|
+
##
|
71
|
+
# This is the list of all classes in JavaFX that most apps should care about.
|
72
|
+
# It is a hashmaps with the leafs as arrays. Where a leaf also contains more
|
73
|
+
# packages, the hashmap key is "" (empty string). You can utilize this constant
|
74
|
+
# to save yourself some typing when adding code for most/all of the JavaFX
|
75
|
+
# classes by using either `Hash.flat_tree_inject` from jrubyfx/utils.rb or
|
76
|
+
# writing your own traversal function
|
77
|
+
#
|
78
|
+
JFX_CLASS_HIERARCHY = { :javafx => {
|
79
|
+
:animation => %w[Animation AnimationTimer FadeTransition FillTransition Interpolator KeyFrame KeyValue ParallelTransition PathTransition
|
80
|
+
PauseTransition RotateTransition ScaleTransition SequentialTransition StrokeTransition Timeline Transition TranslateTransition],
|
81
|
+
:application => ['Platform'],
|
82
|
+
:beans => {
|
83
|
+
:property => %w[SimpleBooleanProperty SimpleDoubleProperty SimpleFloatProperty SimpleIntegerProperty SimpleListProperty SimpleLongProperty SimpleMapProperty SimpleObjectProperty SimpleSetProperty SimpleStringProperty],
|
84
|
+
#TODO: import more
|
85
|
+
:value => ['ChangeListener']
|
86
|
+
},
|
87
|
+
:collections => ['FXCollections'],
|
88
|
+
:concurrent => %w[Worker Task Service],
|
89
|
+
:event => %w[Event ActionEvent EventHandler],
|
90
|
+
:fxml => ['Initializable', 'LoadException'],
|
91
|
+
:geometry => %w[HorizontalDirection HPos Insets Orientation Pos Rectangle2D Side VerticalDirection VPos],
|
92
|
+
:scene => {
|
93
|
+
'' => %w[Group Node Parent Scene],
|
94
|
+
:canvas => ['Canvas'],
|
95
|
+
:chart => %w[AreaChart Axis BarChart BubbleChart CategoryAxis Chart LineChart NumberAxis
|
96
|
+
PieChart ScatterChart StackedAreaChart StackedBarChart ValueAxis XYChart],
|
97
|
+
:control => %w[Accordion Button Cell CheckBox CheckBoxTreeItem CheckMenuItem ChoiceBox ColorPicker ComboBox ContextMenu Hyperlink
|
98
|
+
Label ListCell ListView Menu MenuBar MenuButton MenuItem Pagination PasswordField PopupControl ProgressBar ProgressIndicator RadioButton
|
99
|
+
RadioMenuItem ScrollBar ScrollPane Separator SeparatorMenuItem Slider SplitMenuButton SplitPane Tab TableView TableCell TableColumn TabPane TextArea
|
100
|
+
TextField TitledPane ToggleButton ToggleGroup ToolBar Tooltip TreeCell TreeItem TreeView ContentDisplay OverrunStyle SelectionMode],
|
101
|
+
:effect => %w[Blend BlendMode Bloom BlurType BoxBlur ColorAdjust ColorInput DisplacementMap DropShadow GaussianBlur Glow ImageInput
|
102
|
+
InnerShadow Lighting MotionBlur PerspectiveTransform Reflection SepiaTone Shadow],
|
103
|
+
:image => %w[Image ImageView PixelReader PixelWriter],
|
104
|
+
:input => %w[Clipboard ClipboardContent ContextMenuEvent DragEvent GestureEvent InputEvent InputMethodEvent KeyCode KeyEvent
|
105
|
+
Mnemonic MouseButton MouseDragEvent MouseEvent RotateEvent ScrollEvent SwipeEvent TouchEvent TransferMode ZoomEvent],
|
106
|
+
:layout => %w[AnchorPane BorderPane ColumnConstraints FlowPane GridPane HBox Pane Priority RowConstraints StackPane TilePane VBox],
|
107
|
+
:media => %w[AudioClip AudioEqualizer AudioTrack EqualizerBand Media MediaException
|
108
|
+
MediaErrorEvent MediaMarkerEvent MediaPlayer MediaView VideoTrack],
|
109
|
+
:paint => %w[Color CycleMethod ImagePattern LinearGradient Paint RadialGradient Stop],
|
110
|
+
:shape => %w[Arc ArcTo ArcType Circle ClosePath CubicCurve CubicCurveTo Ellipse FillRule HLineTo Line LineTo MoveTo Path PathElement
|
111
|
+
Polygon Polyline QuadCurve QuadCurveTo Rectangle Shape StrokeLineCap StrokeLineJoin StrokeType SVGPath VLineTo],
|
112
|
+
:text => %w[Font FontPosture FontSmoothingType FontWeight Text TextAlignment TextBoundsType],
|
113
|
+
:transform => %w[Affine Rotate Scale Shear Translate],
|
114
|
+
:web => ['WebView', 'HTMLEditor']
|
115
|
+
},
|
116
|
+
:stage => %w[DirectoryChooser FileChooser Modality Popup PopupWindow Screen Stage StageStyle Window WindowEvent],
|
117
|
+
:util => ['Duration']
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
121
|
+
$WRITE_OUT << <<HERE
|
122
|
+
def const_missing(c)
|
123
|
+
if LOCAL_NAME_MAP.has_key? c
|
124
|
+
java_import(LOCAL_NAME_MAP[c])[0]
|
125
|
+
else
|
126
|
+
super
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
HERE
|
131
|
+
|
132
|
+
# Imports all the listed JavaFX classes
|
133
|
+
$WRITE_OUT << "LOCAL_NAME_MAP = { \n "
|
134
|
+
$WRITE_OUT << (JFX_CLASS_HIERARCHY.flat_tree_inject do |res, name, values|
|
135
|
+
name = "#{name.to_s}."
|
136
|
+
name = "" if name == "."
|
137
|
+
res.concat(values.map{|i| "#{name}#{i}"})
|
138
|
+
end).map{|x| "#{x.split(".").last.to_sym.inspect} => #{x.inspect}"}.join(",\n ")
|
139
|
+
$WRITE_OUT << "\n}\njava_import 'java.lang.Void'"
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
=begin
|
2
|
+
JRubyFX - Write JavaFX and FXML in Ruby
|
3
|
+
Copyright (C) 2013 The JRubyFX Team
|
4
|
+
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
you may not use this file except in compliance with the License.
|
7
|
+
You may obtain a copy of the License at
|
8
|
+
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
See the License for the specific language governing permissions and
|
15
|
+
limitations under the License.
|
16
|
+
=end
|
17
|
+
|
18
|
+
# This feels kinda like a hack. If anyone has a better idea, please let me know
|
19
|
+
|
20
|
+
# Standard ruby Hash class extensions
|
21
|
+
class Hash
|
22
|
+
|
23
|
+
# call-seq:
|
24
|
+
# flat_tree_inject() {|results, key, value| block} => array
|
25
|
+
# flat_tree_inject(Hash) {|results, key, value| block} => hash
|
26
|
+
#
|
27
|
+
# Execute given block against all nodes in the hash tree, returning `results`.
|
28
|
+
# Similar to Hash#each except goes into all sub-Hashes
|
29
|
+
#
|
30
|
+
def flat_tree_inject(klass=Array,&block)
|
31
|
+
self.inject(klass.new) do |lres, pair|
|
32
|
+
if pair[1].is_a? Hash
|
33
|
+
pair[1] = pair[1].flat_tree_inject(klass, &block)
|
34
|
+
end
|
35
|
+
block.call(lres, *pair)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Standard ruby String class extensions
|
41
|
+
class String
|
42
|
+
# call-seq:
|
43
|
+
# snake_case(ignore_prefix_namespace=false) => string
|
44
|
+
#
|
45
|
+
# Converts a CamelCaseString to a snake_case_string
|
46
|
+
#
|
47
|
+
# "JavaFX".snake_case #=> "java_fx"
|
48
|
+
#
|
49
|
+
# If ignore_prefix_namespace is specified it will strip
|
50
|
+
# any preceding modules/classes off front of string before
|
51
|
+
# snake casing:
|
52
|
+
# Foo::BigBar #=> "big_bar"
|
53
|
+
#
|
54
|
+
# By default it will separate modules with a "/":
|
55
|
+
# Foo::BigBar #=> "foo/big_bar"
|
56
|
+
#
|
57
|
+
def snake_case(ignore_prefix_namespace=false)
|
58
|
+
base = ignore_prefix_namespace ?
|
59
|
+
self.gsub(/.*::/, '') : self.gsub(/::/, '/')
|
60
|
+
base.
|
61
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
62
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
63
|
+
tr("-", "_").
|
64
|
+
downcase
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
module Enumerable
|
69
|
+
def map_find(&block)
|
70
|
+
m = {}
|
71
|
+
m[self.find do |i|
|
72
|
+
m[i] = block.call(i)
|
73
|
+
end]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
module JRubyFX
|
78
|
+
def self.load_fx(force=false)
|
79
|
+
return if @already_loaded_fx and !force
|
80
|
+
@already_loaded_fx = true
|
81
|
+
java.util.concurrent.CountDownLatch.new(1).tap do |latch|
|
82
|
+
com.sun.javafx.application.PlatformImpl.startup { latch.countDown }
|
83
|
+
latch.await
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Java #:nodoc: all
|
2
|
+
module javafx
|
3
|
+
module animation
|
4
|
+
end
|
5
|
+
module beans
|
6
|
+
module value
|
7
|
+
end
|
8
|
+
end
|
9
|
+
module scene
|
10
|
+
module chart
|
11
|
+
end
|
12
|
+
module control
|
13
|
+
end
|
14
|
+
module effect
|
15
|
+
end
|
16
|
+
module layout
|
17
|
+
end
|
18
|
+
module media
|
19
|
+
end
|
20
|
+
module paint
|
21
|
+
end
|
22
|
+
module shape
|
23
|
+
end
|
24
|
+
module transform
|
25
|
+
end
|
26
|
+
end
|
27
|
+
module stage
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
=begin
|
2
|
+
JRubyFX - Write JavaFX and FXML in Ruby
|
3
|
+
Copyright (C) 2013 The JRubyFX Team
|
4
|
+
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
you may not use this file except in compliance with the License.
|
7
|
+
You may obtain a copy of the License at
|
8
|
+
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
See the License for the specific language governing permissions and
|
15
|
+
limitations under the License.
|
16
|
+
=end
|
17
|
+
false # Do NOT delete this or it will make RDOC associate the copyright header with JRubyFX module
|
18
|
+
|
19
|
+
module JRubyFX
|
20
|
+
module Utils
|
21
|
+
# Contains conversion utilities to ease Ruby => JavaFX coding
|
22
|
+
module CommonConverters
|
23
|
+
java_import 'javafx.scene.paint.Color'
|
24
|
+
java_import 'javafx.geometry.Insets'
|
25
|
+
java_import 'javafx.geometry.Rectangle2D'
|
26
|
+
|
27
|
+
# argument converter method name suffix
|
28
|
+
ARG_CONVERTER_SUFFIX = '_arg_converter'
|
29
|
+
|
30
|
+
# map of snake_cased colors to JavaFX Colors
|
31
|
+
NAME_TO_COLORS = {
|
32
|
+
'darkyellow' => Color.web('0xc0c000'),
|
33
|
+
'lightmagenta' => Color.web('0xffc0ff'),
|
34
|
+
'lightred' => Color.web('0xffc0c0'),
|
35
|
+
}.merge(Color.java_class.fields.inject({}) {|final, field|
|
36
|
+
final[field.name.downcase] = field.value(nil) # TODO: what is nil supposed to be?
|
37
|
+
final
|
38
|
+
})
|
39
|
+
|
40
|
+
##
|
41
|
+
# Generate a converter for a map of supplied values.
|
42
|
+
def map_converter(map)
|
43
|
+
lambda do |value|
|
44
|
+
map.key?(value) ? map[value] : value
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Generate a converter for an enum of the given class
|
50
|
+
def enum_converter(enum_class)
|
51
|
+
lambda do |value|
|
52
|
+
(JRubyFX::Utils::CommonConverters.map_enums(enum_class)[value.to_s] || value)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# call-seq:
|
58
|
+
# animation_converter_for :property_name, ...
|
59
|
+
#
|
60
|
+
# Generates an animation adapter for the given properties so you can specify
|
61
|
+
# transformations, etc with a hashmap of from, to values
|
62
|
+
# === Examples
|
63
|
+
# animation_converter_for :value
|
64
|
+
#
|
65
|
+
# ...
|
66
|
+
#
|
67
|
+
# _my_type_(value: {0 => 360})
|
68
|
+
#
|
69
|
+
def animation_converter_for(*prop_names)
|
70
|
+
prop_names.each do |prop_name|
|
71
|
+
self.__send__(:define_method, prop_name.to_s + "=") do |hash|
|
72
|
+
method("from_#{prop_name}=").call hash.keys[0]
|
73
|
+
method("to_#{prop_name}=").call hash.values[0]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Allows you to specify you want a converter method created for the
|
80
|
+
# specified method where each listed converter corresponds to each
|
81
|
+
# argument for that method. You can have n-arity lists for all
|
82
|
+
# matching Java overloads. This mechanism means you may not always
|
83
|
+
# be able to specify all coercions you want.
|
84
|
+
# === Examples
|
85
|
+
#
|
86
|
+
# coverter_for :new, [:none, :color]
|
87
|
+
#
|
88
|
+
# This method will define a method on the current class called
|
89
|
+
# *new_arg_converter* which will perform no argument coercion on
|
90
|
+
# the first argument and a color coercion on the second argument.
|
91
|
+
#
|
92
|
+
# e = enum_converter(Java::javafx::scene::input::TransferMode)
|
93
|
+
# converter_for :accept_transfer_modes &e
|
94
|
+
#
|
95
|
+
# This method will allow a catch-all converter to be used for all
|
96
|
+
# arities not specified. In this case since no arities are given
|
97
|
+
# all arities will pass through this enum_converter. This form
|
98
|
+
# is useful for single var_args signatures.
|
99
|
+
#
|
100
|
+
def converter_for(method_name, *converters, &default)
|
101
|
+
# puts "[converter for #{self}, #{method_name}]"
|
102
|
+
sheep = lambda do |direct, this, *values|
|
103
|
+
converter = converters.find { |e| e.length == values.length }
|
104
|
+
converter = Array.new(values.length, default) unless converter
|
105
|
+
|
106
|
+
# FIXME: Better error reporting on many things which can fail
|
107
|
+
i = 0
|
108
|
+
values = values.inject([]) do |s, value|
|
109
|
+
conv = converter[i]
|
110
|
+
if conv.kind_of? Proc
|
111
|
+
s << conv.call(value)
|
112
|
+
else
|
113
|
+
s << CONVERTERS[converter[i]].call(value)
|
114
|
+
end
|
115
|
+
i += 1
|
116
|
+
s
|
117
|
+
end
|
118
|
+
if direct
|
119
|
+
return this.method("set_" + method_name.to_s).call(*values)
|
120
|
+
else
|
121
|
+
return values
|
122
|
+
end
|
123
|
+
end
|
124
|
+
# define a setter for normal usage
|
125
|
+
unless method_name == :new
|
126
|
+
self.__send__(:define_method, method_name.to_s + "=") do |*values|
|
127
|
+
sheep.call(true, self, *values)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
# define a build/with usage
|
131
|
+
self.__send__(:define_method, method_name.to_s + ARG_CONVERTER_SUFFIX) do |*values|
|
132
|
+
sheep.call(false, self, *values)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Map of different kinds of known converters
|
137
|
+
CONVERTERS = {
|
138
|
+
:none => lambda { |value|
|
139
|
+
value
|
140
|
+
},
|
141
|
+
:color => lambda { |value|
|
142
|
+
new_value = NAME_TO_COLORS[value.to_s.gsub(/_/, "")]
|
143
|
+
if !new_value && value.kind_of?(Symbol)
|
144
|
+
raise ArgumentError.new("No such color: #{value.to_s}")
|
145
|
+
end
|
146
|
+
new_value ? new_value : value
|
147
|
+
},
|
148
|
+
:rectangle2d => lambda { |value|
|
149
|
+
if value == :empty
|
150
|
+
Rectangle2D::EMPTY
|
151
|
+
elsif value.is_a? Array
|
152
|
+
Rectangle2D.new(*value)
|
153
|
+
else
|
154
|
+
value
|
155
|
+
end
|
156
|
+
},
|
157
|
+
:insets => lambda { |value|
|
158
|
+
if value == :empty
|
159
|
+
Insets::EMPTY
|
160
|
+
elsif value.is_a? Numeric
|
161
|
+
Insets.new(value)
|
162
|
+
elsif value.is_a? Array
|
163
|
+
# top/bottom, left/right
|
164
|
+
value = [value[0], value[1], value[0], value[1]] if value.size == 2
|
165
|
+
Insets.new(*value)
|
166
|
+
else
|
167
|
+
value
|
168
|
+
end
|
169
|
+
},
|
170
|
+
}
|
171
|
+
|
172
|
+
ENUM_CACHE = {}
|
173
|
+
|
174
|
+
# Store enum mapping overrides
|
175
|
+
ENUM_OVERRIDES = {Java::JavafxAnimation::PathTransition::OrientationType => {:orthogonal_to_tangent => :orthogonal},
|
176
|
+
Java::JavafxSceneEffect::BlendMode => {:src_over => :over, :src_atop => :atop, :color_dodge => :dodge, :color_burn => :burn},
|
177
|
+
Java::JavafxSceneControl::ContentDisplay => {:graphic_only => :graphic, :text_only => :text},
|
178
|
+
Java::JavafxSceneEffect::BlurType => {:one_pass_box => [:one, :one_pass], :two_pass_box => [:two, :two_pass], :three_pass_box => [:three, :three_pass]},
|
179
|
+
Java::JavafxStage::Modality => {:window_modal => :window, :application_modal => [:application, :app]}}
|
180
|
+
|
181
|
+
# sets the given overrides for the given class/enum
|
182
|
+
def self.set_overrides_for(enum_class,ovr)
|
183
|
+
ENUM_OVERRIDES[enum_class] = ovr
|
184
|
+
end
|
185
|
+
|
186
|
+
# Given a class, returns a hash of lowercase strings mapped to Java Enums
|
187
|
+
def self.map_enums(enum_class)
|
188
|
+
res = Hash[enum_class.java_class.enum_constants.map {|i| [i.to_s.downcase, i] }]
|
189
|
+
(ENUM_OVERRIDES[enum_class]||[]).each do |oldk, newks|
|
190
|
+
[newks].flatten.each do |newk|
|
191
|
+
res[newk.to_s] = res[oldk.to_s]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
res
|
195
|
+
end
|
196
|
+
|
197
|
+
def self.parse_ruby_symbols(const, enum)
|
198
|
+
ENUM_CACHE[enum] = JRubyFX::Utils::CommonConverters.map_enums(enum) if ENUM_CACHE[enum] == nil
|
199
|
+
ENUM_CACHE[enum][const.to_s] || const
|
200
|
+
end
|
201
|
+
|
202
|
+
def self.convert_args(values, converters)
|
203
|
+
converter = converters.find { |e| e.length == values.length }
|
204
|
+
converter = Array.new(values.length) unless converter
|
205
|
+
|
206
|
+
# FIXME: Better error reporting on many things which can fail
|
207
|
+
i = 0
|
208
|
+
values = values.inject([]) do |s, value|
|
209
|
+
conv = converter[i]
|
210
|
+
if conv.kind_of? Proc
|
211
|
+
s << conv.call(value)
|
212
|
+
else
|
213
|
+
s << CONVERTERS[converter[i]].call(value)
|
214
|
+
end
|
215
|
+
i += 1
|
216
|
+
s
|
217
|
+
end
|
218
|
+
return values
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
end
|