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 
SkSetClearShift(uint32_t bits,bool cond,unsigned shift)11 static 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 
SkView(uint32_t flags)18 SkView::SkView(uint32_t flags) : fFlags(SkToU8(flags)) {
19     fWidth = fHeight = 0;
20 }
21 
~SkView()22 SkView::~SkView() {}
23 
setFlags(uint32_t flags)24 void SkView::setFlags(uint32_t flags) {
25     SkASSERT((flags & ~kAllFlagMasks) == 0);
26     fFlags = SkToU8(flags);
27 }
28 
setVisibleP(bool pred)29 void SkView::setVisibleP(bool pred) {
30     this->setFlags(SkSetClearShift(fFlags, pred, kVisible_Shift));
31 }
32 
setClipToBounds(bool pred)33 void SkView::setClipToBounds(bool pred) {
34     this->setFlags(SkSetClearShift(fFlags, !pred, kNoClip_Shift));
35 }
36 
setSize(SkScalar width,SkScalar height)37 void 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 
draw(SkCanvas * canvas)49 void 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 
Click(SkView * target)71 SkView::Click::Click(SkView* target) {
72     SkASSERT(target);
73     fTargetID = target->getSinkID();
74 }
75 
~Click()76 SkView::Click::~Click() {}
77 
findClickHandler(SkScalar x,SkScalar y,unsigned modi)78 SkView::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 
DoClickDown(Click * click,int x,int y,unsigned modi)86 void 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 
DoClickMoved(Click * click,int x,int y,unsigned modi)105 void 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 
DoClickUp(Click * click,int x,int y,unsigned modi)124 void 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 
onDraw(SkCanvas * canvas)145 void SkView::onDraw(SkCanvas* canvas) {}
146 
onSizeChange()147 void SkView::onSizeChange() {}
148 
onFindClickHandler(SkScalar x,SkScalar y,unsigned modi)149 SkView::Click* SkView::onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
150     return nullptr;
151 }
152 
onClick(Click *)153 bool SkView::onClick(Click*) {
154     return false;
155 }
156