kumiki 0.1.1
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/LICENSE +21 -0
- data/README.md +256 -0
- data/lib/kumiki/animation/animated_state.rb +83 -0
- data/lib/kumiki/animation/easing.rb +62 -0
- data/lib/kumiki/animation/value_tween.rb +69 -0
- data/lib/kumiki/app.rb +381 -0
- data/lib/kumiki/box.rb +40 -0
- data/lib/kumiki/chart/area_chart.rb +308 -0
- data/lib/kumiki/chart/bar_chart.rb +291 -0
- data/lib/kumiki/chart/base_chart.rb +213 -0
- data/lib/kumiki/chart/chart_helpers.rb +74 -0
- data/lib/kumiki/chart/gauge_chart.rb +174 -0
- data/lib/kumiki/chart/heatmap_chart.rb +223 -0
- data/lib/kumiki/chart/line_chart.rb +292 -0
- data/lib/kumiki/chart/pie_chart.rb +222 -0
- data/lib/kumiki/chart/scales.rb +79 -0
- data/lib/kumiki/chart/scatter_chart.rb +306 -0
- data/lib/kumiki/chart/stacked_bar_chart.rb +279 -0
- data/lib/kumiki/column.rb +351 -0
- data/lib/kumiki/core.rb +2511 -0
- data/lib/kumiki/dsl.rb +408 -0
- data/lib/kumiki/frame_ranma.rb +570 -0
- data/lib/kumiki/markdown/ast.rb +127 -0
- data/lib/kumiki/markdown/mermaid/layout.rb +389 -0
- data/lib/kumiki/markdown/mermaid/models.rb +235 -0
- data/lib/kumiki/markdown/mermaid/parser.rb +522 -0
- data/lib/kumiki/markdown/mermaid/renderer.rb +339 -0
- data/lib/kumiki/markdown/parser.rb +808 -0
- data/lib/kumiki/markdown/renderer.rb +642 -0
- data/lib/kumiki/markdown/theme.rb +168 -0
- data/lib/kumiki/render_node.rb +262 -0
- data/lib/kumiki/row.rb +288 -0
- data/lib/kumiki/spacer.rb +20 -0
- data/lib/kumiki/style.rb +799 -0
- data/lib/kumiki/theme.rb +567 -0
- data/lib/kumiki/themes/material.rb +40 -0
- data/lib/kumiki/themes/tokyo_night.rb +11 -0
- data/lib/kumiki/version.rb +5 -0
- data/lib/kumiki/widgets/button.rb +105 -0
- data/lib/kumiki/widgets/calendar.rb +1028 -0
- data/lib/kumiki/widgets/checkbox.rb +119 -0
- data/lib/kumiki/widgets/container.rb +111 -0
- data/lib/kumiki/widgets/data_table.rb +670 -0
- data/lib/kumiki/widgets/divider.rb +31 -0
- data/lib/kumiki/widgets/image.rb +105 -0
- data/lib/kumiki/widgets/input.rb +485 -0
- data/lib/kumiki/widgets/markdown.rb +58 -0
- data/lib/kumiki/widgets/modal.rb +165 -0
- data/lib/kumiki/widgets/multiline_input.rb +970 -0
- data/lib/kumiki/widgets/multiline_text.rb +180 -0
- data/lib/kumiki/widgets/net_image.rb +100 -0
- data/lib/kumiki/widgets/progress_bar.rb +72 -0
- data/lib/kumiki/widgets/radio_buttons.rb +93 -0
- data/lib/kumiki/widgets/slider.rb +135 -0
- data/lib/kumiki/widgets/switch.rb +84 -0
- data/lib/kumiki/widgets/tabs.rb +175 -0
- data/lib/kumiki/widgets/text.rb +120 -0
- data/lib/kumiki/widgets/tree.rb +434 -0
- data/lib/kumiki/widgets/webview.rb +87 -0
- data/lib/kumiki.rb +130 -0
- metadata +113 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
module Kumiki
|
|
2
|
+
# Modal dialog - overlay with backdrop and centered content
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# modal = Modal.new(dialog_content)
|
|
6
|
+
# # Place inside a Box with main content:
|
|
7
|
+
# Box(main_content, modal)
|
|
8
|
+
# # Open/close:
|
|
9
|
+
# modal.open_modal
|
|
10
|
+
# modal.close_modal
|
|
11
|
+
|
|
12
|
+
class Modal < Widget
|
|
13
|
+
def initialize(content)
|
|
14
|
+
super()
|
|
15
|
+
@modal_content = content
|
|
16
|
+
@visible = false
|
|
17
|
+
@content_added = false
|
|
18
|
+
@backdrop_color = 0x80000000
|
|
19
|
+
@dialog_radius = 8.0
|
|
20
|
+
@dialog_w = 320.0
|
|
21
|
+
@dialog_h = 200.0
|
|
22
|
+
@title_text = nil
|
|
23
|
+
@title_font_size = 16.0
|
|
24
|
+
@width_policy = EXPANDING
|
|
25
|
+
@height_policy = EXPANDING
|
|
26
|
+
@z_index_val = 98
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def dialog_size(w, h)
|
|
30
|
+
@dialog_w = w
|
|
31
|
+
@dialog_h = h
|
|
32
|
+
self
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def title(t)
|
|
36
|
+
@title_text = t
|
|
37
|
+
self
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def open_modal
|
|
41
|
+
@visible = true
|
|
42
|
+
mark_dirty
|
|
43
|
+
update
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def close_modal
|
|
47
|
+
@visible = false
|
|
48
|
+
mark_dirty
|
|
49
|
+
update
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def is_open
|
|
53
|
+
@visible
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def measure(painter)
|
|
57
|
+
Size.new(@width, @height)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def redraw(painter, completely)
|
|
61
|
+
if !@visible
|
|
62
|
+
return
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Draw semi-transparent backdrop
|
|
66
|
+
painter.fill_rect(0.0, 0.0, @width, @height, @backdrop_color)
|
|
67
|
+
|
|
68
|
+
# Calculate dialog position (centered)
|
|
69
|
+
dx = (@width - @dialog_w) / 2.0
|
|
70
|
+
dy = (@height - @dialog_h) / 2.0
|
|
71
|
+
|
|
72
|
+
# Resolve colors from theme
|
|
73
|
+
dialog_bg_c = Kumiki.theme.bg_primary
|
|
74
|
+
dialog_border_c = Kumiki.theme.border
|
|
75
|
+
title_c = Kumiki.theme.text_primary
|
|
76
|
+
close_c = Kumiki.theme.error
|
|
77
|
+
|
|
78
|
+
# Draw dialog background
|
|
79
|
+
painter.fill_round_rect(dx, dy, @dialog_w, @dialog_h, @dialog_radius, dialog_bg_c)
|
|
80
|
+
painter.stroke_round_rect(dx, dy, @dialog_w, @dialog_h, @dialog_radius, dialog_border_c, 1.0)
|
|
81
|
+
|
|
82
|
+
# Draw title if set
|
|
83
|
+
title_h = 0.0
|
|
84
|
+
if @title_text != nil
|
|
85
|
+
title_h = 40.0
|
|
86
|
+
ascent = painter.get_text_ascent(Kumiki.theme.font_family, @title_font_size)
|
|
87
|
+
painter.draw_text(@title_text, dx + 16.0, dy + 12.0 + ascent, Kumiki.theme.font_family, @title_font_size, title_c)
|
|
88
|
+
# Close button (X) in top right
|
|
89
|
+
close_x = dx + @dialog_w - 32.0
|
|
90
|
+
painter.draw_text("X", close_x, dy + 12.0 + ascent, Kumiki.theme.font_family, @title_font_size, close_c)
|
|
91
|
+
# Divider line below title
|
|
92
|
+
painter.draw_line(dx, dy + 40.0, dx + @dialog_w, dy + 40.0, dialog_border_c, 1.0)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Draw content inside dialog using save/restore + translate + clip
|
|
96
|
+
content_x = dx + 12.0
|
|
97
|
+
content_y = dy + title_h + 12.0
|
|
98
|
+
content_w = @dialog_w - 24.0
|
|
99
|
+
content_h = @dialog_h - title_h - 24.0
|
|
100
|
+
|
|
101
|
+
# Position and size the content widget
|
|
102
|
+
@modal_content.move_xy(@x + content_x, @y + content_y)
|
|
103
|
+
@modal_content.resize_wh(content_w, content_h)
|
|
104
|
+
|
|
105
|
+
# Save painter state, translate to content origin, clip, draw, restore
|
|
106
|
+
painter.save
|
|
107
|
+
painter.translate(content_x, content_y)
|
|
108
|
+
painter.clip_rect(0.0, 0.0, content_w, content_h)
|
|
109
|
+
@modal_content.redraw(painter, true)
|
|
110
|
+
painter.restore
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def dispatch(p)
|
|
114
|
+
if !@visible
|
|
115
|
+
return [nil, nil]
|
|
116
|
+
end
|
|
117
|
+
if contain(p)
|
|
118
|
+
# Try dispatching to modal content first
|
|
119
|
+
content_result = @modal_content.dispatch(p)
|
|
120
|
+
target = content_result[0]
|
|
121
|
+
if target != nil
|
|
122
|
+
return content_result
|
|
123
|
+
end
|
|
124
|
+
# Click was on modal but not on content child - return self
|
|
125
|
+
local_p = Point.new(p.x - @x, p.y - @y)
|
|
126
|
+
[self, local_p]
|
|
127
|
+
else
|
|
128
|
+
[nil, nil]
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def mouse_up(ev)
|
|
133
|
+
if !@visible
|
|
134
|
+
return
|
|
135
|
+
end
|
|
136
|
+
# Check if click is on the close button (X)
|
|
137
|
+
if @title_text != nil
|
|
138
|
+
dx = (@width - @dialog_w) / 2.0
|
|
139
|
+
dy = (@height - @dialog_h) / 2.0
|
|
140
|
+
close_x = dx + @dialog_w - 40.0
|
|
141
|
+
close_y = dy
|
|
142
|
+
cx = ev.pos.x
|
|
143
|
+
cy = ev.pos.y
|
|
144
|
+
if cx >= close_x && cx <= dx + @dialog_w && cy >= close_y && cy <= close_y + 40.0
|
|
145
|
+
close_modal
|
|
146
|
+
return
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
# Check if click is on the backdrop (outside dialog)
|
|
150
|
+
dx = (@width - @dialog_w) / 2.0
|
|
151
|
+
dy = (@height - @dialog_h) / 2.0
|
|
152
|
+
cx = ev.pos.x
|
|
153
|
+
cy = ev.pos.y
|
|
154
|
+
if cx < dx || cx > dx + @dialog_w || cy < dy || cy > dy + @dialog_h
|
|
155
|
+
close_modal
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Top-level helper
|
|
161
|
+
def Modal(content)
|
|
162
|
+
Modal.new(content)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
end
|