1#include <sstream>
2#include "cell.hpp"
3#include "text_helper.hpp"
4
5namespace
6{
7 void
8 bounce_move(float &v, float &q, float pmax, float sc)
9 {
10 const float delta(q * sc);
11
12 v += delta;
13 if (v < 0)
14 {
15 v = -v;
16 q = -q;
17 }
18 else if (v > pmax)
19 {
20 v = pmax - (v - pmax);
21 q = -q;
22 }
23 }
24
25 void
26 bounce_move(vec2 &v, vec2 &delta, vec2 pmax, float sc)
27 {
28 bounce_move(v.x(), delta.x(), pmax.x(), sc);
29 bounce_move(v.y(), delta.y(), pmax.y(), sc);
30 }
31}
32
33Cell::
34Cell(PainterWidget *p, const CellParams &params):
35 PainterWidget(p),
36 m_first_frame(true),
37 m_thousandths_degrees_rotation(0),
38 m_thousandths_degrees_cell_rotation(0),
39 m_pixels_per_ms(params.m_pixels_per_ms),
40 m_degrees_per_s(params.m_degrees_per_s),
41 m_background_brush(params.m_background_brush),
42 m_image_brush(params.m_image_brush),
43 m_text_brush(params.m_text_brush),
44 m_line_brush(params.m_line_brush),
45 m_item_location(params.m_size * 0.5f),
46 m_text(params.m_pixel_size,
47 fastuidraw::Painter::y_increases_downwards,
48 *params.m_glyph_cache),
49 m_shared_state(params.m_state),
50 m_timer_based_animation(params.m_timer_based_animation)
51{
52 std::ostringstream ostr;
53 ostr << "Cell" << params.m_table_pos
54 << "\n" << params.m_text
55 << "\n" << params.m_image_name;
56
57 std::istringstream str(ostr.str());
58 create_formatted_text(m_text,
59 PainterEnums::y_increases_downwards,
60 str, params.m_font.get(),
61 params.m_font_database);
62
63 m_dimensions = params.m_size;
64 m_table_pos = m_dimensions * vec2(params.m_table_pos);
65
66 if (params.m_image)
67 {
68 m_rect_dims = vec2(params.m_image->dimensions());
69 }
70 else
71 {
72 m_rect_dims = vec2(m_dimensions) * 0.25f;
73 }
74}
75
76void
77Cell::
78pre_paint(void)
79{
80 if (!m_first_frame)
81 {
82 uint32_t ms;
83 if (m_timer_based_animation)
84 {
85 ms = m_time.restart();
86 }
87 else
88 {
89 ms = 16;
90 }
91
92 if (m_shared_state->m_pause)
93 {
94 ms = 0;
95 }
96
97 m_thousandths_degrees_rotation += m_degrees_per_s * ms;
98 bounce_move(m_item_location, m_pixels_per_ms,
99 m_dimensions, static_cast<float>(ms));
100
101 if (m_thousandths_degrees_rotation >= 360 * 1000)
102 {
103 m_thousandths_degrees_rotation = m_thousandths_degrees_rotation % (360 * 1000);
104 }
105
106 if (m_shared_state->m_rotating)
107 {
108 m_thousandths_degrees_cell_rotation += m_degrees_per_s * ms;
109 if (m_thousandths_degrees_rotation >= 360 * 1000)
110 {
111 m_thousandths_degrees_cell_rotation = m_thousandths_degrees_rotation % (360 * 1000);
112 }
113 }
114 else
115 {
116 m_thousandths_degrees_cell_rotation = 0;
117 }
118 }
119 else
120 {
121 m_first_frame = false;
122 }
123
124 m_item_rotation =
125 static_cast<float>(FASTUIDRAW_PI) * static_cast<float>(m_thousandths_degrees_rotation) / (1000.0f * 180.0f);
126
127 if (m_shared_state->m_rotating)
128 {
129 float r;
130
131 r = static_cast<float>(FASTUIDRAW_PI) * static_cast<float>(m_thousandths_degrees_cell_rotation) / (1000.0f * 180.0f);
132 m_parent_matrix_this.reset();
133 m_parent_matrix_this.translate(m_dimensions * 0.5f + m_table_pos);
134 m_parent_matrix_this.rotate(r);
135 m_parent_matrix_this.translate(-m_dimensions * 0.5f);
136 }
137 else
138 {
139 m_parent_matrix_this = float3x3(float2x2(), m_table_pos);
140 }
141 m_draw_transparent = m_shared_state->m_draw_transparent;
142}
143
144void
145Cell::
146paint_pre_children(const reference_counted_ptr<Painter> &painter)
147{
148 painter->save();
149 painter->fill_rect(PainterData(m_background_brush),
150 Rect().size(m_dimensions),
151 false);
152
153 painter->translate(m_item_location);
154 painter->rotate(m_item_rotation);
155
156 if (m_shared_state->m_draw_image)
157 {
158 vec2 wh;
159 wh = m_rect_dims;
160 painter->save();
161 painter->translate(-wh * 0.5f);
162 painter->blend_shader(m_shared_state->m_rect_blend_mode);
163 painter->fill_rect(PainterData(m_image_brush),
164 Rect().size(wh),
165 false);
166 painter->restore();
167 }
168
169 if (m_shared_state->m_draw_text)
170 {
171 painter->draw_glyphs(PainterData(m_text_brush), m_text,
172 GlyphRenderer(m_shared_state->m_glyph_render));
173 }
174
175 painter->restore();
176
177 if (m_shared_state->m_rotating && m_shared_state->m_stroke_width > 0.0f)
178 {
179 PainterStrokeParams st;
180
181 st.miter_limit(-1.0f);
182 st.width(m_shared_state->m_stroke_width);
183
184 painter->stroke_path(PainterData(m_line_brush, &st),
185 m_shared_state->m_path,
186 StrokingStyle()
187 .join_style(Painter::miter_clip_joins),
188 m_shared_state->m_anti_alias_stroking);
189 }
190 m_shared_state->m_cells_drawn++;
191}
192