main.odin ¶
1package src
2
3
4
5
6
7
8
9
10
11
12import "core:math"
13import oc "core:sys/orca"
14
15clockNumberStrings := [?]string{"12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"}
16
17surface: oc.surface = {}
18renderer: oc.canvas_renderer = {}
19canvas: oc.canvas_context = {}
20font: oc.font = {}
21frameSize: oc.vec2 = {100, 100}
22lastSeconds: f64 = 0
23
24mat_transform :: proc "contextless" (x, y, radians: f32) -> oc.mat2x3 {
25 rotation := oc.mat2x3_rotate(radians)
26 translation := oc.mat2x3_translate(x, y)
27 return oc.mat2x3_mul_m(translation, rotation)
28}
29
30main :: proc() {
31 oc.window_set_title("clock")
32 oc.window_set_size({400, 400})
33
34 renderer = oc.canvas_renderer_create()
35 surface = oc.canvas_surface_create(renderer)
36 canvas = oc.canvas_context_create()
37
38 ranges := [?]oc.unicode_range {
39 oc.UNICODE_BASIC_LATIN,
40 oc.UNICODE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
41 oc.UNICODE_LATIN_EXTENDED_A,
42 oc.UNICODE_LATIN_EXTENDED_B,
43 oc.UNICODE_SPECIALS,
44 }
45
46 oc.font_create_from_path("segoeui.ttf", 5, &ranges[0])
47}
48
49@(export)
50oc_on_resize :: proc "c" (width, height: u32) {
51 frameSize.x = f32(width)
52 frameSize.y = f32(height)
53}
54
55
56remainder_f64 :: proc "contextless" (x, y: f64) -> f64 {
57 return x - round_slow(x / y) * y
58}
59
60round_slow :: proc "contextless" (x: f64) -> f64 {
61 t := math.trunc(x)
62 if abs(x - t) >= 0.5 {
63 return t + math.copy_sign(1, x)
64 }
65 return t
66}
67
68mod_f64 :: proc "contextless" (x, y: f64) -> (n: f64) {
69 z := abs(y)
70 n = remainder_f64(abs(x), z)
71 if math.sign(n) < 0 {
72 n += z
73 }
74 return math.copy_sign(n, x)
75}
76
77@(export)
78oc_on_frame_refresh :: proc "c" () {
79
80
81 oc.canvas_context_select(canvas)
82 oc.set_color_rgba(.05, .05, .05, 1)
83 oc.clear()
84
85 timestampSecs := f64(oc.clock_time(.DATE))
86 secs := mod_f64(timestampSecs, 60.0)
87 minutes := mod_f64(timestampSecs, 60.0 * 60.0) / 60.0
88 hours := mod_f64(timestampSecs, 60.0 * 60.0 * 24) / (60.0 * 60.0)
89 hoursAs12Format := mod_f64(hours, 12.0)
90
91 if lastSeconds != math.floor(secs) {
92 lastSeconds = math.floor(secs)
93
94
95
96
97
98
99
100 }
101
102 secondsRotation := (math.PI * 2) * (secs / 60.0) - (math.PI / 2)
103 minutesRotation := (math.PI * 2) * (minutes / 60.0) - (math.PI / 2)
104 hoursRotation := (math.PI * 2) * (hoursAs12Format / 12.0) - (math.PI / 2)
105
106 centerX := frameSize.x / 2
107 centerY := frameSize.y / 2
108 clockRadius := min(frameSize.x, frameSize.y) * 0.5 * 0.85
109
110 DEFAULT_CLOCK_RADIUS :: 260
111 uiScale := clockRadius / DEFAULT_CLOCK_RADIUS
112
113 fontSize := 26 * uiScale
114 oc.set_font(font)
115 oc.set_font_size(fontSize)
116
117
118 oc.set_color_rgba(1, 1, 1, 1)
119 oc.circle_fill(centerX, centerY, clockRadius)
120
121
122 for i in 0 ..< len(clockNumberStrings) {
123 str := clockNumberStrings[i]
124 textRect := oc.font_text_metrics(font, fontSize, str).ink
125
126 angle := f32(i) * ((math.PI * 2) / f32(12.0)) - (math.PI / 2)
127 transform := mat_transform(
128 centerX - (textRect.w / 2) - textRect.x,
129 centerY - (textRect.h / 2) - textRect.y,
130 angle,
131 )
132
133 pos := oc.mat2x3_mul(transform, {clockRadius * 0.8, 0})
134
135 oc.set_color_rgba(0.2, 0.2, 0.2, 1)
136 oc.text_fill(pos.x, pos.y, str)
137 }
138
139
140 oc.matrix_multiply_push(mat_transform(centerX, centerY, f32(hoursRotation)))
141 {
142 oc.set_color_rgba(.2, 0.2, 0.2, 1)
143 oc.rounded_rectangle_fill(0, -7.5 * uiScale, clockRadius * 0.5, 15 * uiScale, 5 * uiScale)
144 }
145 oc.matrix_pop()
146
147
148 oc.matrix_multiply_push(mat_transform(centerX, centerY, f32(minutesRotation)))
149 {
150 oc.set_color_rgba(.2, 0.2, 0.2, 1)
151 oc.rounded_rectangle_fill(0, -5 * uiScale, clockRadius * 0.7, 10 * uiScale, 5 * uiScale)
152 }
153 oc.matrix_pop()
154
155
156 oc.matrix_multiply_push(mat_transform(centerX, centerY, f32(secondsRotation)))
157 {
158 oc.set_color_rgba(1, 0.2, 0.2, 1)
159 oc.rounded_rectangle_fill(0, -2.5 * uiScale, clockRadius * 0.8, 5 * uiScale, 5 * uiScale)
160 }
161 oc.matrix_pop()
162
163 oc.set_color_srgba(.2, 0.2, 0.2, 1)
164 oc.circle_fill(centerX, centerY, 10 * uiScale)
165
166 oc.canvas_render(renderer, canvas, surface)
167 oc.canvas_present(renderer, surface)
168}