Browse Source

Add `Widget::getRelativeZoom()` and `getAbsoluteZoom()`.

tags/v2.0.0
Andrew Belt 4 years ago
parent
commit
b6382f6697
4 changed files with 42 additions and 12 deletions
  1. +16
    -3
      include/widget/Widget.hpp
  2. +1
    -0
      include/widget/ZoomWidget.hpp
  3. +14
    -8
      src/widget/Widget.cpp
  4. +11
    -1
      src/widget/ZoomWidget.cpp

+ 16
- 3
include/widget/Widget.hpp View File

@@ -50,14 +50,27 @@ struct Widget {


void requestDelete(); void requestDelete();


/** Returns the smallest rectangle containing this widget's children (visible and invisible) in its local coordinates.
Returns `Rect(Vec(inf, inf), Vec(-inf, -inf))` if there are no children.
*/
virtual math::Rect getChildrenBoundingBox(); virtual math::Rect getChildrenBoundingBox();
/** Returns `v` transformed into the coordinate system of `relative` */
/** Returns `v` (given in local coordinates) transformed into the coordinate system of `relative`.
*/
virtual math::Vec getRelativeOffset(math::Vec v, Widget* relative); virtual math::Vec getRelativeOffset(math::Vec v, Widget* relative);
/** Returns `v` transformed into world coordinates */
/** Returns `v` transformed into world/root/global/absolute coordinates.
*/
math::Vec getAbsoluteOffset(math::Vec v) { math::Vec getAbsoluteOffset(math::Vec v) {
return getRelativeOffset(v, NULL); return getRelativeOffset(v, NULL);
} }
/** Returns a subset of the given math::Rect bounded by the box of this widget and all ancestors */
/** Returns the zoom level in the coordinate system of `relative`.
Only `ZoomWidget` should override this to return value other than 1.
*/
virtual float getRelativeZoom(Widget* relative);
float getAbsoluteZoom() {
return getRelativeZoom(NULL);
}
/** Returns a subset of the given Rect bounded by the box of this widget and all ancestors.
*/
virtual math::Rect getViewport(math::Rect r); virtual math::Rect getViewport(math::Rect r);


template <class T> template <class T>


+ 1
- 0
include/widget/ZoomWidget.hpp View File

@@ -11,6 +11,7 @@ struct ZoomWidget : Widget {
float zoom = 1.f; float zoom = 1.f;


math::Vec getRelativeOffset(math::Vec v, Widget* relative) override; math::Vec getRelativeOffset(math::Vec v, Widget* relative) override;
float getRelativeZoom(Widget* relative) override;
math::Rect getViewport(math::Rect r) override; math::Rect getViewport(math::Rect r) override;
void setZoom(float zoom); void setZoom(float zoom);
float getZoom() { float getZoom() {


+ 14
- 8
src/widget/Widget.cpp View File

@@ -87,8 +87,6 @@ math::Rect Widget::getChildrenBoundingBox() {
math::Vec min = math::Vec(INFINITY, INFINITY); math::Vec min = math::Vec(INFINITY, INFINITY);
math::Vec max = math::Vec(-INFINITY, -INFINITY); math::Vec max = math::Vec(-INFINITY, -INFINITY);
for (Widget* child : children) { for (Widget* child : children) {
if (!child->visible)
continue;
min = min.min(child->box.getTopLeft()); min = min.min(child->box.getTopLeft());
max = max.max(child->box.getBottomRight()); max = max.max(child->box.getBottomRight());
} }
@@ -97,14 +95,22 @@ math::Rect Widget::getChildrenBoundingBox() {




math::Vec Widget::getRelativeOffset(math::Vec v, Widget* relative) { math::Vec Widget::getRelativeOffset(math::Vec v, Widget* relative) {
if (this == relative) {
if (this == relative)
return v; return v;
}
// Translate offset
v = v.plus(box.pos); v = v.plus(box.pos);
if (parent) {
v = parent->getRelativeOffset(v, relative);
}
return v;
if (!parent)
return v;
return parent->getRelativeOffset(v, relative);
}


float Widget::getRelativeZoom(Widget* relative) {
if (this == relative)
return 1.f;
if (!parent)
return 1.f;
return parent->getRelativeZoom(relative);
} }






+ 11
- 1
src/widget/ZoomWidget.cpp View File

@@ -6,9 +6,17 @@ namespace widget {




math::Vec ZoomWidget::getRelativeOffset(math::Vec v, Widget* relative) { math::Vec ZoomWidget::getRelativeOffset(math::Vec v, Widget* relative) {
return Widget::getRelativeOffset(v.mult(zoom), relative);
// Transform `v` (which is in child coordinates) to local coordinates.
v = v.mult(zoom);
return Widget::getRelativeOffset(v, relative);
} }



float ZoomWidget::getRelativeZoom(Widget* relative) {
return zoom * Widget::getRelativeZoom(relative);
}


math::Rect ZoomWidget::getViewport(math::Rect r) { math::Rect ZoomWidget::getViewport(math::Rect r) {
r.pos = r.pos.mult(zoom); r.pos = r.pos.mult(zoom);
r.size = r.size.mult(zoom); r.size = r.size.mult(zoom);
@@ -18,6 +26,7 @@ math::Rect ZoomWidget::getViewport(math::Rect r) {
return r; return r;
} }



void ZoomWidget::setZoom(float zoom) { void ZoomWidget::setZoom(float zoom) {
if (zoom == this->zoom) if (zoom == this->zoom)
return; return;
@@ -30,6 +39,7 @@ void ZoomWidget::setZoom(float zoom) {
Widget::onDirty(eDirty); Widget::onDirty(eDirty);
} }



void ZoomWidget::draw(const DrawArgs& args) { void ZoomWidget::draw(const DrawArgs& args) {
DrawArgs zoomCtx = args; DrawArgs zoomCtx = args;
zoomCtx.clipBox.pos = zoomCtx.clipBox.pos.div(zoom); zoomCtx.clipBox.pos = zoomCtx.clipBox.pos.div(zoom);


Loading…
Cancel
Save