src/view.cpp in reflexion-0.1.37 vs src/view.cpp in reflexion-0.1.38
- old
+ new
@@ -103,16 +103,26 @@
{
if (!ppivot) ppivot.reset(new Point);
return *ppivot;
}
+ bool has_pivot () const
+ {
+ return ppivot && *ppivot != ZERO;
+ }
+
Point& scroll ()
{
if (!pscroll) pscroll.reset(new Point);
return *pscroll;
}
+ bool has_scroll () const
+ {
+ return pscroll && *pscroll != ZERO;
+ }
+
Selector& selector ()
{
if (!pselector) pselector.reset(new Selector);
return *pselector;
}
@@ -1244,13 +1254,13 @@
p->translate(pos);
if (self->angle != 0)
{
const Point* pivot = self->ppivot.get();
- if (pivot) p->translate( pivot->x * bounds.width, pivot->y * bounds.height);
+ if (pivot) p->translate( pivot->x * bounds.w, pivot->y * bounds.h);
p->rotate(self->angle);
- if (pivot) p->translate(-pivot->x * bounds.width, -pivot->y * bounds.height);
+ if (pivot) p->translate(-pivot->x * bounds.w, -pivot->y * bounds.h);
}
float zoom = self->zoom;
if (zoom != 1 && zoom > 0)
p->scale(zoom, zoom);
@@ -1569,49 +1579,99 @@
{
LayoutContext(this).place_children();
redraw();
}
+ static void
+ get_from_parent_matrix (Matrix* m, const View* view)
+ {
+ assert(m && view);
+ View::Data* self = view->self.get();
+
+ const auto& frame = self->frame;
+ const auto* scroll = self->has_scroll() ? self->pscroll.get() : NULL;
+ auto angle = self->angle;
+ auto zoom = self->zoom;
+
+ if (zoom != 1 && zoom > 0) m->scale(1 / zoom, 1 / zoom);
+ if (angle != 0)
+ {
+ const auto* pivot = self->has_pivot() ? self->ppivot.get() : NULL;
+ if (pivot) m->translate( pivot->x * frame.w, pivot->y * frame.h);
+ m->rotate(-angle);
+ if (pivot) m->translate(-pivot->x * frame.w, -pivot->y * frame.h);
+ }
+ m->translate(-frame.position());
+ if (scroll) m->translate(-*scroll);
+ }
+
+ static void
+ get_to_parent_matrix (Matrix* m, const View* view)
+ {
+ assert(m && view);
+ View::Data* self = view->self.get();
+
+ const auto& frame = self->frame;
+ const auto* scroll = self->has_scroll() ? self->pscroll.get() : NULL;
+ auto angle = self->angle;
+ auto zoom = self->zoom;
+
+ if (scroll) m->translate(*scroll);
+ m->translate(frame.position());
+ if (angle != 0)
+ {
+ const auto* pivot = self->has_pivot() ? self->ppivot.get() : NULL;
+ if (pivot) m->translate( pivot->x * frame.w, pivot->y * frame.h);
+ m->rotate(angle);
+ if (pivot) m->translate(-pivot->x * frame.w, -pivot->y * frame.h);
+ }
+ if (zoom != 1 && zoom > 0) m->scale(zoom, zoom);
+ }
+
Point
View::from_parent (const Point& point) const
{
- if (!parent())
- invalid_state_error(__FILE__, __LINE__);
-
- return point - frame().position();
+ if (self->zoom == 1 && self->angle == 0 && !self->has_scroll())
+ return point - self->frame.position();
+ else
+ {
+ Matrix m(1);
+ get_from_parent_matrix(&m, this);
+ return m * point;
+ }
}
Point
View::to_parent (const Point& point) const
{
- if (!parent())
- invalid_state_error(__FILE__, __LINE__);
-
- return point + frame().position();
+ if (self->zoom == 1 && self->angle == 0 && !self->has_scroll())
+ return point + self->frame.position();
+ else
+ {
+ Matrix m(1);
+ get_to_parent_matrix(&m, this);
+ return m * point;
+ }
}
Point
View::from_window (const Point& point) const
{
if (!window())
invalid_state_error(__FILE__, __LINE__);
- Point p = point;
- for (const View* v = this; v; v = v->parent())
- p -= v->frame().position();
- return p;
+ const auto* parent = self->parent;
+ return from_parent(parent ? parent->from_window(point) : point);
}
Point
View::to_window (const Point& point) const
{
if (!window())
invalid_state_error(__FILE__, __LINE__);
- Point p = point;
- for (const View* v = this; v; v = v->parent())
- p += v->frame().position();
- return p;
+ const auto* parent = self->parent;
+ return parent ? parent->to_window(to_parent(point)) : to_parent(point);
}
Point
View::from_screen (const Point& point) const
{