konpeito 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +75 -0
- data/CONTRIBUTING.md +123 -0
- data/LICENSE +21 -0
- data/README.md +257 -0
- data/Rakefile +11 -0
- data/bin/konpeito +6 -0
- data/konpeito.gemspec +43 -0
- data/lib/konpeito/ast/typed_ast.rb +620 -0
- data/lib/konpeito/ast/visitor.rb +78 -0
- data/lib/konpeito/cache/cache_manager.rb +230 -0
- data/lib/konpeito/cache/dependency_graph.rb +192 -0
- data/lib/konpeito/cache.rb +8 -0
- data/lib/konpeito/cli/base_command.rb +187 -0
- data/lib/konpeito/cli/build_command.rb +220 -0
- data/lib/konpeito/cli/check_command.rb +104 -0
- data/lib/konpeito/cli/config.rb +231 -0
- data/lib/konpeito/cli/deps_command.rb +128 -0
- data/lib/konpeito/cli/doctor_command.rb +340 -0
- data/lib/konpeito/cli/fmt_command.rb +199 -0
- data/lib/konpeito/cli/init_command.rb +312 -0
- data/lib/konpeito/cli/lsp_command.rb +40 -0
- data/lib/konpeito/cli/run_command.rb +150 -0
- data/lib/konpeito/cli/test_command.rb +248 -0
- data/lib/konpeito/cli/watch_command.rb +212 -0
- data/lib/konpeito/cli.rb +301 -0
- data/lib/konpeito/codegen/builtin_methods.rb +229 -0
- data/lib/konpeito/codegen/cruby_backend.rb +1090 -0
- data/lib/konpeito/codegen/debug_info.rb +352 -0
- data/lib/konpeito/codegen/inliner.rb +486 -0
- data/lib/konpeito/codegen/jvm_backend.rb +197 -0
- data/lib/konpeito/codegen/jvm_generator.rb +13412 -0
- data/lib/konpeito/codegen/llvm_generator.rb +13191 -0
- data/lib/konpeito/codegen/loop_optimizer.rb +363 -0
- data/lib/konpeito/codegen/monomorphizer.rb +359 -0
- data/lib/konpeito/codegen/profile_runtime.c +341 -0
- data/lib/konpeito/codegen/profiler.rb +99 -0
- data/lib/konpeito/compiler.rb +592 -0
- data/lib/konpeito/dependency_resolver.rb +296 -0
- data/lib/konpeito/diagnostics/collector.rb +127 -0
- data/lib/konpeito/diagnostics/diagnostic.rb +237 -0
- data/lib/konpeito/diagnostics/renderer.rb +144 -0
- data/lib/konpeito/formatter/formatter.rb +1214 -0
- data/lib/konpeito/hir/builder.rb +7167 -0
- data/lib/konpeito/hir/nodes.rb +2465 -0
- data/lib/konpeito/lsp/document_manager.rb +820 -0
- data/lib/konpeito/lsp/server.rb +183 -0
- data/lib/konpeito/lsp/transport.rb +38 -0
- data/lib/konpeito/parser/prism_adapter.rb +65 -0
- data/lib/konpeito/platform.rb +103 -0
- data/lib/konpeito/profile/report.rb +136 -0
- data/lib/konpeito/rbs_inline/preprocessor.rb +199 -0
- data/lib/konpeito/stdlib/compression/compression.rb +72 -0
- data/lib/konpeito/stdlib/compression/compression.rbs +60 -0
- data/lib/konpeito/stdlib/compression/compression_native.c +415 -0
- data/lib/konpeito/stdlib/compression/extconf.rb +19 -0
- data/lib/konpeito/stdlib/crypto/crypto.rb +85 -0
- data/lib/konpeito/stdlib/crypto/crypto.rbs +74 -0
- data/lib/konpeito/stdlib/crypto/crypto_native.c +312 -0
- data/lib/konpeito/stdlib/crypto/extconf.rb +40 -0
- data/lib/konpeito/stdlib/http/extconf.rb +19 -0
- data/lib/konpeito/stdlib/http/http.rb +125 -0
- data/lib/konpeito/stdlib/http/http.rbs +57 -0
- data/lib/konpeito/stdlib/http/http_native.c +440 -0
- data/lib/konpeito/stdlib/json/extconf.rb +17 -0
- data/lib/konpeito/stdlib/json/json.rb +44 -0
- data/lib/konpeito/stdlib/json/json.rbs +33 -0
- data/lib/konpeito/stdlib/json/json_native.c +286 -0
- data/lib/konpeito/stdlib/ui/extconf.rb +216 -0
- data/lib/konpeito/stdlib/ui/konpeito_ui_native.cpp +1625 -0
- data/lib/konpeito/stdlib/ui/konpeito_ui_native.h +162 -0
- data/lib/konpeito/stdlib/ui/ui.rb +318 -0
- data/lib/konpeito/stdlib/ui/ui.rbs +247 -0
- data/lib/konpeito/type_checker/annotation_parser.rb +67 -0
- data/lib/konpeito/type_checker/hm_inferrer.rb +2565 -0
- data/lib/konpeito/type_checker/inferrer.rb +565 -0
- data/lib/konpeito/type_checker/rbs_loader.rb +1621 -0
- data/lib/konpeito/type_checker/type_resolver.rb +276 -0
- data/lib/konpeito/type_checker/types.rb +1434 -0
- data/lib/konpeito/type_checker/unification.rb +323 -0
- data/lib/konpeito/ui/animation/animated_state.rb +80 -0
- data/lib/konpeito/ui/animation/easing.rb +59 -0
- data/lib/konpeito/ui/animation/value_tween.rb +66 -0
- data/lib/konpeito/ui/app.rb +379 -0
- data/lib/konpeito/ui/box.rb +38 -0
- data/lib/konpeito/ui/castella.rb +70 -0
- data/lib/konpeito/ui/castella_native.rb +76 -0
- data/lib/konpeito/ui/chart/area_chart.rb +305 -0
- data/lib/konpeito/ui/chart/bar_chart.rb +288 -0
- data/lib/konpeito/ui/chart/base_chart.rb +210 -0
- data/lib/konpeito/ui/chart/chart_helpers.rb +79 -0
- data/lib/konpeito/ui/chart/gauge_chart.rb +171 -0
- data/lib/konpeito/ui/chart/heatmap_chart.rb +222 -0
- data/lib/konpeito/ui/chart/line_chart.rb +289 -0
- data/lib/konpeito/ui/chart/pie_chart.rb +219 -0
- data/lib/konpeito/ui/chart/scales.rb +77 -0
- data/lib/konpeito/ui/chart/scatter_chart.rb +303 -0
- data/lib/konpeito/ui/chart/stacked_bar_chart.rb +276 -0
- data/lib/konpeito/ui/column.rb +271 -0
- data/lib/konpeito/ui/core.rb +2199 -0
- data/lib/konpeito/ui/dsl.rb +443 -0
- data/lib/konpeito/ui/frame.rb +171 -0
- data/lib/konpeito/ui/frame_native.rb +494 -0
- data/lib/konpeito/ui/markdown/ast.rb +124 -0
- data/lib/konpeito/ui/markdown/mermaid/layout.rb +387 -0
- data/lib/konpeito/ui/markdown/mermaid/models.rb +232 -0
- data/lib/konpeito/ui/markdown/mermaid/parser.rb +519 -0
- data/lib/konpeito/ui/markdown/mermaid/renderer.rb +336 -0
- data/lib/konpeito/ui/markdown/parser.rb +805 -0
- data/lib/konpeito/ui/markdown/renderer.rb +639 -0
- data/lib/konpeito/ui/markdown/theme.rb +165 -0
- data/lib/konpeito/ui/render_node.rb +260 -0
- data/lib/konpeito/ui/row.rb +207 -0
- data/lib/konpeito/ui/spacer.rb +18 -0
- data/lib/konpeito/ui/style.rb +799 -0
- data/lib/konpeito/ui/theme.rb +563 -0
- data/lib/konpeito/ui/themes/material.rb +35 -0
- data/lib/konpeito/ui/themes/tokyo_night.rb +6 -0
- data/lib/konpeito/ui/widgets/button.rb +103 -0
- data/lib/konpeito/ui/widgets/calendar.rb +1034 -0
- data/lib/konpeito/ui/widgets/checkbox.rb +119 -0
- data/lib/konpeito/ui/widgets/container.rb +91 -0
- data/lib/konpeito/ui/widgets/data_table.rb +667 -0
- data/lib/konpeito/ui/widgets/divider.rb +29 -0
- data/lib/konpeito/ui/widgets/image.rb +105 -0
- data/lib/konpeito/ui/widgets/input.rb +485 -0
- data/lib/konpeito/ui/widgets/markdown.rb +57 -0
- data/lib/konpeito/ui/widgets/modal.rb +163 -0
- data/lib/konpeito/ui/widgets/multiline_input.rb +968 -0
- data/lib/konpeito/ui/widgets/multiline_text.rb +180 -0
- data/lib/konpeito/ui/widgets/net_image.rb +100 -0
- data/lib/konpeito/ui/widgets/progress_bar.rb +70 -0
- data/lib/konpeito/ui/widgets/radio_buttons.rb +93 -0
- data/lib/konpeito/ui/widgets/slider.rb +133 -0
- data/lib/konpeito/ui/widgets/switch.rb +84 -0
- data/lib/konpeito/ui/widgets/tabs.rb +157 -0
- data/lib/konpeito/ui/widgets/text.rb +110 -0
- data/lib/konpeito/ui/widgets/tree.rb +426 -0
- data/lib/konpeito/version.rb +5 -0
- data/lib/konpeito.rb +109 -0
- data/test_native_array.rb +172 -0
- data/test_native_array_class.rb +197 -0
- data/test_native_class.rb +151 -0
- data/tools/konpeito-asm/build.sh +65 -0
- data/tools/konpeito-asm/lib/asm-9.7.1.jar +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KArray.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KCompression.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KConditionVariable.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KCrypto.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KFile.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KHTTP.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KHash.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KJSON$Parser.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KJSON.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KMath.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KRactor.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KRactorPort.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KSizedQueue.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KThread.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KTime.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/RubyDispatch.class +0 -0
- data/tools/konpeito-asm/src/ClassIntrospector.java +312 -0
- data/tools/konpeito-asm/src/KonpeitoAssembler.java +659 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KArray.java +390 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KCompression.java +168 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KConditionVariable.java +48 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KCrypto.java +151 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KFile.java +100 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KHTTP.java +113 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KHash.java +228 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KJSON.java +405 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KMath.java +54 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KRactor.java +244 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KRactorPort.java +53 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KSizedQueue.java +49 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KThread.java +49 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KTime.java +53 -0
- data/tools/konpeito-asm/src/konpeito/runtime/RubyDispatch.java +416 -0
- metadata +267 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Markdown theme - color and size tokens for markdown rendering
|
|
2
|
+
# Integrates with the global $theme
|
|
3
|
+
|
|
4
|
+
class MarkdownTheme
|
|
5
|
+
def initialize
|
|
6
|
+
# Text colors - derive from global theme
|
|
7
|
+
@text_color = $theme.text_primary
|
|
8
|
+
@heading_color = $theme.accent
|
|
9
|
+
@link_color = $theme.accent
|
|
10
|
+
@code_color = $theme.warning
|
|
11
|
+
@emphasis_color = 0xFF9AA5CE # Slightly muted blue for italic
|
|
12
|
+
@strikethrough_color = $theme.text_secondary
|
|
13
|
+
|
|
14
|
+
# Background colors
|
|
15
|
+
@code_bg_color = $theme.bg_secondary
|
|
16
|
+
@code_inline_bg = $theme.bg_secondary
|
|
17
|
+
@blockquote_bg = $theme.accent
|
|
18
|
+
|
|
19
|
+
# Heading sizes
|
|
20
|
+
@h1_size = 28.0
|
|
21
|
+
@h2_size = 24.0
|
|
22
|
+
@h3_size = 20.0
|
|
23
|
+
@h4_size = 18.0
|
|
24
|
+
@h5_size = 16.0
|
|
25
|
+
@h6_size = 14.0
|
|
26
|
+
@base_font_size = 14.0
|
|
27
|
+
|
|
28
|
+
# Table colors
|
|
29
|
+
@table_header_bg = $theme.bg_secondary
|
|
30
|
+
@table_border_color = $theme.text_secondary
|
|
31
|
+
@checkbox_checked_color = $theme.success
|
|
32
|
+
@checkbox_unchecked_color = $theme.text_secondary
|
|
33
|
+
|
|
34
|
+
# Mermaid colors
|
|
35
|
+
@mermaid_node_fill = 0xFF4A90D9
|
|
36
|
+
@mermaid_node_stroke = 0xFF2C5F8A
|
|
37
|
+
@mermaid_node_text = 0xFFFFFFFF
|
|
38
|
+
@mermaid_edge_color = $theme.text_secondary
|
|
39
|
+
@mermaid_subgraph_bg = 0x20FFFFFF
|
|
40
|
+
@mermaid_subgraph_border = $theme.text_secondary
|
|
41
|
+
@mermaid_font_size = 12.0
|
|
42
|
+
|
|
43
|
+
# Spacing
|
|
44
|
+
@paragraph_spacing = 8.0
|
|
45
|
+
@block_spacing = 12.0
|
|
46
|
+
@list_indent = 24.0
|
|
47
|
+
@blockquote_indent = 20.0
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def text_color
|
|
51
|
+
@text_color
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def heading_color
|
|
55
|
+
@heading_color
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def link_color
|
|
59
|
+
@link_color
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def code_color
|
|
63
|
+
@code_color
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def emphasis_color
|
|
67
|
+
@emphasis_color
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def strikethrough_color
|
|
71
|
+
@strikethrough_color
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def code_bg_color
|
|
75
|
+
@code_bg_color
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def code_inline_bg
|
|
79
|
+
@code_inline_bg
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def blockquote_bg
|
|
83
|
+
@blockquote_bg
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def base_font_size
|
|
87
|
+
@base_font_size
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def paragraph_spacing
|
|
91
|
+
@paragraph_spacing
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def block_spacing
|
|
95
|
+
@block_spacing
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def list_indent
|
|
99
|
+
@list_indent
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def blockquote_indent
|
|
103
|
+
@blockquote_indent
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def table_header_bg
|
|
107
|
+
@table_header_bg
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def table_border_color
|
|
111
|
+
@table_border_color
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def checkbox_checked_color
|
|
115
|
+
@checkbox_checked_color
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def checkbox_unchecked_color
|
|
119
|
+
@checkbox_unchecked_color
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def mermaid_node_fill
|
|
123
|
+
@mermaid_node_fill
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def mermaid_node_stroke
|
|
127
|
+
@mermaid_node_stroke
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def mermaid_node_text
|
|
131
|
+
@mermaid_node_text
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def mermaid_edge_color
|
|
135
|
+
@mermaid_edge_color
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def mermaid_subgraph_bg
|
|
139
|
+
@mermaid_subgraph_bg
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def mermaid_subgraph_border
|
|
143
|
+
@mermaid_subgraph_border
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def mermaid_font_size
|
|
147
|
+
@mermaid_font_size
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def heading_size(level)
|
|
151
|
+
if level == 1
|
|
152
|
+
@h1_size
|
|
153
|
+
elsif level == 2
|
|
154
|
+
@h2_size
|
|
155
|
+
elsif level == 3
|
|
156
|
+
@h3_size
|
|
157
|
+
elsif level == 4
|
|
158
|
+
@h4_size
|
|
159
|
+
elsif level == 5
|
|
160
|
+
@h5_size
|
|
161
|
+
else
|
|
162
|
+
@h6_size
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
2
|
+
|
|
3
|
+
# RenderNode system - layout/paint dirty tracking and z-order caching
|
|
4
|
+
# Port of ~/castella/castella/render/node.py and layout_node.py
|
|
5
|
+
|
|
6
|
+
# Base render node with fine-grained dirty tracking
|
|
7
|
+
class RenderNodeBase
|
|
8
|
+
#: (untyped widget) -> void
|
|
9
|
+
def initialize(widget)
|
|
10
|
+
@widget = widget
|
|
11
|
+
@layout_dirty = true
|
|
12
|
+
@paint_dirty = true
|
|
13
|
+
@subtree_dirty = false
|
|
14
|
+
@measured_size = nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
#: () -> untyped
|
|
18
|
+
def get_widget
|
|
19
|
+
@widget
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# ===== Dirty Tracking =====
|
|
23
|
+
|
|
24
|
+
#: () -> bool
|
|
25
|
+
def is_layout_dirty
|
|
26
|
+
@layout_dirty
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#: () -> bool
|
|
30
|
+
def is_paint_dirty
|
|
31
|
+
@paint_dirty
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
#: () -> void
|
|
35
|
+
def mark_layout_dirty
|
|
36
|
+
@layout_dirty = true
|
|
37
|
+
@paint_dirty = true
|
|
38
|
+
@measured_size = nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
#: () -> void
|
|
42
|
+
def mark_paint_dirty
|
|
43
|
+
@paint_dirty = true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#: () -> bool
|
|
47
|
+
def is_subtree_dirty
|
|
48
|
+
@subtree_dirty
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
#: () -> void
|
|
52
|
+
def mark_subtree_dirty
|
|
53
|
+
@subtree_dirty = true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
#: () -> void
|
|
57
|
+
def clear_dirty
|
|
58
|
+
@layout_dirty = false
|
|
59
|
+
@paint_dirty = false
|
|
60
|
+
@subtree_dirty = false
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# ===== Layout =====
|
|
64
|
+
|
|
65
|
+
#: (untyped painter) -> Size
|
|
66
|
+
def cached_measure(painter)
|
|
67
|
+
if @measured_size == nil || @layout_dirty
|
|
68
|
+
@measured_size = @widget.measure(painter)
|
|
69
|
+
end
|
|
70
|
+
@measured_size
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# ===== Hit Testing =====
|
|
74
|
+
|
|
75
|
+
#: (Point point) -> bool
|
|
76
|
+
def hit_test(point)
|
|
77
|
+
@widget.contain(point)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Layout render node with z-order caching and child management
|
|
82
|
+
class LayoutRenderNode < RenderNodeBase
|
|
83
|
+
#: (untyped widget) -> void
|
|
84
|
+
def initialize(widget)
|
|
85
|
+
super(widget)
|
|
86
|
+
@children = []
|
|
87
|
+
@sorted_children = nil
|
|
88
|
+
@z_order_dirty = true
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# ===== Child Management =====
|
|
92
|
+
|
|
93
|
+
#: (untyped child) -> void
|
|
94
|
+
def add_child(child)
|
|
95
|
+
@children << child
|
|
96
|
+
@z_order_dirty = true
|
|
97
|
+
mark_layout_dirty
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
#: (untyped child) -> void
|
|
101
|
+
def remove_child(child)
|
|
102
|
+
i = 0
|
|
103
|
+
while i < @children.length
|
|
104
|
+
if @children[i] == child
|
|
105
|
+
@children.delete_at(i)
|
|
106
|
+
@z_order_dirty = true
|
|
107
|
+
mark_layout_dirty
|
|
108
|
+
return
|
|
109
|
+
end
|
|
110
|
+
i = i + 1
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
#: () -> void
|
|
115
|
+
def clear_children
|
|
116
|
+
@children = []
|
|
117
|
+
@sorted_children = nil
|
|
118
|
+
@z_order_dirty = true
|
|
119
|
+
mark_layout_dirty
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
#: () -> Integer
|
|
123
|
+
def child_count
|
|
124
|
+
@children.length
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
#: () -> Array
|
|
128
|
+
def get_children
|
|
129
|
+
@children
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# ===== Z-Order Management =====
|
|
133
|
+
|
|
134
|
+
#: () -> void
|
|
135
|
+
def invalidate_z_order
|
|
136
|
+
@z_order_dirty = true
|
|
137
|
+
@sorted_children = nil
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
#: () -> Array
|
|
141
|
+
def get_sorted_children
|
|
142
|
+
if @z_order_dirty || @sorted_children == nil
|
|
143
|
+
# Copy children list
|
|
144
|
+
@sorted_children = []
|
|
145
|
+
i = 0
|
|
146
|
+
while i < @children.length
|
|
147
|
+
@sorted_children << @children[i]
|
|
148
|
+
i = i + 1
|
|
149
|
+
end
|
|
150
|
+
# Sort by z_index (bubble sort - children count is typically small)
|
|
151
|
+
changed = true
|
|
152
|
+
while changed
|
|
153
|
+
changed = false
|
|
154
|
+
j = 0
|
|
155
|
+
while j < @sorted_children.length - 1
|
|
156
|
+
if @sorted_children[j].get_z_index > @sorted_children[j + 1].get_z_index
|
|
157
|
+
tmp = @sorted_children[j]
|
|
158
|
+
@sorted_children[j] = @sorted_children[j + 1]
|
|
159
|
+
@sorted_children[j + 1] = tmp
|
|
160
|
+
changed = true
|
|
161
|
+
end
|
|
162
|
+
j = j + 1
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
@z_order_dirty = false
|
|
166
|
+
end
|
|
167
|
+
@sorted_children
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Paint order: lower z-index first (background to foreground)
|
|
171
|
+
#: () -> Array
|
|
172
|
+
def iter_paint_order
|
|
173
|
+
get_sorted_children
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Hit test order: higher z-index first (foreground to background)
|
|
177
|
+
#: () -> Array
|
|
178
|
+
def iter_hit_test_order
|
|
179
|
+
sorted = get_sorted_children
|
|
180
|
+
result = []
|
|
181
|
+
i = sorted.length - 1
|
|
182
|
+
while i >= 0
|
|
183
|
+
result << sorted[i]
|
|
184
|
+
i = i - 1
|
|
185
|
+
end
|
|
186
|
+
result
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# ===== Dirty Propagation =====
|
|
190
|
+
|
|
191
|
+
#: () -> bool
|
|
192
|
+
def is_any_child_dirty
|
|
193
|
+
i = 0
|
|
194
|
+
while i < @children.length
|
|
195
|
+
if @children[i].is_dirty
|
|
196
|
+
return true
|
|
197
|
+
end
|
|
198
|
+
i = i + 1
|
|
199
|
+
end
|
|
200
|
+
false
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Scrollable layout render node with viewport culling
|
|
205
|
+
class ScrollableLayoutRenderNode < LayoutRenderNode
|
|
206
|
+
#: (untyped widget) -> void
|
|
207
|
+
def initialize(widget)
|
|
208
|
+
super(widget)
|
|
209
|
+
@scroll_x = 0.0
|
|
210
|
+
@scroll_y = 0.0
|
|
211
|
+
@viewport_width = 0.0
|
|
212
|
+
@viewport_height = 0.0
|
|
213
|
+
@viewport_set = false
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
#: () -> Float
|
|
217
|
+
def get_scroll_x
|
|
218
|
+
@scroll_x
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
#: (Float v) -> void
|
|
222
|
+
def set_scroll_x(v)
|
|
223
|
+
if @scroll_x != v
|
|
224
|
+
@scroll_x = v
|
|
225
|
+
mark_paint_dirty
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
#: () -> Float
|
|
230
|
+
def get_scroll_y
|
|
231
|
+
@scroll_y
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
#: (Float v) -> void
|
|
235
|
+
def set_scroll_y(v)
|
|
236
|
+
if @scroll_y != v
|
|
237
|
+
@scroll_y = v
|
|
238
|
+
mark_paint_dirty
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
#: (Float w, Float h) -> void
|
|
243
|
+
def set_viewport_size(w, h)
|
|
244
|
+
@viewport_width = w
|
|
245
|
+
@viewport_height = h
|
|
246
|
+
@viewport_set = true
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
#: (untyped child) -> bool
|
|
250
|
+
def is_child_visible(child)
|
|
251
|
+
if !@viewport_set
|
|
252
|
+
return true
|
|
253
|
+
end
|
|
254
|
+
cx = child.get_x - @scroll_x
|
|
255
|
+
cy = child.get_y - @scroll_y
|
|
256
|
+
cw = child.get_width
|
|
257
|
+
ch = child.get_height
|
|
258
|
+
!(cx + cw < 0.0 || cx > @viewport_width || cy + ch < 0.0 || cy > @viewport_height)
|
|
259
|
+
end
|
|
260
|
+
end
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
2
|
+
|
|
3
|
+
# Row layout - horizontal arrangement of children
|
|
4
|
+
# Port of Castella LinearLayout (horizontal axis)
|
|
5
|
+
|
|
6
|
+
class Row < Layout
|
|
7
|
+
def initialize
|
|
8
|
+
super
|
|
9
|
+
@spacing = 0.0
|
|
10
|
+
@is_scrollable = false
|
|
11
|
+
@scroll_offset = 0.0
|
|
12
|
+
@content_width = 0.0
|
|
13
|
+
@pin_right = false
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
#: (Float s) -> Row
|
|
17
|
+
def spacing(s)
|
|
18
|
+
@spacing = s
|
|
19
|
+
self
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#: () -> Row
|
|
23
|
+
def scrollable
|
|
24
|
+
@is_scrollable = true
|
|
25
|
+
self
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#: () -> Row
|
|
29
|
+
def pin_to_end
|
|
30
|
+
@pin_right = true
|
|
31
|
+
self
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
#: () -> bool
|
|
35
|
+
def is_scrollable
|
|
36
|
+
@is_scrollable
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
#: (bool is_direction_x) -> bool
|
|
40
|
+
def has_scrollbar(is_direction_x)
|
|
41
|
+
if is_direction_x
|
|
42
|
+
@is_scrollable
|
|
43
|
+
else
|
|
44
|
+
false
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
#: () -> Float
|
|
49
|
+
def get_scroll_offset
|
|
50
|
+
@scroll_offset
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
#: (Float v) -> void
|
|
54
|
+
def set_scroll_offset(v)
|
|
55
|
+
@scroll_offset = v
|
|
56
|
+
mark_dirty
|
|
57
|
+
update
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
#: (untyped painter) -> Size
|
|
61
|
+
def measure(painter)
|
|
62
|
+
total_w = 0.0
|
|
63
|
+
max_h = 0.0
|
|
64
|
+
i = 0
|
|
65
|
+
while i < @children.length
|
|
66
|
+
cs = @children[i].measure(painter)
|
|
67
|
+
total_w = total_w + cs.width
|
|
68
|
+
total_w = total_w + @spacing if i > 0
|
|
69
|
+
max_h = cs.height if cs.height > max_h
|
|
70
|
+
i = i + 1
|
|
71
|
+
end
|
|
72
|
+
Size.new(total_w, max_h)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
#: (untyped painter) -> void
|
|
76
|
+
def relocate_children(painter)
|
|
77
|
+
remaining = @width
|
|
78
|
+
expanding_total_flex = 0
|
|
79
|
+
|
|
80
|
+
# First pass: measure FIXED/CONTENT children, collect EXPANDING
|
|
81
|
+
i = 0
|
|
82
|
+
while i < @children.length
|
|
83
|
+
c = @children[i]
|
|
84
|
+
if c.get_width_policy != EXPANDING
|
|
85
|
+
# Set height before measure so height-dependent layouts work
|
|
86
|
+
if c.get_height_policy == EXPANDING
|
|
87
|
+
c.resize_wh(c.get_width, @height)
|
|
88
|
+
end
|
|
89
|
+
cs = c.measure(painter)
|
|
90
|
+
c.resize_wh(cs.width, @height)
|
|
91
|
+
remaining = remaining - cs.width
|
|
92
|
+
else
|
|
93
|
+
expanding_total_flex = expanding_total_flex + c.get_flex
|
|
94
|
+
end
|
|
95
|
+
remaining = remaining - @spacing if i > 0
|
|
96
|
+
i = i + 1
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
if remaining < 0.0
|
|
100
|
+
remaining = 0.0
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Second pass: distribute remaining space, position all
|
|
104
|
+
cx = @x
|
|
105
|
+
if @is_scrollable
|
|
106
|
+
cx = cx - @scroll_offset
|
|
107
|
+
end
|
|
108
|
+
total_content_w = 0.0
|
|
109
|
+
i = 0
|
|
110
|
+
while i < @children.length
|
|
111
|
+
c = @children[i]
|
|
112
|
+
if c.get_width_policy == EXPANDING
|
|
113
|
+
w = 0.0
|
|
114
|
+
if expanding_total_flex > 0 && remaining > 0.0
|
|
115
|
+
w = remaining * c.get_flex / expanding_total_flex
|
|
116
|
+
end
|
|
117
|
+
c.resize_wh(w, @height)
|
|
118
|
+
else
|
|
119
|
+
if c.get_height_policy == EXPANDING
|
|
120
|
+
c.resize_wh(c.get_width, @height)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
c.move_xy(cx, @y)
|
|
124
|
+
cx = cx + c.get_width + @spacing
|
|
125
|
+
total_content_w = total_content_w + c.get_width
|
|
126
|
+
total_content_w = total_content_w + @spacing if i > 0
|
|
127
|
+
i = i + 1
|
|
128
|
+
end
|
|
129
|
+
@content_width = total_content_w
|
|
130
|
+
|
|
131
|
+
# Auto-scroll to end when pinned
|
|
132
|
+
if @pin_right && @is_scrollable
|
|
133
|
+
max_scroll = @content_width - @width
|
|
134
|
+
if max_scroll > 0.0
|
|
135
|
+
@scroll_offset = max_scroll
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
#: (untyped painter, bool completely) -> void
|
|
141
|
+
def redraw(painter, completely)
|
|
142
|
+
relocate_children(painter)
|
|
143
|
+
redraw_children(painter, completely)
|
|
144
|
+
draw_scrollbar(painter) if @is_scrollable
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
#: (untyped painter) -> void
|
|
148
|
+
def draw_scrollbar(painter)
|
|
149
|
+
viewport_w = @width
|
|
150
|
+
content_w = @content_width
|
|
151
|
+
return if content_w <= viewport_w
|
|
152
|
+
|
|
153
|
+
bar_height = 8.0
|
|
154
|
+
thumb_color = 0xC0AAAAAA
|
|
155
|
+
|
|
156
|
+
# Thumb
|
|
157
|
+
thumb_w = viewport_w * viewport_w / content_w
|
|
158
|
+
if thumb_w < 20.0
|
|
159
|
+
thumb_w = 20.0
|
|
160
|
+
end
|
|
161
|
+
thumb_x = (@scroll_offset / content_w) * viewport_w
|
|
162
|
+
if thumb_x + thumb_w > viewport_w
|
|
163
|
+
thumb_x = viewport_w - thumb_w
|
|
164
|
+
end
|
|
165
|
+
painter.fill_round_rect(thumb_x, @height - bar_height + 2.0, thumb_w, bar_height - 4.0, 2.0, thumb_color)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
#: (WheelEvent ev) -> void
|
|
169
|
+
def mouse_wheel(ev)
|
|
170
|
+
if @is_scrollable
|
|
171
|
+
scroll_speed = 30.0
|
|
172
|
+
@scroll_offset = @scroll_offset - ev.delta_y * scroll_speed
|
|
173
|
+
# Clamp scroll offset
|
|
174
|
+
max_scroll = @content_width - @width
|
|
175
|
+
if max_scroll < 0.0
|
|
176
|
+
max_scroll = 0.0
|
|
177
|
+
end
|
|
178
|
+
if @scroll_offset < 0.0
|
|
179
|
+
@scroll_offset = 0.0
|
|
180
|
+
end
|
|
181
|
+
if @scroll_offset > max_scroll
|
|
182
|
+
@scroll_offset = max_scroll
|
|
183
|
+
end
|
|
184
|
+
# Toggle pin_to_end: disable on scroll left, re-enable at end
|
|
185
|
+
if ev.delta_y > 0.0
|
|
186
|
+
@pin_right = false
|
|
187
|
+
end
|
|
188
|
+
if max_scroll > 0.0 && @scroll_offset >= max_scroll
|
|
189
|
+
@pin_right = true
|
|
190
|
+
end
|
|
191
|
+
mark_dirty
|
|
192
|
+
update
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Top-level helper
|
|
198
|
+
#: (*untyped children) -> Row
|
|
199
|
+
def Row(*children)
|
|
200
|
+
row = Row.new
|
|
201
|
+
i = 0
|
|
202
|
+
while i < children.length
|
|
203
|
+
row.add(children[i])
|
|
204
|
+
i = i + 1
|
|
205
|
+
end
|
|
206
|
+
row
|
|
207
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# rbs_inline: enabled
|
|
2
|
+
|
|
3
|
+
# Spacer - flexible space widget
|
|
4
|
+
# Port of Castella Spacer
|
|
5
|
+
|
|
6
|
+
class Spacer < Widget
|
|
7
|
+
def initialize
|
|
8
|
+
super
|
|
9
|
+
@width_policy = EXPANDING
|
|
10
|
+
@height_policy = EXPANDING
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Top-level helper
|
|
15
|
+
#: () -> Spacer
|
|
16
|
+
def Spacer()
|
|
17
|
+
Spacer.new
|
|
18
|
+
end
|