shoes-swt 4.0.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +84 -0
- data/Gemfile +24 -0
- data/Guardfile +11 -0
- data/LICENSE +31 -0
- data/README.md +201 -0
- data/lib/shoes/swt.rb +118 -0
- data/lib/shoes/swt/animation.rb +46 -0
- data/lib/shoes/swt/app.rb +314 -0
- data/lib/shoes/swt/arc.rb +71 -0
- data/lib/shoes/swt/background.rb +41 -0
- data/lib/shoes/swt/border.rb +41 -0
- data/lib/shoes/swt/button.rb +18 -0
- data/lib/shoes/swt/check.rb +14 -0
- data/lib/shoes/swt/check_button.rb +19 -0
- data/lib/shoes/swt/color.rb +49 -0
- data/lib/shoes/swt/color_factory.rb +32 -0
- data/lib/shoes/swt/common/child.rb +16 -0
- data/lib/shoes/swt/common/clickable.rb +68 -0
- data/lib/shoes/swt/common/container.rb +28 -0
- data/lib/shoes/swt/common/fill.rb +38 -0
- data/lib/shoes/swt/common/painter.rb +92 -0
- data/lib/shoes/swt/common/painter_updates_position.rb +12 -0
- data/lib/shoes/swt/common/remove.rb +30 -0
- data/lib/shoes/swt/common/resource.rb +29 -0
- data/lib/shoes/swt/common/selection_listener.rb +14 -0
- data/lib/shoes/swt/common/stroke.rb +42 -0
- data/lib/shoes/swt/common/update_position.rb +15 -0
- data/lib/shoes/swt/common/visibility.rb +13 -0
- data/lib/shoes/swt/dialog.rb +90 -0
- data/lib/shoes/swt/disposed_protection.rb +23 -0
- data/lib/shoes/swt/download.rb +24 -0
- data/lib/shoes/swt/font.rb +32 -0
- data/lib/shoes/swt/gradient.rb +92 -0
- data/lib/shoes/swt/image.rb +128 -0
- data/lib/shoes/swt/image_pattern.rb +31 -0
- data/lib/shoes/swt/input_box.rb +73 -0
- data/lib/shoes/swt/key_listener.rb +145 -0
- data/lib/shoes/swt/line.rb +60 -0
- data/lib/shoes/swt/link.rb +31 -0
- data/lib/shoes/swt/link_segment.rb +111 -0
- data/lib/shoes/swt/list_box.rb +48 -0
- data/lib/shoes/swt/mouse_move_listener.rb +67 -0
- data/lib/shoes/swt/oval.rb +52 -0
- data/lib/shoes/swt/progress.rb +35 -0
- data/lib/shoes/swt/radio.rb +29 -0
- data/lib/shoes/swt/radio_group.rb +54 -0
- data/lib/shoes/swt/rect.rb +30 -0
- data/lib/shoes/swt/rect_painter.rb +23 -0
- data/lib/shoes/swt/redrawing_aspect.rb +123 -0
- data/lib/shoes/swt/shape.rb +133 -0
- data/lib/shoes/swt/shoes_layout.rb +43 -0
- data/lib/shoes/swt/slot.rb +39 -0
- data/lib/shoes/swt/sound.rb +119 -0
- data/lib/shoes/swt/star.rb +50 -0
- data/lib/shoes/swt/support/jl1.0.1.jar +0 -0
- data/lib/shoes/swt/support/jogg-0.0.7.jar +0 -0
- data/lib/shoes/swt/support/jorbis-0.0.15.jar +0 -0
- data/lib/shoes/swt/support/log4j-1.2.16.jar +0 -0
- data/lib/shoes/swt/support/mp3spi1.9.5.jar +0 -0
- data/lib/shoes/swt/support/tritonus_share.jar +0 -0
- data/lib/shoes/swt/support/vorbisspi1.0.3.jar +0 -0
- data/lib/shoes/swt/swt_button.rb +56 -0
- data/lib/shoes/swt/text_block.rb +124 -0
- data/lib/shoes/swt/text_block/centered_text_segment.rb +22 -0
- data/lib/shoes/swt/text_block/cursor_painter.rb +53 -0
- data/lib/shoes/swt/text_block/fitter.rb +212 -0
- data/lib/shoes/swt/text_block/painter.rb +47 -0
- data/lib/shoes/swt/text_block/text_font_factory.rb +50 -0
- data/lib/shoes/swt/text_block/text_segment.rb +108 -0
- data/lib/shoes/swt/text_block/text_segment_collection.rb +160 -0
- data/lib/shoes/swt/text_block/text_style_factory.rb +88 -0
- data/lib/shoes/swt/timer.rb +19 -0
- data/lib/shoes/swt/tooling/leak_hunter.rb +35 -0
- data/lib/shoes/swt/version.rb +5 -0
- data/manifests/common.rb +34 -0
- data/manifests/shoes-swt.rb +29 -0
- data/shoes-swt.gemspec +24 -0
- data/spec/code_coverage.rb +14 -0
- data/spec/shoes/animation_spec.rb +65 -0
- data/spec/shoes/app_spec.rb +484 -0
- data/spec/shoes/arc_spec.rb +51 -0
- data/spec/shoes/background_spec.rb +53 -0
- data/spec/shoes/border_spec.rb +47 -0
- data/spec/shoes/builtin_methods_spec.rb +110 -0
- data/spec/shoes/button_spec.rb +44 -0
- data/spec/shoes/check_spec.rb +35 -0
- data/spec/shoes/cli_spec.rb +15 -0
- data/spec/shoes/color_spec.rb +408 -0
- data/spec/shoes/common/inspect_spec.rb +26 -0
- data/spec/shoes/common/remove_spec.rb +38 -0
- data/spec/shoes/common/style_normalizer_spec.rb +28 -0
- data/spec/shoes/common/style_spec.rb +147 -0
- data/spec/shoes/configuration_spec.rb +36 -0
- data/spec/shoes/constants_spec.rb +38 -0
- data/spec/shoes/dialog_spec.rb +163 -0
- data/spec/shoes/dimension_spec.rb +407 -0
- data/spec/shoes/dimensions_spec.rb +837 -0
- data/spec/shoes/download_spec.rb +142 -0
- data/spec/shoes/flow_spec.rb +133 -0
- data/spec/shoes/font_spec.rb +37 -0
- data/spec/shoes/framework_learning_spec.rb +30 -0
- data/spec/shoes/gradient_spec.rb +32 -0
- data/spec/shoes/helpers/fake_element.rb +17 -0
- data/spec/shoes/helpers/inspect_helpers.rb +5 -0
- data/spec/shoes/helpers/sample17_helper.rb +66 -0
- data/spec/shoes/image_spec.rb +49 -0
- data/spec/shoes/images/shoe.jpg +0 -0
- data/spec/shoes/input_box_spec.rb +80 -0
- data/spec/shoes/integration_spec.rb +20 -0
- data/spec/shoes/internal_app_spec.rb +141 -0
- data/spec/shoes/keypress_spec.rb +11 -0
- data/spec/shoes/keyrelease_spec.rb +12 -0
- data/spec/shoes/line_spec.rb +49 -0
- data/spec/shoes/link_spec.rb +105 -0
- data/spec/shoes/list_box_spec.rb +74 -0
- data/spec/shoes/logger/ruby_spec.rb +8 -0
- data/spec/shoes/logger_spec.rb +45 -0
- data/spec/shoes/oval_spec.rb +24 -0
- data/spec/shoes/point_spec.rb +71 -0
- data/spec/shoes/progress_spec.rb +54 -0
- data/spec/shoes/radio_spec.rb +32 -0
- data/spec/shoes/rect_spec.rb +39 -0
- data/spec/shoes/renamed_delegate_spec.rb +70 -0
- data/spec/shoes/shape_spec.rb +95 -0
- data/spec/shoes/shared_examples/button.rb +6 -0
- data/spec/shoes/shared_examples/changeable.rb +26 -0
- data/spec/shoes/shared_examples/clickable.rb +5 -0
- data/spec/shoes/shared_examples/common_methods.rb +35 -0
- data/spec/shoes/shared_examples/dimensions.rb +32 -0
- data/spec/shoes/shared_examples/dsl.rb +44 -0
- data/spec/shoes/shared_examples/dsl/animate.rb +29 -0
- data/spec/shoes/shared_examples/dsl/arc.rb +45 -0
- data/spec/shoes/shared_examples/dsl/background.rb +26 -0
- data/spec/shoes/shared_examples/dsl/border.rb +10 -0
- data/spec/shoes/shared_examples/dsl/button.rb +5 -0
- data/spec/shoes/shared_examples/dsl/cap.rb +6 -0
- data/spec/shoes/shared_examples/dsl/check.rb +11 -0
- data/spec/shoes/shared_examples/dsl/edit_box.rb +8 -0
- data/spec/shoes/shared_examples/dsl/edit_line.rb +8 -0
- data/spec/shoes/shared_examples/dsl/editable_element.rb +29 -0
- data/spec/shoes/shared_examples/dsl/fill.rb +27 -0
- data/spec/shoes/shared_examples/dsl/flow.rb +15 -0
- data/spec/shoes/shared_examples/dsl/gradient.rb +62 -0
- data/spec/shoes/shared_examples/dsl/image.rb +21 -0
- data/spec/shoes/shared_examples/dsl/line.rb +9 -0
- data/spec/shoes/shared_examples/dsl/nofill.rb +6 -0
- data/spec/shoes/shared_examples/dsl/nostroke.rb +6 -0
- data/spec/shoes/shared_examples/dsl/oval.rb +88 -0
- data/spec/shoes/shared_examples/dsl/pattern.rb +34 -0
- data/spec/shoes/shared_examples/dsl/progress.rb +7 -0
- data/spec/shoes/shared_examples/dsl/rect.rb +92 -0
- data/spec/shoes/shared_examples/dsl/rgb.rb +26 -0
- data/spec/shoes/shared_examples/dsl/shape.rb +21 -0
- data/spec/shoes/shared_examples/dsl/star.rb +48 -0
- data/spec/shoes/shared_examples/dsl/stroke.rb +30 -0
- data/spec/shoes/shared_examples/dsl/strokewidth.rb +19 -0
- data/spec/shoes/shared_examples/dsl/style.rb +32 -0
- data/spec/shoes/shared_examples/dsl/text_elements.rb +81 -0
- data/spec/shoes/shared_examples/dsl/video.rb +5 -0
- data/spec/shoes/shared_examples/dsl_app_context.rb +8 -0
- data/spec/shoes/shared_examples/hover_leave.rb +11 -0
- data/spec/shoes/shared_examples/parent.rb +6 -0
- data/spec/shoes/shared_examples/scroll.rb +41 -0
- data/spec/shoes/shared_examples/shared_element_method.rb +60 -0
- data/spec/shoes/shared_examples/slot.rb +331 -0
- data/spec/shoes/shared_examples/state.rb +19 -0
- data/spec/shoes/shared_examples/style.rb +82 -0
- data/spec/shoes/slot_spec.rb +130 -0
- data/spec/shoes/sound_spec.rb +15 -0
- data/spec/shoes/span_spec.rb +112 -0
- data/spec/shoes/spec_helper.rb +24 -0
- data/spec/shoes/stack_spec.rb +79 -0
- data/spec/shoes/star_spec.rb +31 -0
- data/spec/shoes/text_block_dimensions_spec.rb +75 -0
- data/spec/shoes/text_block_spec.rb +270 -0
- data/spec/shoes/url_spec.rb +68 -0
- data/spec/shoes/widget_spec.rb +70 -0
- data/spec/shoes_spec.rb +44 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/swt_shoes/animation_spec.rb +86 -0
- data/spec/swt_shoes/app_spec.rb +84 -0
- data/spec/swt_shoes/arc_spec.rb +103 -0
- data/spec/swt_shoes/background_spec.rb +67 -0
- data/spec/swt_shoes/border_spec.rb +52 -0
- data/spec/swt_shoes/button_spec.rb +101 -0
- data/spec/swt_shoes/check_spec.rb +28 -0
- data/spec/swt_shoes/color_factory_spec.rb +49 -0
- data/spec/swt_shoes/color_spec.rb +67 -0
- data/spec/swt_shoes/common/painter_spec.rb +49 -0
- data/spec/swt_shoes/common/remove_spec.rb +53 -0
- data/spec/swt_shoes/configuration_spec.rb +12 -0
- data/spec/swt_shoes/dialog_spec.rb +106 -0
- data/spec/swt_shoes/disposed_protection_spec.rb +49 -0
- data/spec/swt_shoes/flow_spec.rb +36 -0
- data/spec/swt_shoes/font_spec.rb +33 -0
- data/spec/swt_shoes/gradient_spec.rb +31 -0
- data/spec/swt_shoes/image_pattern_spec.rb +35 -0
- data/spec/swt_shoes/image_spec.rb +100 -0
- data/spec/swt_shoes/input_box_spec.rb +116 -0
- data/spec/swt_shoes/integration_spec.rb +27 -0
- data/spec/swt_shoes/key_listener_spec.rb +325 -0
- data/spec/swt_shoes/line_spec.rb +49 -0
- data/spec/swt_shoes/link_segment_spec.rb +120 -0
- data/spec/swt_shoes/link_spec.rb +54 -0
- data/spec/swt_shoes/list_box_spec.rb +56 -0
- data/spec/swt_shoes/minimal.png +0 -0
- data/spec/swt_shoes/mouse_move_listener_spec.rb +123 -0
- data/spec/swt_shoes/oval_spec.rb +51 -0
- data/spec/swt_shoes/progress_spec.rb +44 -0
- data/spec/swt_shoes/radio_group_spec.rb +73 -0
- data/spec/swt_shoes/radio_spec.rb +56 -0
- data/spec/swt_shoes/rect_painter_spec.rb +45 -0
- data/spec/swt_shoes/rect_spec.rb +19 -0
- data/spec/swt_shoes/shape_spec.rb +84 -0
- data/spec/swt_shoes/shared_examples/button.rb +21 -0
- data/spec/swt_shoes/shared_examples/clickable.rb +85 -0
- data/spec/swt_shoes/shared_examples/movable.rb +36 -0
- data/spec/swt_shoes/shared_examples/paintable.rb +7 -0
- data/spec/swt_shoes/shared_examples/painter.rb +83 -0
- data/spec/swt_shoes/shared_examples/pattern.rb +32 -0
- data/spec/swt_shoes/shared_examples/removable.rb +41 -0
- data/spec/swt_shoes/shared_examples/swt_app_context.rb +23 -0
- data/spec/swt_shoes/shared_examples/visibility.rb +15 -0
- data/spec/swt_shoes/shell_control_listener_spec.rb +23 -0
- data/spec/swt_shoes/slot_spec.rb +24 -0
- data/spec/swt_shoes/sound.rb +10 -0
- data/spec/swt_shoes/spec_helper.rb +31 -0
- data/spec/swt_shoes/star_spec.rb +47 -0
- data/spec/swt_shoes/text_block/centered_text_segment_spec.rb +16 -0
- data/spec/swt_shoes/text_block/cursor_painter_spec.rb +120 -0
- data/spec/swt_shoes/text_block/fitter_spec.rb +213 -0
- data/spec/swt_shoes/text_block/painter_spec.rb +212 -0
- data/spec/swt_shoes/text_block/text_font_factory_spec.rb +40 -0
- data/spec/swt_shoes/text_block/text_segment_collection_spec.rb +256 -0
- data/spec/swt_shoes/text_block/text_segment_spec.rb +135 -0
- data/spec/swt_shoes/text_block_spec.rb +199 -0
- metadata +496 -0
@@ -0,0 +1,256 @@
|
|
1
|
+
require 'swt_shoes/spec_helper'
|
2
|
+
|
3
|
+
describe Shoes::Swt::TextBlock::TextSegmentCollection do
|
4
|
+
include_context "swt app"
|
5
|
+
|
6
|
+
let(:first_segment) { create_segment("first", "first") }
|
7
|
+
let(:second_segment) { create_segment("second", "rest") }
|
8
|
+
let(:dsl) { double("dsl", font: "", size: 16, style:{}) }
|
9
|
+
|
10
|
+
let(:gc) { double("gc") }
|
11
|
+
let(:default_text_styles) {
|
12
|
+
{
|
13
|
+
:fg => :fg,
|
14
|
+
:bg => :bg,
|
15
|
+
:strikecolor => :strikecolor,
|
16
|
+
:undercolor => :undercolor,
|
17
|
+
:font_detail => {
|
18
|
+
:name => "font name",
|
19
|
+
:size => 12,
|
20
|
+
:styles => [::Swt::SWT::NORMAL]
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
describe "with one segment" do
|
26
|
+
subject { Shoes::Swt::TextBlock::TextSegmentCollection.new(dsl,
|
27
|
+
[first_segment],
|
28
|
+
default_text_styles) }
|
29
|
+
|
30
|
+
before do
|
31
|
+
allow(dsl).to receive(:text) { first_segment.text }
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should have length" do
|
35
|
+
expect(subject.length).to eq(1)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "delegates drawing" do
|
39
|
+
subject.draw(gc)
|
40
|
+
expect(first_segment).to have_received(:draw)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "applies segment styling" do
|
44
|
+
styles = [[0..1, [double("segment", style:{stroke: :blue})]]]
|
45
|
+
subject.style_segment_ranges(styles)
|
46
|
+
|
47
|
+
expected_style = style_with(stroke: :blue, fg: :blue)
|
48
|
+
expect(first_segment).to have_received(:set_style).with(expected_style, 0..1)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "only gets default styling if segment is missing opts" do
|
52
|
+
styles = [[0..1, [double("segment")]]]
|
53
|
+
subject.style_segment_ranges(styles)
|
54
|
+
expect(first_segment).to have_received(:set_style).with(default_text_styles, 0..1)
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "links" do
|
58
|
+
it "styles links" do
|
59
|
+
dsl_link = create_link("linky")
|
60
|
+
styles = [[0..1, [dsl_link]]]
|
61
|
+
subject.style_segment_ranges(styles)
|
62
|
+
|
63
|
+
dsl_style = dsl_link.style
|
64
|
+
default_style = default_text_styles.merge(dsl_style)
|
65
|
+
expected_style = default_style.merge({underline: true, stroke: ::Shoes::COLORS[:blue], fill: nil})
|
66
|
+
expect(first_segment).to have_received(:set_style).with(expected_style, 0..1)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "creates a link segment" do
|
70
|
+
link = create_link("f")
|
71
|
+
styles = [[0..1, [link]]]
|
72
|
+
subject.create_links(styles)
|
73
|
+
|
74
|
+
expect(link.gui.link_segments.size).to eq(1)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "segment ranges" do
|
79
|
+
it "picks within the first range" do
|
80
|
+
result = subject.segment_ranges(0..2)
|
81
|
+
expect(result).to eql([[first_segment, 0..2]])
|
82
|
+
end
|
83
|
+
|
84
|
+
it "picks the full first range if too large value requested" do
|
85
|
+
result = subject.segment_ranges(0..first_segment.text.length + 10)
|
86
|
+
expect(result).to eql([[first_segment, 0..first_segment.text.length]])
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "relative text positions" do
|
91
|
+
it "should choose the segment" do
|
92
|
+
expect(subject.relative_text_position(0)).to eq(0)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should choose segment nearing end" do
|
96
|
+
cursor = first_segment.text.length - 1
|
97
|
+
expect(subject.relative_text_position(cursor)).to eq(cursor)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should choose segment at end" do
|
101
|
+
cursor = first_segment.text.length
|
102
|
+
expect_relative_position_at_end_of(cursor, first_segment)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should choose the segment when just past end" do
|
106
|
+
cursor = first_segment.text.length + 1
|
107
|
+
expect_relative_position_at_end_of(cursor, first_segment)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should choose right past end" do
|
111
|
+
cursor = first_segment.text.length + 3
|
112
|
+
expect_relative_position_at_end_of(cursor, first_segment)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should chooose the segment for -1" do
|
116
|
+
expect_relative_position_at_end_of(-1, first_segment)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should allow crazy positions past the end" do
|
120
|
+
expect_relative_position_at_end_of(1000, first_segment)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "with two segments" do
|
126
|
+
subject { Shoes::Swt::TextBlock::TextSegmentCollection.new(dsl,
|
127
|
+
[first_segment, second_segment],
|
128
|
+
default_text_styles) }
|
129
|
+
|
130
|
+
before do
|
131
|
+
allow(dsl).to receive(:text) { first_segment.text + second_segment.text }
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should have length" do
|
135
|
+
expect(subject.length).to eq(2)
|
136
|
+
end
|
137
|
+
|
138
|
+
it "picks range in first segment" do
|
139
|
+
result = subject.segment_ranges(0..2)
|
140
|
+
expect(result).to eql([[first_segment, 0..2]])
|
141
|
+
end
|
142
|
+
|
143
|
+
it "picks range in second segment" do
|
144
|
+
result = subject.segment_ranges(5..7)
|
145
|
+
expect(result).to eql([[second_segment, 0..2]])
|
146
|
+
end
|
147
|
+
|
148
|
+
it "spans both segments" do
|
149
|
+
result = subject.segment_ranges(2..7)
|
150
|
+
expect(result).to eql([[first_segment, 2..5],
|
151
|
+
[second_segment, 0..2]])
|
152
|
+
end
|
153
|
+
|
154
|
+
it "applies segment styling in first segment" do
|
155
|
+
styles = [[0..2, [double("segment", style:{stroke: :blue})]]]
|
156
|
+
subject.style_segment_ranges(styles)
|
157
|
+
|
158
|
+
expected_style = style_with(stroke: :blue, fg: :blue)
|
159
|
+
expect(first_segment).to have_received(:set_style).with(expected_style, 0..2)
|
160
|
+
expect(second_segment).to_not have_received(:set_style)
|
161
|
+
end
|
162
|
+
|
163
|
+
it "applies segment styling in second segment" do
|
164
|
+
styles = [[5..7, [double("segment", style:{stroke: :blue})]]]
|
165
|
+
subject.style_segment_ranges(styles)
|
166
|
+
|
167
|
+
expected_style = style_with(stroke: :blue, fg: :blue)
|
168
|
+
expect(first_segment).to_not have_received(:set_style)
|
169
|
+
expect(second_segment).to have_received(:set_style).with(expected_style, 0..2)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "applies segment styling in both segments" do
|
173
|
+
styles = [[2..7, [double("segment", style:{stroke: :blue})]]]
|
174
|
+
subject.style_segment_ranges(styles)
|
175
|
+
|
176
|
+
expected_style = style_with(stroke: :blue, fg: :blue)
|
177
|
+
expect(first_segment).to have_received(:set_style).with(expected_style, 2..5)
|
178
|
+
expect(second_segment).to have_received(:set_style).with(expected_style, 0..2)
|
179
|
+
end
|
180
|
+
|
181
|
+
describe "links" do
|
182
|
+
let(:link) { create_link("rstres") }
|
183
|
+
|
184
|
+
it "creates link segments in both segments" do
|
185
|
+
styles = [[2..7, [link]]]
|
186
|
+
subject.create_links(styles)
|
187
|
+
|
188
|
+
expect(link.gui.link_segments.size).to eq(2)
|
189
|
+
end
|
190
|
+
|
191
|
+
it "clears links before re-creating them" do
|
192
|
+
styles = [[2..7, [link]]]
|
193
|
+
|
194
|
+
subject.create_links(styles)
|
195
|
+
subject.create_links(styles)
|
196
|
+
|
197
|
+
expect(link.gui.link_segments.size).to eq(2)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "relative text positions" do
|
202
|
+
it "should choose the first segment" do
|
203
|
+
expect(subject.relative_text_position(0)).to eq(0)
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should choose first segment nearing end" do
|
207
|
+
cursor = first_segment.text.length - 1
|
208
|
+
expect(subject.relative_text_position(cursor)).to eq(cursor)
|
209
|
+
end
|
210
|
+
|
211
|
+
it "should choose second segment at end" do
|
212
|
+
cursor = first_segment.text.length
|
213
|
+
expect(subject.relative_text_position(cursor)).to eq(0)
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should choose the second segment" do
|
217
|
+
cursor = first_segment.text.length + 1
|
218
|
+
expect(subject.relative_text_position(cursor)).to eq(1)
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should chooose the second segment for -1" do
|
222
|
+
expect_relative_position_at_end_of(-1, second_segment)
|
223
|
+
end
|
224
|
+
|
225
|
+
it "should allow crazy positions past the end" do
|
226
|
+
expect_relative_position_at_end_of(1000, second_segment)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def create_segment(name, text)
|
232
|
+
bounds = double("bounds", x: 0, y: 0, height: 0)
|
233
|
+
layout = double(name, text: text,
|
234
|
+
line_bounds: bounds, line_count: 1)
|
235
|
+
|
236
|
+
segment = Shoes::Swt::TextBlock::TextSegment.new(dsl, text, 1)
|
237
|
+
segment.position_at(0, 0)
|
238
|
+
allow(segment).to receive(:draw)
|
239
|
+
allow(segment).to receive(:set_style)
|
240
|
+
allow(segment).to receive(:get_location).and_return(double("position", x: 0, y: 0))
|
241
|
+
allow(segment).to receive(:layout).and_return(layout)
|
242
|
+
segment
|
243
|
+
end
|
244
|
+
|
245
|
+
def create_link(text)
|
246
|
+
Shoes::Link.new(shoes_app, parent, [text])
|
247
|
+
end
|
248
|
+
|
249
|
+
def style_with(style={})
|
250
|
+
default_text_styles.merge(style)
|
251
|
+
end
|
252
|
+
|
253
|
+
def expect_relative_position_at_end_of(cursor, segment)
|
254
|
+
expect(subject.relative_text_position(cursor)).to eq(segment.text.length)
|
255
|
+
end
|
256
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'swt_shoes/spec_helper'
|
2
|
+
|
3
|
+
describe Shoes::Swt::TextBlock::TextSegment do
|
4
|
+
let(:layout) { double("layout", text: "the text",
|
5
|
+
:alignment= => nil, :justify= => nil, :spacing= => nil,
|
6
|
+
:text= => nil, :width= => nil,
|
7
|
+
disposed?: false, dispose: nil,
|
8
|
+
set_style: nil, bounds: bounds) }
|
9
|
+
let(:bounds) { Java::OrgEclipseSwtGraphics::Rectangle.new(0, 0, 0, 0) }
|
10
|
+
let(:element_left) { 0 }
|
11
|
+
let(:element_top) { 0 }
|
12
|
+
let(:segment_width) { 10 }
|
13
|
+
let(:segment_height) { 10 }
|
14
|
+
let(:left_offset) { 5 }
|
15
|
+
let(:top_offset) { 5 }
|
16
|
+
|
17
|
+
let(:font_factory) { double("font factory", create_font: font, dispose: nil) }
|
18
|
+
let(:style_factory) { double("style factory", create_style: style, dispose: nil) }
|
19
|
+
let(:font) { double("font") }
|
20
|
+
let(:style) { double("style") }
|
21
|
+
|
22
|
+
let(:style_hash) {
|
23
|
+
{
|
24
|
+
bg: double("bg"),
|
25
|
+
fg: double("fg"),
|
26
|
+
font_detail: {
|
27
|
+
name: "Comic Sans",
|
28
|
+
size: 18,
|
29
|
+
styles: nil
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
let(:dsl) { double("dsl", font: "", size: 16, style:{}) }
|
35
|
+
|
36
|
+
before(:each) do
|
37
|
+
allow(::Swt::TextLayout).to receive(:new) { layout }
|
38
|
+
allow(Shoes::Swt::TextFontFactory).to receive(:new) { font_factory }
|
39
|
+
allow(Shoes::Swt::TextStyleFactory).to receive(:new) { style_factory }
|
40
|
+
end
|
41
|
+
|
42
|
+
subject do
|
43
|
+
segment = Shoes::Swt::TextBlock::TextSegment.new(dsl, "text", segment_width)
|
44
|
+
segment.position_at(element_left, element_top)
|
45
|
+
end
|
46
|
+
|
47
|
+
context "disposal" do
|
48
|
+
it "disposes of underlying layout" do
|
49
|
+
allow(layout).to receive(:disposed?) { false }
|
50
|
+
expect(layout).to receive(:dispose)
|
51
|
+
subject.dispose
|
52
|
+
end
|
53
|
+
|
54
|
+
it "doesn't overdispose" do
|
55
|
+
allow(layout).to receive(:disposed?) { true }
|
56
|
+
expect(layout).to_not receive(:dispose)
|
57
|
+
subject.dispose
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "setting style" do
|
62
|
+
it "on full range" do
|
63
|
+
subject.set_style(style_hash)
|
64
|
+
expect(layout).to have_received(:set_style).
|
65
|
+
with(style, 0, layout.text.length - 1).
|
66
|
+
at_least(1).times
|
67
|
+
end
|
68
|
+
|
69
|
+
it "with a range" do
|
70
|
+
subject.set_style(style_hash, 1..2)
|
71
|
+
expect(layout).to have_received(:set_style).with(style, 1, 2)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "ignores empty ranges" do
|
75
|
+
subject.set_style(style_hash, 0...0)
|
76
|
+
expect(layout).to_not have_received(:set_style).with(style, 0, 0)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "shrinking on initialization" do
|
81
|
+
it "should not shrink when enough containing width" do
|
82
|
+
expect(subject.layout).to_not have_received(:width=)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "shrinks when too long for container" do
|
86
|
+
bounds.width = segment_width + 10
|
87
|
+
expect(subject.layout).to have_received(:width=).with(segment_width)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "bounds checking" do
|
92
|
+
before(:each) do
|
93
|
+
set_bounds(0, 0, segment_width, segment_height)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "checks boundaries" do
|
97
|
+
expect(subject.in_bounds?(1,1)).to be_truthy
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "offsets left" do
|
101
|
+
let(:element_left) { left_offset }
|
102
|
+
|
103
|
+
it "checks boundaries" do
|
104
|
+
expect(subject.in_bounds?(segment_width + left_offset - 1, 0)).to be_truthy
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "offsets top" do
|
109
|
+
let(:element_top) { top_offset }
|
110
|
+
|
111
|
+
it "checks boundaries" do
|
112
|
+
expect(subject.in_bounds?(0, segment_height + top_offset - 1)).to be_truthy
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def set_bounds(x, y, width, height)
|
117
|
+
bounds.x = x
|
118
|
+
bounds.y = y
|
119
|
+
bounds.width = width
|
120
|
+
bounds.height = height
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "dispose" do
|
125
|
+
it "should dispose its Swt fonts" do
|
126
|
+
subject.dispose
|
127
|
+
expect(font_factory).to have_received(:dispose)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should dispose its Swt colors" do
|
131
|
+
subject.dispose
|
132
|
+
expect(style_factory).to have_received(:dispose)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require 'swt_shoes/spec_helper'
|
2
|
+
|
3
|
+
describe Shoes::Swt::TextBlock do
|
4
|
+
include_context "swt app"
|
5
|
+
|
6
|
+
let(:height) { 100 }
|
7
|
+
let(:width) { 200 }
|
8
|
+
let(:margin) { 10 }
|
9
|
+
let(:dsl) { double("dsl", app: shoes_app, text: "text",
|
10
|
+
margin_left: 0, margin_right: 0,
|
11
|
+
margin_top: 0, margin_bottom: 0,
|
12
|
+
pass_coordinates?: nil).as_null_object }
|
13
|
+
|
14
|
+
subject { Shoes::Swt::TextBlock.new(dsl, swt_app) }
|
15
|
+
|
16
|
+
it_behaves_like "paintable"
|
17
|
+
it_behaves_like "updating visibility"
|
18
|
+
it_behaves_like "clickable backend"
|
19
|
+
|
20
|
+
# reported nil, caused trouble in simple-downloader.rb
|
21
|
+
it 'initially responds with empty segments' do
|
22
|
+
expect(subject.segments).to be_empty
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "bounds checking" do
|
26
|
+
it "delegates to segment" do
|
27
|
+
segment = double()
|
28
|
+
subject.segments = [segment]
|
29
|
+
expect(segment).to receive(:in_bounds?)
|
30
|
+
|
31
|
+
subject.in_bounds?(1,1)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "contents alignment" do
|
36
|
+
let(:layout_width) { 100 }
|
37
|
+
let(:layout_height) { 200 }
|
38
|
+
let(:line_height) { 10 }
|
39
|
+
|
40
|
+
let(:bounds) { double("bounds", height: layout_height, width: layout_width) }
|
41
|
+
let(:unused_bounds) { double("unused bounds", height: 0, width: 0) }
|
42
|
+
|
43
|
+
let(:fitter) { double("fitter") }
|
44
|
+
let(:segment) { create_segment }
|
45
|
+
let(:second_segment) { create_segment }
|
46
|
+
|
47
|
+
let(:current_position) { Shoes::Slot::CurrentPosition.new(0, 0) }
|
48
|
+
|
49
|
+
before(:each) do
|
50
|
+
allow(::Shoes::Swt::TextBlock::Fitter).to receive(:new) { fitter }
|
51
|
+
allow(fitter).to receive(:fit_it_in).and_return([segment], [second_segment])
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "with single segment" do
|
55
|
+
before(:each) do
|
56
|
+
allow(dsl).to receive(:absolute_left) { 50 }
|
57
|
+
allow(dsl).to receive(:absolute_top) { 0 }
|
58
|
+
allow(dsl).to receive(:absolute_bottom) { layout_height }
|
59
|
+
end
|
60
|
+
|
61
|
+
it "positions single line of text" do
|
62
|
+
expect(dsl).to receive(:absolute_right=).with(layout_width + 50)
|
63
|
+
expect(dsl).to receive(:absolute_bottom=).with(layout_height)
|
64
|
+
|
65
|
+
when_aligns_and_positions
|
66
|
+
|
67
|
+
expect(current_position.y).to eq(layout_height - line_height)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "positions single line with margin" do
|
71
|
+
allow(dsl).to receive_messages(margin_left: margin, margin_right: margin,
|
72
|
+
margin_top: margin, margin_bottom: margin)
|
73
|
+
|
74
|
+
expect(dsl).to receive(:absolute_right=).with(layout_width + 50 + margin)
|
75
|
+
expect(dsl).to receive(:absolute_bottom=).with(layout_height + 2 * margin)
|
76
|
+
|
77
|
+
when_aligns_and_positions
|
78
|
+
|
79
|
+
expect(current_position.y).to eq(layout_height - line_height)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "pushes to next line if ends in newline" do
|
83
|
+
allow(dsl).to receive(:text) { "text\n" }
|
84
|
+
|
85
|
+
expect(dsl).to receive(:absolute_right=).with(50)
|
86
|
+
expect(dsl).to receive(:absolute_bottom=).with(layout_height)
|
87
|
+
|
88
|
+
when_aligns_and_positions
|
89
|
+
|
90
|
+
expect(current_position.y).to eq(layout_height)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "disposes of prior segments" do
|
94
|
+
subject.contents_alignment(current_position)
|
95
|
+
expect(segment).to receive(:dispose)
|
96
|
+
|
97
|
+
subject.contents_alignment(current_position)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should not dispose any segments" do
|
101
|
+
expect(segment).not_to receive(:dispose)
|
102
|
+
expect(second_segment).not_to receive(:dispose)
|
103
|
+
|
104
|
+
subject.contents_alignment(current_position)
|
105
|
+
end
|
106
|
+
|
107
|
+
context "on the second call" do
|
108
|
+
before(:each) do
|
109
|
+
subject.contents_alignment(current_position)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should only dispose old segment" do
|
113
|
+
expect(segment).to receive(:dispose)
|
114
|
+
expect(second_segment).not_to receive(:dispose)
|
115
|
+
|
116
|
+
subject.contents_alignment(current_position)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should dispose all segments on remove" do
|
120
|
+
allow(swt_app).to receive(:remove_listener)
|
121
|
+
|
122
|
+
expect(segment).to receive(:dispose).at_least(1).times
|
123
|
+
expect(second_segment).to receive(:dispose).at_least(1).times
|
124
|
+
|
125
|
+
subject.contents_alignment(current_position)
|
126
|
+
subject.remove
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "with two segments" do
|
132
|
+
before(:each) do
|
133
|
+
allow(dsl).to receive(:parent) { double("dsl parent", absolute_left: 0) }
|
134
|
+
allow(dsl).to receive(:absolute_bottom) { layout_height }
|
135
|
+
|
136
|
+
current_position.next_line_start = 0
|
137
|
+
|
138
|
+
allow(fitter).to receive(:fit_it_in) {
|
139
|
+
[create_segment("unused segment"),
|
140
|
+
create_segment("segment")]
|
141
|
+
}
|
142
|
+
end
|
143
|
+
|
144
|
+
it "positions in two segments" do
|
145
|
+
expect(dsl).to receive(:absolute_right=).with(layout_width)
|
146
|
+
expect(dsl).to receive(:absolute_bottom=).with(layout_height)
|
147
|
+
|
148
|
+
when_aligns_and_positions
|
149
|
+
|
150
|
+
expect(current_position.y).to eq(layout_height - line_height)
|
151
|
+
end
|
152
|
+
|
153
|
+
it "positions in two segments with margins" do
|
154
|
+
allow(dsl).to receive_messages(margin_left: margin, margin_right: margin,
|
155
|
+
margin_top: margin, margin_bottom: margin)
|
156
|
+
|
157
|
+
expect(dsl).to receive(:absolute_right=).with(layout_width + margin)
|
158
|
+
expect(dsl).to receive(:absolute_bottom=).with(layout_height + 2 * margin)
|
159
|
+
|
160
|
+
when_aligns_and_positions
|
161
|
+
|
162
|
+
expect(current_position.y).to eq(layout_height - line_height)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context "links" do
|
168
|
+
let(:link) { Shoes::Link.new(shoes_app, subject, ["link"]) }
|
169
|
+
|
170
|
+
before(:each) do
|
171
|
+
allow(dsl).to receive(:links) { [link] }
|
172
|
+
allow(swt_app).to receive(:remove_listener)
|
173
|
+
end
|
174
|
+
|
175
|
+
it "clears links" do
|
176
|
+
expect(link).to receive(:remove)
|
177
|
+
subject.remove
|
178
|
+
end
|
179
|
+
|
180
|
+
it "clears links on replace" do
|
181
|
+
expect(link).to receive(:remove)
|
182
|
+
subject.replace("text")
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def create_segment(name="segment", width=layout_width,
|
187
|
+
height=layout_height, line_height=line_height)
|
188
|
+
bounds = double("bounds", width: width, height: height)
|
189
|
+
double(name, disposed?: false,
|
190
|
+
width: width, height: height,
|
191
|
+
last_line_width: width, last_line_height: line_height,
|
192
|
+
bounds: bounds)
|
193
|
+
end
|
194
|
+
|
195
|
+
def when_aligns_and_positions
|
196
|
+
subject.contents_alignment(current_position)
|
197
|
+
subject.adjust_current_position(current_position)
|
198
|
+
end
|
199
|
+
end
|