void PanZoomTracker:: handle_motion(const fastuidraw::vec2 &pos, const fastuidraw::vec2 &delta) { if(!m_button_down) { return; } if(m_zoom_time.elapsed() > m_zoom_gesture_begin_time) { m_is_zooming = true; } float zdivide(m_scale_zooming * m_zoom_divider); if(!m_is_zooming) { float zdx(pos.x() - m_zoom_pivot.x()); float zdy(pos.y() - m_zoom_pivot.y()); m_transformation.translation( m_transformation.translation() + delta); if(fastuidraw::t_abs(zdx) > zdivide or fastuidraw::t_abs(zdy) > zdivide) { m_zoom_time.restart(); m_zoom_pivot = pos; m_start_gesture = m_transformation; } } else { float zoom_factor(pos.y() - m_zoom_pivot.y()); ScaleTranslate<float> R; zoom_factor /= zdivide; if(zoom_factor < 0.0f) { zoom_factor = -1.0f/fastuidraw::t_min(-1.0f, zoom_factor); } else { zoom_factor = fastuidraw::t_max(1.0f, zoom_factor); } R.scale(zoom_factor); R.translation( (1.0f - zoom_factor) * m_zoom_pivot); m_transformation = R * m_start_gesture; } }
enum Splitter::split_type_t Splitter:: split(const std::vector<unsigned int> &input, const fastuidraw::vec2 &mid, const GlyphSequencePrivate *added_glyphs_src, fastuidraw::vecN<std::vector<unsigned int>, 3> &out_values) { using namespace fastuidraw; vecN<Splitter, 2> splitV; vecN<unsigned int, 2> in_pre_counts(0u, 0u); vecN<unsigned int, 2> in_post_counts(0u, 0u); vecN<unsigned int, 2> in_both_counts(0u, 0u); FASTUIDRAWassert(!splits()); FASTUIDRAWassert(std::is_sorted(input.begin(), input.end())); splitV[0].m_splitting_coordinate = split_in_x_coordinate; splitV[0].m_splitting_value = mid.x(); splitV[1].m_splitting_coordinate = split_in_y_coordinate; splitV[1].m_splitting_value = mid.y(); for (unsigned int I : input) { const PerAddedGlyph &G(added_glyphs_src->added_glyph(I)); for (int c = 0; c < 2; ++c) { enum place_element_t P; bool in_child0, in_child1; P = splitV[c].place_element(G); in_child0 = (P == place_in_child0) || (P == place_in_parent); in_child1 = (P == place_in_child1) || (P == place_in_parent); if (in_child0) { ++in_pre_counts[c]; } if (in_child1) { ++in_post_counts[c]; } if (in_child0 && in_child1) { ++in_both_counts[c]; } } } enum split_type_t choice; choice = (in_both_counts[0] < in_both_counts[1]) ? split_in_x_coordinate : split_in_y_coordinate; if (in_both_counts[choice] == input.size()) { return does_not_split; } m_splitting_coordinate = choice; m_splitting_value = mid[choice]; for (unsigned int I : input) { const PerAddedGlyph &G(added_glyphs_src->added_glyph(I)); enum place_element_t P; P = place_element(G); out_values[P].push_back(I); } FASTUIDRAWassert(std::is_sorted(out_values[0].begin(), out_values[0].end())); FASTUIDRAWassert(std::is_sorted(out_values[1].begin(), out_values[1].end())); FASTUIDRAWassert(std::is_sorted(out_values[2].begin(), out_values[2].end())); return m_splitting_coordinate; }