#include "SkRect.h"
#include "SkDOM.h"
#include "SkTDict.h"
+#include "SkMatrix.h"
class SkCanvas;
class SkLayerView;
/** Return a rectangle set to [0, 0, width, height] */
void getLocalBounds(SkRect* bounds) const;
+ /** Loc - the view's offset with respect to its parent in its view hiearchy.
+ NOTE: For more complex transforms, use Local Matrix. The tranformations
+ are applied in the following order:
+ canvas->translate(fLoc.fX, fLoc.fY);
+ canvas->concat(fMatrix);
+ */
/** Return the view's left edge */
SkScalar locX() const { return fLoc.fX; }
/** Return the view's top edge */
void setLoc(const SkPoint& loc) { this->setLoc(loc.fX, loc.fY); }
void setLocX(SkScalar x) { this->setLoc(x, fLoc.fY); }
void setLocY(SkScalar y) { this->setLoc(fLoc.fX, y); }
+
+ /** Local Matrix - matrix used to tranform the view with respect to its
+ parent in its view hiearchy. Use setLocalMatrix to apply matrix
+ transformations to the current view and in turn affect its children.
+ NOTE: For simple offsets, use Loc. The transformations are applied in
+ the following order:
+ canvas->translate(fLoc.fX, fLoc.fY);
+ canvas->concat(fMatrix);
+ */
+ const SkMatrix& getLocalMatrix() const { return fMatrix; }
+ void setLocalMatrix(const SkMatrix& matrix);
+
/** Offset (move) the view by the specified dx and dy. This does not affect the view's size */
void offset(SkScalar dx, SkScalar dy);
private:
SkScalar fWidth, fHeight;
+ SkMatrix fMatrix;
SkPoint fLoc;
SkView* fParent;
SkView* fFirstChild;
bool setFocusView(SkView* fvOrNull);
SkView* acceptFocus(FocusDirection);
void detachFromParent_NoLayout();
+ /** Compute the matrix to transform view-local coordinates into global ones */
+ void localToGlobal(SkMatrix* matrix) const;
};
#endif
gAnimTimePrev = gAnimTime;
gAnimTime = SkTime::GetMSecs();
}
-
- SkScalar cx = fZoomCenterX;
- SkScalar cy = fZoomCenterY;
-
- if (fZoomLevel) {
- SkMatrix m;
- SkPoint center;
- m = canvas->getTotalMatrix();//.invert(&m);
- m.mapXY(cx, cy, ¢er);
- cx = center.fX;
- cy = center.fY;
-
- m.setTranslate(-cx, -cy);
- m.postScale(fZoomScale, fZoomScale);
- m.postTranslate(cx, cy);
-
- canvas->concat(m);
- }
-
- if (fFlipAxis) {
- SkMatrix m;
- m.setTranslate(cx, cy);
- if (fFlipAxis & kFlipAxis_X) {
- m.preScale(-SK_Scalar1, SK_Scalar1);
- }
- if (fFlipAxis & kFlipAxis_Y) {
- m.preScale(SK_Scalar1, -SK_Scalar1);
- }
- m.preTranslate(-cx, -cy);
- canvas->concat(m);
- }
- // Apply any gesture matrix
- if (true) {
- const SkMatrix& localM = fGesture.localM();
- if (localM.getType() & SkMatrix::kScale_Mask) {
- canvas->setExternalMatrix(&localM);
- }
- canvas->concat(localM);
- canvas->concat(fGesture.globalM());
-
- if (fGesture.isActive()) {
- this->inval(NULL);
- }
+ const SkMatrix& localM = fGesture.localM();
+ if (localM.getType() & SkMatrix::kScale_Mask) {
+ canvas->setExternalMatrix(&localM);
+ }
+ if (fGesture.isActive()) {
+ this->updateMatrix();
}
if (fNClip) {
} else {
fZoomScale = SK_Scalar1;
}
+ this->updateMatrix();
+}
+void SampleWindow::updateMatrix(){
+ SkMatrix m;
+ m.reset();
+ if (fZoomLevel) {
+ SkPoint center;
+ //m = this->getLocalMatrix();//.invert(&m);
+ m.mapXY(fZoomCenterX, fZoomCenterY, ¢er);
+ SkScalar cx = center.fX;
+ SkScalar cy = center.fY;
+
+ m.setTranslate(-cx, -cy);
+ m.postScale(fZoomScale, fZoomScale);
+ m.postTranslate(cx, cy);
+ }
+
+ if (fFlipAxis) {
+ m.preTranslate(fZoomCenterX, fZoomCenterY);
+ if (fFlipAxis & kFlipAxis_X) {
+ m.preScale(-SK_Scalar1, SK_Scalar1);
+ }
+ if (fFlipAxis & kFlipAxis_Y) {
+ m.preScale(SK_Scalar1, -SK_Scalar1);
+ }
+ m.preTranslate(-fZoomCenterX, -fZoomCenterY);
+ //canvas->concat(m);
+ }
+ // Apply any gesture matrix
+ m.preConcat(fGesture.localM());
+ m.preConcat(fGesture.globalM());
+
+ this->setLocalMatrix(m);
+
this->updateTitle();
-
this->inval(NULL);
}
-
bool SampleWindow::previousSample() {
fCurrIndex = (fCurrIndex - 1 + fSamples.count()) % fSamples.count();
this->loadView(create_transition(curr_view(this), (*fSamples[fCurrIndex])(),
}
if (SkOSMenu::FindSwitchState(evt, "Flip X", NULL)) {
fFlipAxis ^= kFlipAxis_X;
- this->updateTitle();
- this->inval(NULL);
+ this->updateMatrix();
return true;
}
if (SkOSMenu::FindSwitchState(evt, "Flip Y", NULL)) {
fFlipAxis ^= kFlipAxis_Y;
- this->updateTitle();
- this->inval(NULL);
+ this->updateMatrix();
return true;
}
if (SkOSMenu::FindAction(evt,"Save to PDF")) {
bool SampleWindow::onClick(Click* click) {
if (GestureClick::IsGesture(click)) {
- float x = SkScalarToFloat(click->fCurr.fX);
- float y = SkScalarToFloat(click->fCurr.fY);
+ float x = click->fICurr.fX;
+ float y = click->fICurr.fY;
switch (click->fState) {
case SkView::Click::kDown_State:
break;
case SkView::Click::kMoved_State:
fGesture.touchMoved(click->fOwner, x, y);
- this->inval(NULL);
+ this->updateMatrix();
break;
case SkView::Click::kUp_State:
fGesture.touchEnd(click->fOwner);
- this->inval(NULL);
+ this->updateMatrix();
break;
}
return true;
fWidth = fHeight = 0;
fLoc.set(0, 0);
fParent = fFirstChild = fNextSibling = fPrevSibling = NULL;
-
+ fMatrix.setIdentity();
fContainsFocus = 0;
}
{
this->inval(NULL);
fLoc.set(x, y);
- this->inval(NULL);
+ this->inval(NULL);
}
}
this->setLoc(fLoc.fX + dx, fLoc.fY + dy);
}
+void SkView::setLocalMatrix(const SkMatrix& matrix)
+{
+ this->inval(NULL);
+ fMatrix = matrix;
+ this->inval(NULL);
+}
+
void SkView::draw(SkCanvas* canvas)
{
if (fWidth && fHeight && this->isVisible())
if (this->isClipToBounds()) {
canvas->clipRect(r);
}
- canvas->translate(fLoc.fX, fLoc.fY);
-
+
+ canvas->translate(fLoc.fX, fLoc.fY);
+ canvas->concat(fMatrix);
+
if (fParent) {
fParent->beforeChild(this, canvas);
}
if (this->onSendClickToChildren(x, y)) {
F2BIter iter(this);
SkView* child;
-
+
while ((child = iter.next()) != NULL)
{
- Click* click = child->findClickHandler(x - child->fLoc.fX,
- y - child->fLoc.fY);
+ SkPoint p;
+ child->globalToLocal(x, y, &p);
+
+ Click* click = child->findClickHandler(p.fX, p.fY);
+
if (click) {
return click;
}
fFirstChild->detachFromParent_NoLayout();
}
+void SkView::localToGlobal(SkMatrix* matrix) const
+{
+ if (matrix) {
+ matrix->reset();
+ const SkView* view = this;
+ while (view)
+ {
+ matrix->preConcat(view->getLocalMatrix());
+ matrix->preTranslate(-view->fLoc.fX, -view->fLoc.fY);
+ view = view->fParent;
+ }
+ }
+}
void SkView::globalToLocal(SkScalar x, SkScalar y, SkPoint* local) const
{
SkASSERT(this);
-
if (local)
{
- const SkView* view = this;
- while (view)
- {
- x -= view->fLoc.fX;
- y -= view->fLoc.fY;
- view = view->fParent;
- }
- local->set(x, y);
+ SkMatrix m;
+ this->localToGlobal(&m);
+ SkPoint p;
+ m.invert(&m);
+ m.mapXY(x, y, &p);
+ local->set(p.fX, p.fY);
}
}