-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathAnimateWidget.zig
123 lines (100 loc) · 3.2 KB
/
AnimateWidget.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
const std = @import("std");
const dvui = @import("../dvui.zig");
const Event = dvui.Event;
const Options = dvui.Options;
const Rect = dvui.Rect;
const RectScale = dvui.RectScale;
const Size = dvui.Size;
const Widget = dvui.Widget;
const WidgetData = dvui.WidgetData;
const AnimateWidget = @This();
pub const Kind = enum {
alpha,
vertical,
horizontal,
};
wd: WidgetData = undefined,
kind: Kind = undefined,
duration: i32 = undefined,
val: ?f32 = null,
prev_alpha: f32 = 1.0,
pub fn init(src: std.builtin.SourceLocation, kind: Kind, duration_micros: i32, opts: Options) AnimateWidget {
const defaults = Options{ .name = "Animate" };
return AnimateWidget{ .wd = WidgetData.init(src, .{}, defaults.override(opts)), .kind = kind, .duration = duration_micros };
}
pub fn install(self: *AnimateWidget) !void {
dvui.parentSet(self.widget());
try self.wd.register();
if (dvui.firstFrame(self.wd.id)) {
// start begin animation
self.start();
}
if (dvui.animationGet(self.wd.id, "_end")) |a| {
self.val = a.lerp();
} else if (dvui.animationGet(self.wd.id, "_start")) |a| {
self.val = a.lerp();
}
if (self.val) |v| {
switch (self.kind) {
.alpha => {
self.prev_alpha = dvui.themeGet().alpha;
dvui.themeGet().alpha *= v;
},
.vertical => {},
.horizontal => {},
}
}
try self.wd.borderAndBackground(.{});
}
pub fn start(self: *AnimateWidget) void {
dvui.animation(self.wd.id, "_start", .{ .start_val = 0.0, .end_val = 1.0, .end_time = self.duration });
}
pub fn startEnd(self: *AnimateWidget) void {
dvui.animation(self.wd.id, "_end", .{ .start_val = 1.0, .end_val = 0.0, .end_time = self.duration });
}
pub fn end(self: *AnimateWidget) bool {
if (dvui.animationGet(self.wd.id, "_end")) |a| {
return a.done();
}
return false;
}
pub fn widget(self: *AnimateWidget) Widget {
return Widget.init(self, data, rectFor, screenRectScale, minSizeForChild, processEvent);
}
pub fn data(self: *AnimateWidget) *WidgetData {
return &self.wd;
}
pub fn rectFor(self: *AnimateWidget, id: u32, min_size: Size, e: Options.Expand, g: Options.Gravity) Rect {
_ = id;
return dvui.placeIn(self.wd.contentRect().justSize(), min_size, e, g);
}
pub fn screenRectScale(self: *AnimateWidget, rect: Rect) RectScale {
return self.wd.contentRectScale().rectToRectScale(rect);
}
pub fn minSizeForChild(self: *AnimateWidget, s: Size) void {
self.wd.minSizeMax(self.wd.options.padSize(s));
}
pub fn processEvent(self: *AnimateWidget, e: *Event, bubbling: bool) void {
_ = bubbling;
if (e.bubbleable()) {
self.wd.parent.processEvent(e, true);
}
}
pub fn deinit(self: *AnimateWidget) void {
if (self.val) |v| {
switch (self.kind) {
.alpha => {
dvui.themeGet().alpha = self.prev_alpha;
},
.vertical => {
self.wd.min_size.h *= v;
},
.horizontal => {
self.wd.min_size.w *= v;
},
}
}
self.wd.minSizeSetAndRefresh();
self.wd.minSizeReportToParent();
dvui.parentReset(self.wd.id, self.wd.parent);
}