iOS/Cocoa SampleApp, Drawingboard, and Networking updates
http://codereview.appspot.com/4843041/
http://codereview.appspot.com/4826061/
http://codereview.appspot.com/4832044/
http://codereview.appspot.com/4798055/
git-svn-id: http://skia.googlecode.com/svn/trunk@2058 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/DrawingBoard/SampleDrawingClient.cpp b/experimental/DrawingBoard/SampleDrawingClient.cpp
new file mode 100644
index 0000000..9885d51
--- /dev/null
+++ b/experimental/DrawingBoard/SampleDrawingClient.cpp
@@ -0,0 +1,250 @@
+#include "SampleCode.h"
+#include "SkView.h"
+#include "SkCanvas.h"
+#include "SkGPipe.h"
+#include "SkSockets.h"
+#include "SkNetPipeController.h"
+#include "SkCornerPathEffect.h"
+#include "SkColorPalette.h"
+#include "SkOSMenu.h"
+
+#define MAX_READ_PER_FRAME 5
+class DrawingClientView : public SampleView {
+public:
+ DrawingClientView() {
+ fSocket = NULL;
+ fTotalBytesRead = 0;
+ fPalette = new SkColorPalette;
+ fPalette->setSize(100, 300);
+ fPalette->setVisibleP(true);
+ this->attachChildToFront(fPalette);
+ fPalette->unref();
+ fBrushSize = SkFloatToScalar(2.5);
+ fAA = false;
+ fPaletteVisible = true;
+ fSync = false;
+ fVector = false;
+ }
+ ~DrawingClientView() {
+ if (fSocket) {
+ delete fSocket;
+ }
+ fData.reset();
+ fBuffer.reset();
+ }
+
+ virtual void requestMenu(SkOSMenu* menu) {
+ menu->setTitle("Drawing Client");
+ menu->appendTextField("Server IP", "Server IP", this->getSinkID(), "IP address or hostname");
+ menu->appendSwitch("Vector", "Vector", this->getSinkID(), fVector);
+ menu->appendSlider("Brush Size", "Brush Size", this->getSinkID(), 1.0, 100.0, fBrushSize);
+ menu->appendSwitch("Anti-Aliasing", "AA", this->getSinkID(), fAA);
+ menu->appendSwitch("Show Color Palette", "Palette", this->getSinkID(), fPaletteVisible);
+ menu->appendSwitch("Sync", "Sync", this->getSinkID(), fSync);
+ menu->appendAction("Clear", this->getSinkID());
+ }
+
+protected:
+
+ static void readData(int cid, const void* data, size_t size,
+ SkSocket::DataType type, void* context) {
+ DrawingClientView* view = (DrawingClientView*)context;
+ view->onRead(cid, data, size, type);
+ }
+
+ void onRead(int cid, const void* data, size_t size, SkSocket::DataType type) {
+ if (size > 0) {
+ fBuffer.reset();
+ if (type == SkSocket::kPipeReplace_type)
+ fBuffer.append(size, (const char*)data);
+ else if (type == SkSocket::kPipeAppend_type)
+ fData.append(size, (const char*)data);
+ else {
+ //other types of data
+ }
+ }
+ }
+
+ bool onQuery(SkEvent* evt) {
+ if (SampleCode::TitleQ(*evt)) {
+ SampleCode::TitleR(evt, "Drawing Client");
+ return true;
+ }
+
+ return this->INHERITED::onQuery(evt);
+ }
+
+ bool onEvent(const SkEvent& evt) {;
+ if (SkOSMenu::FindSliderValue(&evt, "Brush Size", &fBrushSize))
+ return true;
+
+ SkString s;
+ if (SkOSMenu::FindText(&evt, "Server IP", &s)) {
+ if (NULL != fSocket) {
+ delete fSocket;
+ }
+ fSocket = new SkTCPClient(s.c_str(), 40000);
+ fSocket->connectToServer();
+ fSocket->suspendWrite();
+ SkDebugf("Connecting to %s\n", s.c_str());
+ fData.reset();
+ fBuffer.reset();
+ this->inval(NULL);
+ return true;
+ }
+ if (SkOSMenu::FindSwitchState(&evt, "AA", &fAA) ||
+ SkOSMenu::FindSwitchState(&evt, "Sync", &fSync))
+ return true;
+ if (SkOSMenu::FindSwitchState(&evt, "Vector", &fVector)) {
+ this->clearBitmap();
+ return true;
+ }
+ if (SkOSMenu::FindAction(&evt, "Clear")) {
+ this->clear();
+ return true;
+ }
+ if (SkOSMenu::FindSwitchState(&evt, "Palette", &fPaletteVisible)) {
+ fPalette->setVisibleP(fPaletteVisible);
+ return true;
+ }
+ return this->INHERITED::onEvent(evt);
+ }
+
+ virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
+ return new Click(this);
+ }
+
+ virtual bool onClick(SkView::Click* click) {
+ switch (click->fState) {
+ case SkView::Click::kDown_State:
+ fCurrLine.moveTo(click->fCurr);
+ fType = SkSocket::kPipeReplace_type;
+ if (fSocket)
+ fSocket->resumeWrite();
+ break;
+ case SkView::Click::kMoved_State:
+ fCurrLine.lineTo(click->fCurr);
+ break;
+ case SkView::Click::kUp_State:
+ fType = SkSocket::kPipeAppend_type;
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ virtual void onDrawContent(SkCanvas* canvas) {
+ if (fSocket) {
+ if (fSocket->isConnected()) {
+ if (fSync) {
+ int count = 0;
+ while (fSocket->readPacket(readData, this) > 0 &&
+ count < MAX_READ_PER_FRAME)
+ ++count;
+ }
+ else
+ fSocket->readPacket(readData, this);
+ }
+ else
+ fSocket->connectToServer();
+ }
+ size_t bytesRead = 0;
+ SkCanvas bufferCanvas(fBase);
+ SkCanvas* tempCanvas;
+ while (fTotalBytesRead < fData.count()) {
+ if (fVector)
+ tempCanvas = canvas;
+ else
+ tempCanvas = &bufferCanvas;
+ SkGPipeReader reader(tempCanvas);
+ SkGPipeReader::Status status = reader.playback(fData.begin() + fTotalBytesRead,
+ fData.count() - fTotalBytesRead,
+ &bytesRead);
+ SkASSERT(SkGPipeReader::kError_Status != status);
+ fTotalBytesRead += bytesRead;
+ }
+ if (fVector)
+ fTotalBytesRead = 0;
+ else
+ canvas->drawBitmap(fBase, 0, 0, NULL);
+
+ size_t totalBytesRead = 0;
+ while (totalBytesRead < fBuffer.count()) {
+ SkGPipeReader reader(canvas);
+ reader.playback(fBuffer.begin() + totalBytesRead,
+ fBuffer.count() - totalBytesRead,
+ &bytesRead);
+
+ totalBytesRead += bytesRead;
+ }
+
+ SkNetPipeController controller(canvas);
+ SkGPipeWriter writer;
+ SkCanvas* writerCanvas = writer.startRecording(&controller,
+ SkGPipeWriter::kCrossProcess_Flag);
+
+ //controller.disablePlayback();
+ SkPaint p;
+ p.setColor(fPalette->getColor());
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(fBrushSize);
+ p.setStrokeCap(SkPaint::kRound_Cap);
+ p.setStrokeJoin(SkPaint::kRound_Join);
+ p.setAntiAlias(fAA);
+ p.setPathEffect(new SkCornerPathEffect(55))->unref();
+ writerCanvas->drawPath(fCurrLine, p);
+ writer.endRecording();
+
+ controller.writeToSocket(fSocket, fType);
+ if (fType == SkSocket::kPipeAppend_type && fSocket) {
+ fSocket->suspendWrite();
+ fCurrLine.reset();
+ }
+
+ this->inval(NULL);
+ }
+
+ virtual void onSizeChange() {
+ this->INHERITED::onSizeChange();
+ fPalette->setLoc(this->width()-100, 0);
+ fBase.setConfig(SkBitmap::kARGB_8888_Config, this->width(), this->height());
+ fBase.allocPixels(NULL);
+ this->clearBitmap();
+ }
+
+private:
+ void clear() {
+ fData.reset();
+ fBuffer.reset();
+ fCurrLine.reset();
+ fTotalBytesRead = 0;
+ this->clearBitmap();
+ }
+ void clearBitmap() {
+ fTotalBytesRead = 0;
+ fBase.eraseColor(fBGColor);
+ }
+ SkTDArray<char> fData;
+ SkTDArray<char> fBuffer;
+ SkBitmap fBase;
+ SkPath fCurrLine;
+ SkTCPClient* fSocket;
+ SkSocket::DataType fType;
+ SkColorPalette* fPalette;
+ bool fPaletteVisible;
+ size_t fTotalBytesRead;
+ SkScalar fBrushSize;
+ bool fAA;
+ bool fSync;
+ bool fVector;
+
+ typedef SampleView INHERITED;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new DrawingClientView; }
+static SkViewRegister reg(MyFactory);
+