blob: 9885d518f963c5dbcbcbdff989817ec9d67cb64b [file] [log] [blame]
yangsu@google.comf3493f02011-08-08 15:12:05 +00001#include "SampleCode.h"
2#include "SkView.h"
3#include "SkCanvas.h"
4#include "SkGPipe.h"
5#include "SkSockets.h"
6#include "SkNetPipeController.h"
7#include "SkCornerPathEffect.h"
8#include "SkColorPalette.h"
9#include "SkOSMenu.h"
10
11#define MAX_READ_PER_FRAME 5
12class DrawingClientView : public SampleView {
13public:
14 DrawingClientView() {
15 fSocket = NULL;
16 fTotalBytesRead = 0;
17 fPalette = new SkColorPalette;
18 fPalette->setSize(100, 300);
19 fPalette->setVisibleP(true);
20 this->attachChildToFront(fPalette);
21 fPalette->unref();
22 fBrushSize = SkFloatToScalar(2.5);
23 fAA = false;
24 fPaletteVisible = true;
25 fSync = false;
26 fVector = false;
27 }
28 ~DrawingClientView() {
29 if (fSocket) {
30 delete fSocket;
31 }
32 fData.reset();
33 fBuffer.reset();
34 }
35
36 virtual void requestMenu(SkOSMenu* menu) {
37 menu->setTitle("Drawing Client");
38 menu->appendTextField("Server IP", "Server IP", this->getSinkID(), "IP address or hostname");
39 menu->appendSwitch("Vector", "Vector", this->getSinkID(), fVector);
40 menu->appendSlider("Brush Size", "Brush Size", this->getSinkID(), 1.0, 100.0, fBrushSize);
41 menu->appendSwitch("Anti-Aliasing", "AA", this->getSinkID(), fAA);
42 menu->appendSwitch("Show Color Palette", "Palette", this->getSinkID(), fPaletteVisible);
43 menu->appendSwitch("Sync", "Sync", this->getSinkID(), fSync);
44 menu->appendAction("Clear", this->getSinkID());
45 }
46
47protected:
48
49 static void readData(int cid, const void* data, size_t size,
50 SkSocket::DataType type, void* context) {
51 DrawingClientView* view = (DrawingClientView*)context;
52 view->onRead(cid, data, size, type);
53 }
54
55 void onRead(int cid, const void* data, size_t size, SkSocket::DataType type) {
56 if (size > 0) {
57 fBuffer.reset();
58 if (type == SkSocket::kPipeReplace_type)
59 fBuffer.append(size, (const char*)data);
60 else if (type == SkSocket::kPipeAppend_type)
61 fData.append(size, (const char*)data);
62 else {
63 //other types of data
64 }
65 }
66 }
67
68 bool onQuery(SkEvent* evt) {
69 if (SampleCode::TitleQ(*evt)) {
70 SampleCode::TitleR(evt, "Drawing Client");
71 return true;
72 }
73
74 return this->INHERITED::onQuery(evt);
75 }
76
77 bool onEvent(const SkEvent& evt) {;
78 if (SkOSMenu::FindSliderValue(&evt, "Brush Size", &fBrushSize))
79 return true;
80
81 SkString s;
82 if (SkOSMenu::FindText(&evt, "Server IP", &s)) {
83 if (NULL != fSocket) {
84 delete fSocket;
85 }
86 fSocket = new SkTCPClient(s.c_str(), 40000);
87 fSocket->connectToServer();
88 fSocket->suspendWrite();
89 SkDebugf("Connecting to %s\n", s.c_str());
90 fData.reset();
91 fBuffer.reset();
92 this->inval(NULL);
93 return true;
94 }
95 if (SkOSMenu::FindSwitchState(&evt, "AA", &fAA) ||
96 SkOSMenu::FindSwitchState(&evt, "Sync", &fSync))
97 return true;
98 if (SkOSMenu::FindSwitchState(&evt, "Vector", &fVector)) {
99 this->clearBitmap();
100 return true;
101 }
102 if (SkOSMenu::FindAction(&evt, "Clear")) {
103 this->clear();
104 return true;
105 }
106 if (SkOSMenu::FindSwitchState(&evt, "Palette", &fPaletteVisible)) {
107 fPalette->setVisibleP(fPaletteVisible);
108 return true;
109 }
110 return this->INHERITED::onEvent(evt);
111 }
112
113 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
114 return new Click(this);
115 }
116
117 virtual bool onClick(SkView::Click* click) {
118 switch (click->fState) {
119 case SkView::Click::kDown_State:
120 fCurrLine.moveTo(click->fCurr);
121 fType = SkSocket::kPipeReplace_type;
122 if (fSocket)
123 fSocket->resumeWrite();
124 break;
125 case SkView::Click::kMoved_State:
126 fCurrLine.lineTo(click->fCurr);
127 break;
128 case SkView::Click::kUp_State:
129 fType = SkSocket::kPipeAppend_type;
130 break;
131 default:
132 break;
133 }
134 return true;
135 }
136
137 virtual void onDrawContent(SkCanvas* canvas) {
138 if (fSocket) {
139 if (fSocket->isConnected()) {
140 if (fSync) {
141 int count = 0;
142 while (fSocket->readPacket(readData, this) > 0 &&
143 count < MAX_READ_PER_FRAME)
144 ++count;
145 }
146 else
147 fSocket->readPacket(readData, this);
148 }
149 else
150 fSocket->connectToServer();
151 }
152 size_t bytesRead = 0;
153 SkCanvas bufferCanvas(fBase);
154 SkCanvas* tempCanvas;
155 while (fTotalBytesRead < fData.count()) {
156 if (fVector)
157 tempCanvas = canvas;
158 else
159 tempCanvas = &bufferCanvas;
160 SkGPipeReader reader(tempCanvas);
161 SkGPipeReader::Status status = reader.playback(fData.begin() + fTotalBytesRead,
162 fData.count() - fTotalBytesRead,
163 &bytesRead);
164 SkASSERT(SkGPipeReader::kError_Status != status);
165 fTotalBytesRead += bytesRead;
166 }
167 if (fVector)
168 fTotalBytesRead = 0;
169 else
170 canvas->drawBitmap(fBase, 0, 0, NULL);
171
172 size_t totalBytesRead = 0;
173 while (totalBytesRead < fBuffer.count()) {
174 SkGPipeReader reader(canvas);
175 reader.playback(fBuffer.begin() + totalBytesRead,
176 fBuffer.count() - totalBytesRead,
177 &bytesRead);
178
179 totalBytesRead += bytesRead;
180 }
181
182 SkNetPipeController controller(canvas);
183 SkGPipeWriter writer;
184 SkCanvas* writerCanvas = writer.startRecording(&controller,
185 SkGPipeWriter::kCrossProcess_Flag);
186
187 //controller.disablePlayback();
188 SkPaint p;
189 p.setColor(fPalette->getColor());
190 p.setStyle(SkPaint::kStroke_Style);
191 p.setStrokeWidth(fBrushSize);
192 p.setStrokeCap(SkPaint::kRound_Cap);
193 p.setStrokeJoin(SkPaint::kRound_Join);
194 p.setAntiAlias(fAA);
195 p.setPathEffect(new SkCornerPathEffect(55))->unref();
196 writerCanvas->drawPath(fCurrLine, p);
197 writer.endRecording();
198
199 controller.writeToSocket(fSocket, fType);
200 if (fType == SkSocket::kPipeAppend_type && fSocket) {
201 fSocket->suspendWrite();
202 fCurrLine.reset();
203 }
204
205 this->inval(NULL);
206 }
207
208 virtual void onSizeChange() {
209 this->INHERITED::onSizeChange();
210 fPalette->setLoc(this->width()-100, 0);
211 fBase.setConfig(SkBitmap::kARGB_8888_Config, this->width(), this->height());
212 fBase.allocPixels(NULL);
213 this->clearBitmap();
214 }
215
216private:
217 void clear() {
218 fData.reset();
219 fBuffer.reset();
220 fCurrLine.reset();
221 fTotalBytesRead = 0;
222 this->clearBitmap();
223 }
224 void clearBitmap() {
225 fTotalBytesRead = 0;
226 fBase.eraseColor(fBGColor);
227 }
228 SkTDArray<char> fData;
229 SkTDArray<char> fBuffer;
230 SkBitmap fBase;
231 SkPath fCurrLine;
232 SkTCPClient* fSocket;
233 SkSocket::DataType fType;
234 SkColorPalette* fPalette;
235 bool fPaletteVisible;
236 size_t fTotalBytesRead;
237 SkScalar fBrushSize;
238 bool fAA;
239 bool fSync;
240 bool fVector;
241
242 typedef SampleView INHERITED;
243};
244
245
246///////////////////////////////////////////////////////////////////////////////
247
248static SkView* MyFactory() { return new DrawingClientView; }
249static SkViewRegister reg(MyFactory);
250