1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkView.h"
9#include "SkCanvas.h"
10
11static inline uint32_t SkSetClearShift(uint32_t bits, bool cond, unsigned shift) {
12    SkASSERT((int)cond == 0 || (int)cond == 1);
13    return (bits & ~(1 << shift)) | ((int)cond << shift);
14}
15
16////////////////////////////////////////////////////////////////////////
17
18SkView::SkView(uint32_t flags) : fFlags(SkToU8(flags)) {
19    fWidth = fHeight = 0;
20}
21
22SkView::~SkView() {}
23
24void SkView::setFlags(uint32_t flags) {
25    SkASSERT((flags & ~kAllFlagMasks) == 0);
26    fFlags = SkToU8(flags);
27}
28
29void SkView::setVisibleP(bool pred) {
30    this->setFlags(SkSetClearShift(fFlags, pred, kVisible_Shift));
31}
32
33void SkView::setClipToBounds(bool pred) {
34    this->setFlags(SkSetClearShift(fFlags, !pred, kNoClip_Shift));
35}
36
37void SkView::setSize(SkScalar width, SkScalar height) {
38    width = SkMaxScalar(0, width);
39    height = SkMaxScalar(0, height);
40
41    if (fWidth != width || fHeight != height)
42    {
43        fWidth = width;
44        fHeight = height;
45        this->onSizeChange();
46    }
47}
48
49void SkView::draw(SkCanvas* canvas) {
50    if (fWidth && fHeight && this->isVisible()) {
51        SkRect    r;
52        r.set(0, 0, fWidth, fHeight);
53        if (this->isClipToBounds() && canvas->quickReject(r)) {
54            return;
55        }
56
57        SkAutoCanvasRestore    as(canvas, true);
58
59        if (this->isClipToBounds()) {
60            canvas->clipRect(r);
61        }
62
63        int sc = canvas->save();
64        this->onDraw(canvas);
65        canvas->restoreToCount(sc);
66    }
67}
68
69////////////////////////////////////////////////////////////////////////////
70
71SkView::Click::Click(SkView* target) {
72    SkASSERT(target);
73    fTargetID = target->getSinkID();
74}
75
76SkView::Click::~Click() {}
77
78SkView::Click* SkView::findClickHandler(SkScalar x, SkScalar y, unsigned modi) {
79    if (x < 0 || y < 0 || x >= fWidth || y >= fHeight) {
80        return nullptr;
81    }
82
83    return this->onFindClickHandler(x, y, modi);
84}
85
86void SkView::DoClickDown(Click* click, int x, int y, unsigned modi) {
87    SkASSERT(click);
88
89    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
90    if (nullptr == target) {
91        return;
92    }
93
94    click->fIOrig.set(x, y);
95    click->fICurr = click->fIPrev = click->fIOrig;
96
97    click->fOrig.iset(x, y);
98    click->fPrev = click->fCurr = click->fOrig;
99
100    click->fState = Click::kDown_State;
101    click->fModifierKeys = modi;
102    target->onClick(click);
103}
104
105void SkView::DoClickMoved(Click* click, int x, int y, unsigned modi) {
106    SkASSERT(click);
107
108    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
109    if (nullptr == target) {
110        return;
111    }
112
113    click->fIPrev = click->fICurr;
114    click->fICurr.set(x, y);
115
116    click->fPrev = click->fCurr;
117    click->fCurr.iset(x, y);
118
119    click->fState = Click::kMoved_State;
120    click->fModifierKeys = modi;
121    target->onClick(click);
122}
123
124void SkView::DoClickUp(Click* click, int x, int y, unsigned modi) {
125    SkASSERT(click);
126
127    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
128    if (nullptr == target) {
129        return;
130    }
131
132    click->fIPrev = click->fICurr;
133    click->fICurr.set(x, y);
134
135    click->fPrev = click->fCurr;
136    click->fCurr.iset(x, y);
137
138    click->fState = Click::kUp_State;
139    click->fModifierKeys = modi;
140    target->onClick(click);
141}
142
143//////////////////////////////////////////////////////////////////////
144
145void SkView::onDraw(SkCanvas* canvas) {}
146
147void SkView::onSizeChange() {}
148
149SkView::Click* SkView::onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
150    return nullptr;
151}
152
153bool SkView::onClick(Click*) {
154    return false;
155}
156