Added Debugger to Sample App, off by default
Removed CocoaDebugger from experimental
Slight changes to SkOSMenu
Bug fixes for NetPipeReader and DrawingBoard


git-svn-id: http://skia.googlecode.com/svn/trunk@2102 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/samplecode/OverView.cpp b/samplecode/OverView.cpp
index 8a9359a..1a6d9e9 100644
--- a/samplecode/OverView.cpp
+++ b/samplecode/OverView.cpp
@@ -13,6 +13,11 @@
 const SkScalar W = SkIntToScalar(640);
 const SkScalar H = SkIntToScalar(480); 
 
+static const char gIsOverview[] = "is-overview";
+bool is_overview(SkView* view) {
+    SkEvent isOverview(gIsOverview);
+    return view->doQuery(&isOverview); 
+}
 class OverView : public SkView {
 public:
     OverView(int count, const SkViewFactory factories[]);
@@ -33,6 +38,9 @@
             SampleCode::TitleR(evt, "Overview");
             return true;
         }
+        if (evt->isType(gIsOverview)) {
+            return true;
+        }
         return this->INHERITED::onQuery(evt);
     }
 
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index 15d1c28..e450a95 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -29,7 +29,7 @@
 #include "SkPDFDocument.h"
 #include "SkStream.h"
 
-#define TEST_GPIPEx
+#define TEST_GPIPE
 
 #ifdef  TEST_GPIPE
 #define PIPE_FILEx
@@ -42,13 +42,24 @@
 #include "SkSockets.h"
 SkTCPServer gServer;
 #endif
+
+#define DEBUGGERx
+#ifdef  DEBUGGER
+extern SkView* create_debugger(const char* data, size_t size);
+extern bool is_debugger(SkView* view);
+SkTDArray<char> gTempDataStore;
+#endif
+
 #endif
 
 #define USE_ARROWS_FOR_ZOOM true
 //#define DEFAULT_TO_GPU
 
 extern SkView* create_overview(int, const SkViewFactory[]);
+extern bool is_overview(SkView* view);
 extern SkView* create_transition(SkView*, SkView*, int);
+extern bool is_transition(SkView* view);
+
 
 #define ANIMATING_EVENTTYPE "nextSample"
 #define ANIMATING_DELAY     750
@@ -438,6 +449,7 @@
     fZoomScale = SK_Scalar1;
     
     fMagnify = false;
+    fDebugger = false;
     
     fSaveToPdf = false;
     fPdfCanvas = NULL;
@@ -449,7 +461,8 @@
     fAppMenu.setTitle("Global Settings");
     int itemID;
     
-    itemID =fAppMenu.appendList("Device Type", "Device Type", sinkID, 0, "Raster", "Picture", "OpenGL", NULL);
+    itemID =fAppMenu.appendList("Device Type", "Device Type", sinkID, 0, 
+                                "Raster", "Picture", "OpenGL", NULL);
     fAppMenu.assignKeyEquivalentToItem(itemID, 'd');
     itemID = fAppMenu.appendTriState("AA", "AA", sinkID, fAAState);
     fAppMenu.assignKeyEquivalentToItem(itemID, 'b');
@@ -459,14 +472,16 @@
     fAppMenu.assignKeyEquivalentToItem(itemID, 'n');
     itemID = fAppMenu.appendTriState("Hinting", "Hinting", sinkID, fHintingState);
     fAppMenu.assignKeyEquivalentToItem(itemID, 'h');
-    itemID = fAppMenu.appendSwitch("Pipe", "Pipe" , sinkID, fUsePipe);    
-    fAppMenu.assignKeyEquivalentToItem(itemID, 'p');
+    fUsePipeMenuItemID = fAppMenu.appendSwitch("Pipe", "Pipe" , sinkID, fUsePipe);    
+    fAppMenu.assignKeyEquivalentToItem(fUsePipeMenuItemID, 'p');
+#ifdef DEBUGGER
+    itemID = fAppMenu.appendSwitch("Debugger", "Debugger", sinkID, fDebugger);
+    fAppMenu.assignKeyEquivalentToItem(itemID, 'q');
+#endif
     itemID = fAppMenu.appendSwitch("Slide Show", "Slide Show" , sinkID, false);    
     fAppMenu.assignKeyEquivalentToItem(itemID, 'a');    
     itemID = fAppMenu.appendSwitch("Clip", "Clip" , sinkID, fUseClip);    
     fAppMenu.assignKeyEquivalentToItem(itemID, 'c');
-    itemID = fAppMenu.appendSwitch("Measure FPS", "Measure FPS" , sinkID, fMeasureFPS);
-    fAppMenu.assignKeyEquivalentToItem(itemID, 'f');
     itemID = fAppMenu.appendSwitch("Flip X", "Flip X" , sinkID, false); 
     fAppMenu.assignKeyEquivalentToItem(itemID, 'x');
     itemID = fAppMenu.appendSwitch("Flip Y", "Flip Y" , sinkID, false);
@@ -914,7 +929,7 @@
         this->inval(NULL);
         return;
     }
-
+    
     if (fRequestGrabImage) {
         fRequestGrabImage = false;
 
@@ -969,7 +984,24 @@
         r.set(50, 50, 50+100, 50+100);
         bm.scrollRect(&r, dx, dy, &inval);
         paint_rgn(bm, r, inval);
-    }        
+    }
+#ifdef DEBUGGER
+    SkView* curr = curr_view(this);
+    if (fDebugger && !is_debugger(curr) && !is_transition(curr) && !is_overview(curr)) {
+        //Stop Pipe when fDebugger is active
+        fUsePipe = false;
+        (void)SampleView::SetUsePipe(curr, false);
+        fAppMenu.getItemByID(fUsePipeMenuItemID)->setBool(fUsePipe);
+        this->onUpdateMenu(&fAppMenu);
+        
+        //Reset any transformations
+        fGesture.stop();
+        fGesture.reset();
+        
+        this->loadView(create_debugger(gTempDataStore.begin(), 
+                                       gTempDataStore.count()));
+    }
+#endif
 }
 
 void SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) {
@@ -1000,7 +1032,7 @@
     } else {
         (void)SampleView::SetRepeatDraw(child, 1);
     }
-    (void)SampleView::SetUsePipe(child, fUsePipe);
+    //(void)SampleView::SetUsePipe(child, fUsePipe);
 }
 
 void SampleWindow::afterChild(SkView* child, SkCanvas* canvas) {
@@ -1089,8 +1121,8 @@
         }
         return true;
     }
-    if (evt.isType("unref-transition-view")) {
-        SkEventSink::FindSink(evt.getFast32())->unref();
+    if (evt.isType("replace-transition-view")) {
+        this->loadView((SkView*)SkEventSink::FindSink(evt.getFast32()));
         return true;
     }
     if (evt.isType("set-curr-index")) {
@@ -1102,49 +1134,65 @@
         return true;
     }
     int selected = -1;
-    if (SkOSMenu::FindListIndex(&evt, "Device Type", &selected)) {
+    if (SkOSMenu::FindListIndex(evt, "Device Type", &selected)) {
         this->setDeviceType((DeviceType)selected);
         return true; 
     }
-    if (SkOSMenu::FindSwitchState(&evt, "Pipe", NULL)) {
-        this->togglePipe();
+    if (SkOSMenu::FindSwitchState(evt, "Pipe", &fUsePipe)) {
+#ifdef PIPE_NET
+        if (!fUsePipe)
+            gServer.disconnectAll();
+#endif
+        (void)SampleView::SetUsePipe(curr_view(this), fUsePipe);
+        this->updateTitle();
+        this->inval(NULL);
         return true;
     }
-    if (SkOSMenu::FindSwitchState(&evt, "Slide Show", NULL)) {
+    if (SkOSMenu::FindSwitchState(evt, "Slide Show", NULL)) {
         this->toggleSlideshow();
         return true;
     }
-    if (SkOSMenu::FindTriState(&evt, "AA", &fAAState) ||
-        SkOSMenu::FindTriState(&evt, "LCD", &fLCDState) ||
-        SkOSMenu::FindTriState(&evt, "Filter", &fFilterState) ||
-        SkOSMenu::FindTriState(&evt, "Hinting", &fHintingState) ||
-        SkOSMenu::FindSwitchState(&evt, "Clip", &fUseClip) ||
-        SkOSMenu::FindSwitchState(&evt, "Zoomer", &fShowZoomer) ||
-        SkOSMenu::FindSwitchState(&evt, "Magnify", &fMagnify) ||
-        SkOSMenu::FindSwitchState(&evt, "Measure FPS", &fMeasureFPS) ||
-        SkOSMenu::FindListIndex(&evt, "Transition-Next", &fTransitionNext) ||
-        SkOSMenu::FindListIndex(&evt, "Transition-Prev", &fTransitionPrev)) {
+    if (SkOSMenu::FindTriState(evt, "AA", &fAAState) ||
+        SkOSMenu::FindTriState(evt, "LCD", &fLCDState) ||
+        SkOSMenu::FindTriState(evt, "Filter", &fFilterState) ||
+        SkOSMenu::FindTriState(evt, "Hinting", &fHintingState) ||
+        SkOSMenu::FindSwitchState(evt, "Clip", &fUseClip) ||
+        SkOSMenu::FindSwitchState(evt, "Zoomer", &fShowZoomer) ||
+        SkOSMenu::FindSwitchState(evt, "Magnify", &fMagnify) ||
+        SkOSMenu::FindListIndex(evt, "Transition-Next", &fTransitionNext) ||
+        SkOSMenu::FindListIndex(evt, "Transition-Prev", &fTransitionPrev)) {
         this->inval(NULL);
         this->updateTitle();
         return true;
     }
-    if (SkOSMenu::FindSwitchState(&evt, "Flip X", NULL)) {
+    if (SkOSMenu::FindSwitchState(evt, "Flip X", NULL)) {
         fFlipAxis ^= kFlipAxis_X;
         this->updateTitle();
         this->inval(NULL);
         return true;
     }
-    if (SkOSMenu::FindSwitchState(&evt, "Flip Y", NULL)) {
+    if (SkOSMenu::FindSwitchState(evt, "Flip Y", NULL)) {
         fFlipAxis ^= kFlipAxis_Y;
         this->updateTitle();
         this->inval(NULL);
         return true;
     }
-    
-    if (SkOSMenu::FindAction(&evt,"Save to PDF")) {
+    if (SkOSMenu::FindAction(evt,"Save to PDF")) {
         this->saveToPdf();
         return true;
-    }    
+    } 
+#ifdef DEBUGGER
+    if (SkOSMenu::FindSwitchState(evt, "Debugger", &fDebugger)) {
+        if (fDebugger) {
+            fUsePipe = true;
+            (void)SampleView::SetUsePipe(curr_view(this), true);
+        } else {
+            this->loadView(fSamples[fCurrIndex]());
+        }
+        this->inval(NULL);
+        return true;
+    }
+#endif
     return this->INHERITED::onEvent(evt);
 }
 
@@ -1230,6 +1278,12 @@
         case 'd':
             SkGraphics::SetFontCacheUsed(0);
             return true;
+        case 'f':
+            // only 
+            fMeasureFPS = !fMeasureFPS;
+            this->updateTitle();
+            this->inval(NULL);
+            break;
         case 'g':
             fRequestGrabImage = true;
             this->inval(NULL);
@@ -1285,16 +1339,6 @@
     this->inval(NULL);
 }
 
-void SampleWindow::togglePipe() {
-    fUsePipe = !fUsePipe;
-#ifdef PIPE_NET
-    if (!fUsePipe)
-        gServer.disconnectAll();
-#endif
-    this->updateTitle();
-    this->inval(NULL);
-}
-
 #include "SkDumpCanvas.h"
 
 bool SampleWindow::onHandleKey(SkKey key) {
@@ -1427,7 +1471,7 @@
     if (prev) {
         prev->detachFromParent();
     }
-
+    
     view->setVisibleP(true);
     view->setClipToBounds(false);
     this->attachChildToFront(view)->unref();
@@ -1435,10 +1479,16 @@
 
     //repopulate the slide menu when a view is loaded
     fSlideMenu.reset();
+#ifdef DEBUGGER
+    if (!is_debugger(view) && !is_overview(view) && !is_transition(view) && fDebugger) {
+        //Force Pipe to be on if using debugger
+        fUsePipe = true;
+    }
+#endif
+    (void)SampleView::SetUsePipe(view, fUsePipe);
     if (SampleView::IsSampleView(view))
         ((SampleView*)view)->requestMenu(&fSlideMenu);
     this->onUpdateMenu(&fSlideMenu);
-    
     this->updateTitle();
 }
 
@@ -1648,10 +1698,9 @@
 SimplePC::~SimplePC() {
 //    SkASSERT(SkGPipeReader::kDone_Status == fStatus);
     if (fTotalWritten) {
-        SkDebugf("--- %d bytes %d atoms, status %d\n", fTotalWritten,
-                     fAtomsWritten, fStatus);
-        
         if (fWriteToPipe) {
+            SkDebugf("--- %d bytes %d atoms, status %d\n", fTotalWritten,
+                     fAtomsWritten, fStatus);
 #ifdef  PIPE_FILE
             //File is open in append mode
             FILE* f = fopen(FILE_PATH, "ab");
@@ -1665,6 +1714,10 @@
                 gServer.writePacket(fBlock, fTotalWritten);
             }
 #endif
+#ifdef  DEBUGGER
+            gTempDataStore.reset();
+            gTempDataStore.append(fTotalWritten, (const char*)fBlock);
+#endif
         }
     }
     sk_free(fBlock);
@@ -1701,6 +1754,9 @@
         canvas = writer.startRecording(&controller, flags);
         //Must draw before controller goes out of scope and sends data
         this->INHERITED::draw(canvas);
+        //explicitly end recording to ensure writer is flushed before the memory
+        //is freed in the deconstructor of the controller
+        writer.endRecording();
         controller.setWriteToPipe(fUsePipe);
     }
     else
diff --git a/samplecode/SampleApp.h b/samplecode/SampleApp.h
index 07c6452..729b7b1 100644
--- a/samplecode/SampleApp.h
+++ b/samplecode/SampleApp.h
@@ -82,7 +82,6 @@
     void toggleRendering();
     void toggleSlideshow();
     void toggleFPS();
-    void togglePipe();
     void showOverview();
 
     GrContext* getGrContext() const { return fDevManager->getGrContext(); }
@@ -144,11 +143,15 @@
     bool fRotate;
     bool fScale;
     bool fRequestGrabImage;
-    bool fUsePipe;
     bool fMeasureFPS;
     SkMSec fMeasureFPS_Time;
     bool fMagnify;
     
+    
+    bool fUsePipe;
+    int  fUsePipeMenuItemID;
+    bool fDebugger;
+    
     // The following are for the 'fatbits' drawing
     // Latest position of the mouse.
     int fMouseX, fMouseY;
diff --git a/samplecode/TransitionView.cpp b/samplecode/TransitionView.cpp
index 8cf3227..99d1275 100644
--- a/samplecode/TransitionView.cpp
+++ b/samplecode/TransitionView.cpp
@@ -10,9 +10,12 @@
 #include "SkTime.h"
 #include "SkInterpolator.h"
 
+extern bool is_overview(SkView* view);
+
 static const char gIsTransitionQuery[] = "is-transition";
 static const char gReplaceTransitionEvt[] = "replace-transition-view";
-static bool isTransition(SkView* view) {
+
+bool is_transition(SkView* view) {
     SkEvent isTransition(gIsTransitionQuery);
     return view->doQuery(&isTransition);
 }
@@ -37,10 +40,13 @@
         //Calling unref because next is a newly created view and TransitionView
         //is now the sole owner of fNext
         this->attachChildToFront(fNext)->unref();
+        
+        fDone = false;
+        //SkDebugf("--created transition\n");
     }
     
     ~TransitionView(){
-        //SkDebugf("deleted transition\n");
+        //SkDebugf("--deleted transition\n");
     }
     
     virtual void requestMenu(SkOSMenu* menu) {
@@ -72,11 +78,30 @@
             this->attachChildToBack(fPrev)->unref();
             this->inval(NULL);
             return true;
-        } 
+        }
+        if (evt.isType("transition-done")) {
+            fNext->setLoc(0, 0);
+            fNext->setClipToBounds(false);
+            SkEvent* evt = new SkEvent(gReplaceTransitionEvt, 
+                                       this->getParent()->getSinkID());
+            evt->setFast32(fNext->getSinkID());
+            //increate ref count of fNext so it survives detachAllChildren
+            fNext->ref();
+            this->detachAllChildren();
+            evt->post();
+            return true;
+        }
         return this->INHERITED::onEvent(evt);
     }
     virtual void onDrawBackground(SkCanvas* canvas) {}
     virtual void onDrawContent(SkCanvas* canvas) {
+        if (fDone)
+            return;
+
+        if (is_overview(fNext) || is_overview(fPrev)) {
+            fUsePipe = false;
+        }
+        
         SkScalar values[4];
         SkInterpolator::Result result = fInterp.timeToValues(SkTime::GetMSecs(), values);
         //SkDebugf("transition %x %d pipe:%d\n", this, result, fUsePipe);
@@ -89,35 +114,9 @@
             this->inval(NULL);
         }
         else {
-            fNext->setLocX(0);
-            fNext->setLocY(0);
-            fNext->setClipToBounds(false);
-            
-            SkView* parent = this->getParent();
-            int id = this->getParent()->getSinkID();
-            
-            SkEvent* evt;
-            if (isTransition(parent)) {
-                evt = new SkEvent(gReplaceTransitionEvt, id);
-                evt->setFast32(fNext->getSinkID());
-                //increate ref count of fNext so it survives detachAllChildren
-                fNext->ref();
-            }
-            else {
-                parent->attachChildToFront(fNext);
-                (void)SampleView::SetUsePipe(fNext, fUsePipe);
-                evt = new SkEvent("unref-transition-view", id);
-                evt->setFast32(this->getSinkID());
-                fUsePipe = false;
-                //keep this(TransitionView) alive so it can be deleted by its 
-                //parent through the unref-transition-view event
-                this->ref();
-                this->detachFromParent();
-            }
-            this->detachAllChildren();
-            evt->post();
+            (new SkEvent("transition-done", this->getSinkID()))->post();
+            fDone = true;
         }
-        this->inval(NULL);
     }
     
     virtual void onSizeChange() {
@@ -142,7 +141,7 @@
         fNext->setLocX(lr);
         fNext->setLocY(ud);
         
-        if (isTransition(fPrev))
+        if (is_transition(fPrev))
             lr = ud = 0;
         fEnd[kPrevX] = -lr;
         fEnd[kPrevY] = -ud;
@@ -161,6 +160,7 @@
     };
     SkView* fPrev;
     SkView* fNext;
+    bool    fDone;
     SkInterpolator fInterp;
     
     enum Direction{