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 {