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;
    }
}
Exemple #2
0
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;
}