diff --git a/samplecode/SampleBevel.cpp b/samplecode/SampleBevel.cpp
index 868ce35..e592cf1 100644
--- a/samplecode/SampleBevel.cpp
+++ b/samplecode/SampleBevel.cpp
@@ -11,57 +11,682 @@
 #include "SkNormalSource.h"
 #include "sk_tool_utils.h"
 
+class ParentControl;
+
+// Abstract base class for all components that a control panel must have
+class Control : public SkRefCnt {
+public:
+    Control(SkString name)
+        : fName(name)
+        , fParent(nullptr)
+        , fRelativePos(SkPoint::Make(0.0f, 0.0f)) {}
+
+    // Use this to propagate a click's position down to a control. Gets modulated by the component's
+    // relative position
+    bool click(const SkPoint& clickPos) {
+        SkPoint relativeClickPos = SkPoint::Make(clickPos.fX - fRelativePos.fX,
+                                                 clickPos.fY - fRelativePos.fY);
+        return this->onClick(relativeClickPos);
+    }
+
+    // Use this to draw the control and its appropriate children. Gets modulated by the component's
+    // relative position.
+    void drawContent(SkCanvas *canvas) {
+        canvas->save();
+        canvas->translate(fRelativePos.fX, fRelativePos.fY);
+        this->onDrawContent(canvas);
+        canvas->restore();
+    }
+
+    /* Returns true when click position argumend lands over a control region in this control. Click
+     * position gets modulated by the component's relative position.
+     *
+     * @param click The position of the click in the coordinate space relative to the parent
+     */
+    bool isInCtrlRegion(const SkPoint& click) {
+        SkPoint relativeClickPos = SkPoint::Make(click.fX - fRelativePos.fX,
+                                                 click.fY - fRelativePos.fY);
+        return this->onIsInCtrlRegion(relativeClickPos);
+    }
+
+    // Returns height of content drawn
+    virtual SkScalar height() const = 0;
+
+    // Sets the parent of this component. May only be used once. Height must remain constant after
+    // parent is set.
+    void setParent(ParentControl *parent, const SkPoint& relativePos) {
+        SkASSERT(parent);
+        SkASSERT(!fParent); // No chidren transfer since relativeY would get invalid for younger kid
+
+        fParent = parent;
+        fRelativePos = relativePos;
+        this->onSetParent();
+    }
+
+    // Overriden by sub-classes that need to recompute fields after parent is set. Called after
+    // setting fParent.
+    virtual void onSetParent() {}
+
+    // Overriden by sub-classes that need to know when a click is released.
+    virtual void onClickRelease() {}
+
+protected:
+
+    // Draws a label for the component, using its name and a passed value. Does NOT modulate by
+    // relative height, expects CTM to have been adjusted in advance.
+    void drawLabel(SkCanvas *canvas, const SkString& valueStr) const {
+        // TODO Cache this
+        sk_sp<SkTypeface> fLabelTypeface =
+                sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle());
+
+        SkString label;
+        label.append(fName);
+        label.append(": ");
+        label.append(valueStr);
+
+        SkPaint labelPaint;
+        labelPaint.setTypeface(fLabelTypeface);
+        labelPaint.setAntiAlias(true);
+        labelPaint.setColor(0xFFFFFFFF);
+        labelPaint.setTextSize(12.0f);
+
+        canvas->drawText(label.c_str(), label.size(), 0, kLabelHeight - 6.0f, labelPaint);
+    }
+
+    SkString fName;
+    ParentControl* fParent;
+
+    static constexpr SkScalar kLabelHeight = 20.0f;
+
+private:
+    // Overriden by sub-class to draw component. Do not call directly, drawContent() modulates by
+    // relative position.
+    virtual void onDrawContent(SkCanvas *canvas) = 0;
+
+    // Overriden by sub-class to handle clicks. Do not call directly, click() modulates by relative
+    // position. Return true if holding mouse capture
+    virtual bool onClick(const SkPoint& clickPos) { return false; };
+
+    // Overriden by sub-classes with controls. Should return true if clickPos lands inside a control
+    // region, to enable mouse caputre.
+    virtual bool onIsInCtrlRegion(const SkPoint& clickPos) const { return false; };
+
+    // The position of the control relative to it's parent
+    SkPoint fRelativePos;
+};
+
+class ParentControl : public Control { // Interface for all controls that have children
+public:
+    ParentControl(const SkString& name) : INHERITED(name) {}
+
+    // Adds a child
+    virtual void add(sk_sp<Control> control) = 0;
+
+    // Returns the control's width. Used to propagate width down to components that don't specify it
+    virtual SkScalar width() const = 0;
+
+private:
+    typedef Control INHERITED;
+};
+
+class ControlPanel : public ParentControl {
+public:
+
+    ControlPanel(SkScalar width)
+        : ParentControl(SkString("ControlPanel"))
+        , fWidth(width)
+        , fHeight(0.0f)
+        , fSelectedControl(-1) {}
+
+    // Width unspecified, expectation is inheritance from parent
+    ControlPanel() : ControlPanel(-1.0f) {}
+
+    // Use this for introducing clicks on a ControlPanel from outside of the framework. It
+    // propagates click release or position down the chain. Returns false when click capture is
+    // being released.
+    bool inClick(SkView::Click *inClick) {
+        if (SkView::Click::State::kUp_State == inClick->fState) {
+            this->onClickRelease();
+            return false;
+        }
+        return this->click(inClick->fCurr);
+    }
+
+    // Add children
+    void add(sk_sp<Control> control) override {
+        SkASSERT(!fParent); // Validity of parent's relativeY and fHeight depends on immutability
+        fControls.push_back(control);
+        control->setParent(this, SkPoint::Make(0.0f, fHeight));
+        fHeight += control->height();
+    }
+
+    SkScalar width() const override {
+        return fParent ? fParent->width() : fWidth; // Width inherited from parent if there is one
+    }
+
+    SkScalar height() const override {
+        return fHeight;
+    }
+
+    // Propagate click release to selected control, deselect control
+    void onClickRelease() override {
+        if (fSelectedControl >= 0) {
+            fControls[fSelectedControl]->onClickRelease();
+        }
+        fSelectedControl = -1;
+    }
+
+    // Propagate onSetParent() down to children, some might need fParent->width() refresh
+    void onSetParent() override {
+        for (int i = 0; i < fControls.count(); i++) {
+            fControls[i]->onSetParent();
+        }
+    }
+
+    // Holds a vertical shelf of controls. Can't be hierarchy root if not given a width value.
+    static sk_sp<ParentControl> Make() {
+        return sk_sp<ParentControl>(new ControlPanel());
+    }
+
+    // Holds a vertical shelf of controls. Only control that can be hooked from outside the
+    // framework.
+    static sk_sp<ParentControl> Make(SkScalar width) {
+        return sk_sp<ParentControl>(new ControlPanel(width));
+    }
+
+protected:
+    // Returns true if control panel has mouse captured, false when it is ready to release
+    // capture
+    bool onClick(const SkPoint& click) override {
+
+        if (fSelectedControl == -1) { // If no child control selected, check every child
+            for (int i = 0; i < fControls.count(); i++) {
+                if (fControls[i]->isInCtrlRegion(click)) {
+                    fSelectedControl = i;
+                    break;
+                }
+            }
+        }
+
+        if (fSelectedControl >= 0) { // If child control selected, propagate click
+            bool keepSelection = fControls[fSelectedControl]->click(click);
+            if (!keepSelection) {
+                fSelectedControl = -1;
+            }
+            return keepSelection;
+        }
+
+        return false;
+    }
+
+    // Draw all children
+    void onDrawContent(SkCanvas* canvas) override {
+        canvas->save();
+        for (int i = 0; i < fControls.count(); i++) {
+            fControls[i]->drawContent(canvas);
+        }
+        canvas->restore();
+    }
+
+    // Check all children's control regions
+    bool onIsInCtrlRegion(const SkPoint& clickPos) const override {
+        for (int i = 0; i < fControls.count(); i++) {
+            if (fControls[i]->isInCtrlRegion(clickPos)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+private:
+    SkScalar fWidth;
+    SkScalar fHeight;
+
+    SkTArray<sk_sp<Control>> fControls;
+    int fSelectedControl;
+};
+
+class DiscreteSliderControl : public Control {
+public:
+    SkScalar height() const override {
+        return 2.0f * kLabelHeight;
+    }
+
+    // Set width-dependant variables when new parent is set
+    void onSetParent() override {
+        fCtrlRegion = SkRect::MakeXYWH(0.0f, kLabelHeight, fParent->width(), kSliderHeight);
+        fSliderRange = fParent->width() - kSliderWidth;
+    }
+
+    /* Make a slider for an integer value. Snaps to discrete positions.
+     *
+     * @params name    The name of the control, displayed in the label
+     * @params output  Pointer to the integer that will be set by the slider
+     * @params min     Min value for output.
+     * @params max     Max value for output.
+     */
+    static sk_sp<Control> Make(SkString name, int* output, int min, int max) {
+        return sk_sp<Control>(new DiscreteSliderControl(name, output, min, max));
+    }
+
+protected:
+    void onDrawContent(SkCanvas* canvas) override {
+        SkASSERT(fParent);
+        int numChoices = fMax - fMin + 1;
+        fSlider.offsetTo(fSliderRange * ( (*fOutput)/SkIntToScalar(numChoices)
+                                          + 1.0f/(2.0f * numChoices) ),
+                         fSlider.fTop);
+
+        SkString valueStr;
+        valueStr.appendS32(*fOutput);
+        this->drawLabel(canvas, valueStr);
+
+        SkPaint sliderPaint;
+        sliderPaint.setColor(0xFFF3F3F3);
+        canvas->drawRect(fSlider, sliderPaint);
+
+        SkPaint ctrlRegionPaint;
+        ctrlRegionPaint.setColor(0xFFFFFFFF);
+        ctrlRegionPaint.setStyle(SkPaint::kStroke_Style);
+        ctrlRegionPaint.setStrokeWidth(2.0f);
+        canvas->drawRect(fCtrlRegion, ctrlRegionPaint);
+    }
+
+    bool onClick(const SkPoint& clickPos) override {
+        SkASSERT(fParent);
+        SkScalar x = SkScalarPin(clickPos.fX, 0.0f, fSliderRange);
+        int numChoices = fMax - fMin + 1;
+        *fOutput = SkTMin(SkScalarFloorToInt(numChoices * x / fSliderRange) + fMin, fMax);
+
+        return true;
+    }
+
+    bool onIsInCtrlRegion(const SkPoint& clickPos) const override {
+        SkASSERT(fParent);
+        return fCtrlRegion.contains(SkRect::MakeXYWH(clickPos.fX, clickPos.fY, 1, 1));
+    }
+
+private:
+    DiscreteSliderControl(SkString name, int* output, int min, int max)
+            : INHERITED(name)
+            , fOutput(output)
+            , fMin(min)
+            , fMax(max) {
+        fSlider = SkRect::MakeXYWH(0, kLabelHeight, kSliderWidth, kSliderHeight);
+    }
+
+    int* fOutput;
+    int fMin;
+    int fMax;
+    SkRect fSlider; // The rectangle that slides
+    // The region in which the rectangle slides. Also the region in which mouse is caputred
+    SkRect fCtrlRegion;
+    SkScalar fSliderRange; // The width in pixels over which the slider can slide
+
+    static constexpr SkScalar kSliderHeight = 20.0f;
+    static constexpr SkScalar kSliderWidth = 10.0f;
+
+    typedef Control INHERITED;
+};
+
+class ControlSwitcher : public ParentControl {
+public:
+    // Add children
+    void add(sk_sp<Control> control) override {
+        SkASSERT(!fParent); // Validity of parent's relativeY and fHeight depends on immutability
+        fControls.push_back(control);
+        control->setParent(this, SkPoint::Make(0.0f, kSelectorHeight));
+        fHeight = SkMaxScalar(fHeight, control->height()); // Setting height to max child height.
+    }
+
+    SkScalar width() const override { return fParent ? (fParent->width()) : 0; }
+
+    SkScalar height() const override {
+        return fHeight;
+    }
+
+    // Propagate onClickRelease to control that currently captures mouse
+    void onClickRelease() override {
+        if (fCtrlOnClick) {
+            fCtrlOnClick->onClickRelease();
+        }
+        fCtrlOnClick = nullptr;
+    }
+
+    void onSetParent() override {
+        for (int i = 0; i < fControls.count(); i++) {
+            fControls[i]->onSetParent(); // Propagate to children
+        }
+
+        // Finalize control selector
+        // TODO can be moved to constructor if list-initialized
+        if (!finalizedChildren) {
+            fControlSelector = DiscreteSliderControl::Make(
+                    SkString(fName), &fSelectedControl, 0, fControls.count()-1);
+            fControlSelector->setParent(this, SkPoint::Make(0.0f, 0.0f));
+            fHeight += kSelectorHeight;
+
+            SkASSERT(fControlSelector->height() <= kSelectorHeight);
+        }
+    }
+
+    /* A set of a selector and a list of controls. Displays the control from the list of controls
+     * with the index set by the aforementioned selector.
+     *
+     * @param name The name of the switcher. Will be displayed in the selector's label.
+     */
+    static sk_sp<ParentControl> Make(const SkString& name) {
+        return sk_sp<ParentControl>(new ControlSwitcher(name));
+    }
+
+protected:
+    // Draw selector and currently selected control
+    void onDrawContent(SkCanvas* canvas) override {
+        fControlSelector->drawContent(canvas);
+        fControls[fSelectedControl]->drawContent(canvas);
+    }
+
+    // Returns true if control panel has mouse captured, false when it is ready to release
+    // capture
+    bool onClick(const SkPoint& click) override {
+        if (!fCtrlOnClick) {
+            if (fControlSelector->isInCtrlRegion(click)) {
+                fCtrlOnClick = fControlSelector.get();
+            } else if (fControls[fSelectedControl]->isInCtrlRegion(click)) {
+                fCtrlOnClick = fControls[fSelectedControl].get();
+            }
+        }
+        if (fCtrlOnClick) {
+            return fCtrlOnClick->click(click);
+        }
+
+        return false;
+    }
+
+    // Is in control region of selector or currently selected control
+    bool onIsInCtrlRegion(const SkPoint& clickPos) const override {
+        if (fControlSelector->isInCtrlRegion(clickPos)) {
+            return true;
+        }
+        if (fControls[fSelectedControl]->isInCtrlRegion(clickPos)) {
+            return true;
+        }
+
+        return false;
+    }
+
+private:
+    ControlSwitcher(const SkString& name)
+        : INHERITED(name)
+        , fHeight(0.0)
+        , fSelectedControl(0)
+        , fCtrlOnClick(nullptr){}
+
+    bool finalizedChildren = false;
+
+    sk_sp<Control> fControlSelector;
+    SkScalar fHeight;
+    SkTArray<sk_sp<Control>> fControls;
+    int fSelectedControl;
+
+    Control* fCtrlOnClick;
+
+    static constexpr SkScalar kSelectorHeight = 40.0f;
+
+    typedef ParentControl INHERITED;
+};
+
+class ContinuousSliderControl : public Control {
+public:
+    SkScalar height() const override {
+        return 2.0f * kLabelHeight;
+    }
+
+    void onSetParent() override {
+        fSlider = SkRect::MakeXYWH(0, kLabelHeight, kSliderWidth, kSliderHeight);
+        fCtrlRegion = SkRect::MakeXYWH(0.0f, kLabelHeight, fParent->width(), kSliderHeight);
+        fSliderRange = fParent->width() - kSliderWidth;
+    }
+
+    /* Make a slider for an SkScalar.
+     *
+     * @params name    The name of the control, displayed in the label
+     * @params output  Pointer to the SkScalar that will be set by the slider
+     * @params min     Min value for output
+     * @params max     Max value for output
+     */
+    static sk_sp<Control> Make(const SkString& name, SkScalar* output, SkScalar min, SkScalar max) {
+       return sk_sp<Control>(new ContinuousSliderControl(name, output, min, max));
+    }
+
+protected:
+    void onDrawContent(SkCanvas* canvas) override {
+        SkASSERT(fParent);
+        SkScalar x = fSliderRange * (*fOutput - fMin) / (fMax - fMin);
+        fSlider.offsetTo(SkScalarPin(x, 0.0f, fSliderRange), fSlider.fTop);
+
+        SkString valueStr;
+        valueStr.appendScalar(*fOutput);
+        this->drawLabel(canvas, valueStr);
+
+        SkPaint sliderPaint;
+        sliderPaint.setColor(0xFFF3F3F3);
+        canvas->drawRect(fSlider, sliderPaint);
+
+        SkPaint ctrlRegionPaint;
+        ctrlRegionPaint.setColor(0xFFFFFFFF);
+        ctrlRegionPaint.setStyle(SkPaint::kStroke_Style);
+        ctrlRegionPaint.setStrokeWidth(2.0f);
+        canvas->drawRect(fCtrlRegion, ctrlRegionPaint);
+    }
+
+    bool onClick(const SkPoint& clickPos) override {
+        SkASSERT(fParent);
+        SkScalar x = SkScalarPin(clickPos.fX, 0.0f, fSliderRange);
+        *fOutput = (x/fSliderRange) * (fMax - fMin) + fMin;
+        return true;
+    }
+
+    bool onIsInCtrlRegion(const SkPoint& clickPos) const override {
+        SkASSERT(fParent);
+        return fCtrlRegion.contains(SkRect::MakeXYWH(clickPos.fX, clickPos.fY, 1, 1));
+    }
+
+private:
+    ContinuousSliderControl(const SkString& name, SkScalar* output, SkScalar min, SkScalar max)
+            : INHERITED(name)
+            , fOutput(output)
+            , fMin(min)
+            , fMax(max) {}
+
+    SkScalar* fOutput;
+    SkScalar fMin;
+    SkScalar fMax;
+    SkRect fSlider;
+    SkRect fCtrlRegion;
+    SkScalar fSliderRange;
+
+    static constexpr SkScalar kSliderHeight = 20.0f;
+    static constexpr SkScalar kSliderWidth = 10.0f;
+
+    typedef Control INHERITED;
+};
+
+class RadialDirectionControl : public Control {
+public:
+    SkScalar height() const override {
+        return kLabelHeight + 2.0f * kRegionRadius;
+    }
+
+    /* Make a direction selector.
+     *
+     * @params name    The name of the control, displayed in the label
+     * @params output  Pointer to the SkVector that will be set by the slider
+     */
+    static sk_sp<Control> Make(const SkString& name, SkVector* output) {
+        return sk_sp<Control>(new RadialDirectionControl(name, output));
+    }
+
+protected:
+    void onDrawContent(SkCanvas* canvas) override {
+        SkASSERT(fParent);
+
+        SkString valueStr;
+        valueStr.appendf("%.2f, %.2f", fOutput->fX, fOutput->fY);
+        this->drawLabel(canvas, valueStr);
+
+        SkPoint lineEnd = SkPoint::Make(fCtrlRegion.centerX(), fCtrlRegion.centerY())
+                          + (*fOutput * (kRegionRadius - kCapRadius));
+        SkPaint linePaint;
+        linePaint.setColor(0xFFF3F3F3);
+        linePaint.setStrokeWidth(kStrokeWidth);
+        linePaint.setAntiAlias(true);
+        linePaint.setStrokeCap(SkPaint::kRound_Cap);
+        canvas->drawLine(fCtrlRegion.centerX(), fCtrlRegion.centerY(),
+                         lineEnd.fX, lineEnd.fY, linePaint);
+
+        SkPaint ctrlRegionPaint;
+        ctrlRegionPaint.setColor(0xFFFFFFFF);
+        ctrlRegionPaint.setStyle(SkPaint::kStroke_Style);
+        ctrlRegionPaint.setStrokeWidth(2.0f);
+        ctrlRegionPaint.setAntiAlias(true);
+        canvas->drawCircle(fCtrlRegion.centerX(), fCtrlRegion.centerY(), kRegionRadius,
+                           ctrlRegionPaint);
+    }
+
+    bool onClick(const SkPoint& clickPos) override {
+        SkASSERT(fParent);
+        fOutput->fX = clickPos.fX - fCtrlRegion.centerX();
+        fOutput->fY = clickPos.fY - fCtrlRegion.centerY();
+        fOutput->normalize();
+
+        return true;
+    }
+
+    bool onIsInCtrlRegion(const SkPoint& clickPos) const override {
+        SkASSERT(fParent);
+        return fCtrlRegion.contains(SkRect::MakeXYWH(clickPos.fX, clickPos.fY,
+                                                     1, 1));
+    }
+
+private:
+    RadialDirectionControl(const SkString& name, SkVector* output)
+            : INHERITED(name)
+            , fOutput(output) {
+        fCtrlRegion = SkRect::MakeXYWH(0.0f, kLabelHeight,
+                                       kRegionRadius * 2.0f, kRegionRadius * 2.0f);
+    }
+
+    SkVector* fOutput;
+    SkRect fCtrlRegion;
+
+    static constexpr SkScalar kRegionRadius = 50.0f;
+    static constexpr SkScalar kStrokeWidth = 6.0f;
+    static constexpr SkScalar kCapRadius = kStrokeWidth / 2.0f;
+
+    typedef Control INHERITED;
+};
+
+class ColorDisplay: public Control {
+public:
+    SkScalar height() const override {
+        return kHeight;
+    }
+
+    void onSetParent() override {
+        fDisplayRect = SkRect::MakeXYWH(0.0f, kPadding, fParent->width(), kHeight - kPadding);
+    }
+
+    /* Make a display that shows an SkColor3f.
+     *
+     * @params output  Pointer to the SkColor3f that will be displayed
+     */
+    static sk_sp<Control> Make(SkColor3f* input) {
+        return sk_sp<Control>(new ColorDisplay(SkString("ColorDisplay"), input));
+    }
+
+protected:
+    void onDrawContent(SkCanvas* canvas) override {
+        SkASSERT(fParent);
+
+        SkPaint displayPaint;
+        displayPaint.setColor(SkColor4f::FromColor3f(*fInput, 1.0f).toSkColor());
+        canvas->drawRect(fDisplayRect, displayPaint);
+    }
+
+private:
+    ColorDisplay(const SkString& name, SkColor3f* input)
+            : INHERITED(name)
+            , fInput(input) {}
+
+    SkColor3f* fInput;
+    SkRect fDisplayRect;
+
+    static constexpr SkScalar kHeight = 24.0f;
+    static constexpr SkScalar kPadding = 4.0f;
+
+    typedef Control INHERITED;
+};
 
 class BevelView : public SampleView {
 public:
     BevelView()
         : fShapeBounds(SkRect::MakeWH(kShapeBoundsSize, kShapeBoundsSize))
-        , fRedLight(SkLights::Light::MakeDirectional(SkColor3f::Make(0.6f, 0.45f, 0.3f),
-                                                     SkVector3::Make(0.0f, -5.0f, 1.0f)))
-        , fBlueLight(SkLights::Light::MakeDirectional(SkColor3f::Make(0.3f, 0.45f, 0.6f),
-                                                      SkVector3::Make(0.0f, 5.0f, 1.0f))) {
+        , fControlPanel(kCtrlRange) {
         this->setBGColor(0xFF666868); // Slightly colorized gray for contrast
 
-        // Lights
-        SkLights::Builder builder;
-        builder.add(fRedLight);
-        builder.add(fBlueLight);
-        builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.4f, 0.4f, 0.4f)));
-        fLights = builder.finish();
-
         // Controls
+        fBevelWidth = 25.0f;
+        fBevelHeight = 25.0f;
+        fBevelType = 0;
 
-        SkScalar currY = kSliderHeight;
+        int currLight = 0;
+        fLightDefs[currLight++] =
+                {SkVector::Make(0.0f, 1.0f), 1.0f, SkColor3f::Make(0.6f, 0.45f, 0.3f)};
+        fLightDefs[currLight++] =
+                {SkVector::Make(0.0f, -1.0f), 1.0f, SkColor3f::Make(0.3f, 0.45f, 0.6f)};
+        fLightDefs[currLight++] =
+                {SkVector::Make(1.0f, 0.0f), 1.0f, SkColor3f::Make(0.0f, 0.0f, 0.0f)};
+        // Making sure we initialized all lights
+        SkASSERT(currLight == kNumLights);
 
-        const SkScalar kWidthCtrlInitialPos = 0.2f;
-        fCtrlRangeRects[0] = SkRect::MakeXYWH(0.0f, currY,
-                                              kCtrlRange + kSliderWidth,
-                                              kSliderHeight);
-        fWidthCtrlRect = SkRect::MakeXYWH(kWidthCtrlInitialPos * kCtrlRange, currY,
-                                          kSliderWidth, kSliderHeight);
-        fBevelWidth = kBevelWidthMax * kWidthCtrlInitialPos;
-        currY += 2 * kSliderHeight;
+        fControlPanel.add(ContinuousSliderControl::Make(SkString("BevelWidth"), &fBevelWidth,
+                                                        1.0f, kShapeBoundsSize));
+        fControlPanel.add(ContinuousSliderControl::Make(SkString("BevelHeight"), &fBevelHeight,
+                                                        -50.0f, 50.0f));
+        fControlPanel.add(DiscreteSliderControl::Make(SkString("BevelType"), &fBevelType,
+                                                      0, 2));
+        sk_sp<ParentControl> lightCtrlSelector = ControlSwitcher::Make(SkString("SelectedLight"));
+        for (int i = 0; i < kNumLights; i++) {
+            SkString name("Light");
+            name.appendS32(i);
+            sk_sp<ParentControl> currLightPanel = ControlPanel::Make();
+            SkString dirName(name);
+            dirName.append("Dir");
+            currLightPanel->add(RadialDirectionControl::Make(dirName, &(fLightDefs[i].fDirXY)));
+            SkString heightName(name);
+            heightName.append("Height");
+            currLightPanel->add(ContinuousSliderControl::Make(heightName, &(fLightDefs[i].fDirZ),
+                                                             0.0f, 2.0f));
+            SkString redName(name);
+            redName.append("Red");
+            currLightPanel->add(ContinuousSliderControl::Make(redName, &(fLightDefs[i].fColor.fX),
+                                                              0.0f, 1.0f));
+            SkString greenName(name);
+            greenName.append("Green");
+            currLightPanel->add(ContinuousSliderControl::Make(greenName, &(fLightDefs[i].fColor.fY),
+                                                              0.0f, 1.0f));
+            SkString blueName(name);
+            blueName.append("Blue");
+            currLightPanel->add(ContinuousSliderControl::Make(blueName, &(fLightDefs[i].fColor.fZ),
+                                                              0.0f, 1.0f));
+            currLightPanel->add(ColorDisplay::Make(&(fLightDefs[i].fColor)));
+            lightCtrlSelector->add(currLightPanel);
+        }
+        fControlPanel.add(lightCtrlSelector);
 
-        const SkScalar kHeightCtrlInitialPos = 0.75f;
-        fCtrlRangeRects[1] = SkRect::MakeXYWH(0.0f, currY,
-                                              kCtrlRange + kSliderWidth,
-                                              kSliderHeight);
-        fHeightCtrlRect = SkRect::MakeXYWH(kHeightCtrlInitialPos * kCtrlRange, currY,
-                                           kSliderWidth, kSliderHeight);
-        // Mapping from (0, 1) to (-1, 1)
-        fBevelHeight = kBevelHeightMax * (kHeightCtrlInitialPos * 2.0f - 1.0f);
-        currY += 2 * kSliderHeight;
-
-        const SkScalar kTypeCtrlInitialPos = 1.0f / (2.0f * kBevelTypeCount);
-        fCtrlRangeRects[2] = SkRect::MakeXYWH(0.0f, currY,
-                                              kCtrlRange + kSliderWidth,
-                                              kSliderHeight);
-        fTypeCtrlRect = SkRect::MakeXYWH(kTypeCtrlInitialPos * kCtrlRange, currY,
-                                         kSliderWidth, kSliderHeight);
-        fBevelType = (SkNormalSource::BevelType) SkScalarFloorToInt(kTypeCtrlInitialPos);
-        currY += 2 * kSliderHeight;
-
-        fSelectedCtrlRect = nullptr;
+        fControlPanelSelected = false;
         fDirtyNormalSource = true;
 
         fLabelTypeface = sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle());
@@ -87,7 +712,8 @@
         SkPaint paint;
 
         if (fDirtyNormalSource) {
-            fNormalSource = SkNormalSource::MakeBevel(fBevelType, fBevelWidth, fBevelHeight);
+            fNormalSource = SkNormalSource::MakeBevel((SkNormalSource::BevelType)fBevelType,
+                                                      fBevelWidth, fBevelHeight);
             fDirtyNormalSource = false;
         }
 
@@ -112,58 +738,19 @@
     void onDrawContent(SkCanvas *canvas) override {
 
         canvas->save();
-        canvas->resetMatrix(); // Force static controls and labels
+        canvas->resetMatrix(); // Force static control panel position
+        fControlPanel.drawContent(canvas);
+        canvas->restore();
 
-        // Draw controls
-
-        SkPaint ctrlRectPaint;
-        ctrlRectPaint.setColor(0xFFF3F3F3);
-        canvas->drawRect(fWidthCtrlRect, ctrlRectPaint);
-        canvas->drawRect(fHeightCtrlRect, ctrlRectPaint);
-        canvas->drawRect(fTypeCtrlRect, ctrlRectPaint);
-
-        SkPaint ctrlRectRangePaint;
-        ctrlRectRangePaint.setColor(0xFFFFFFFF);
-        ctrlRectRangePaint.setStyle(SkPaint::kStroke_Style);
-        ctrlRectRangePaint.setStrokeWidth(2.0f);
-
-        for (size_t i = 0; i < kNumControls; i++) {
-            canvas->drawRect(fCtrlRangeRects[i], ctrlRectRangePaint);
+        SkLights::Builder builder;
+        for (int i = 0; i < kNumLights; i++) {
+            builder.add(SkLights::Light::MakeDirectional(fLightDefs[i].fColor,
+                                                         SkPoint3::Make(fLightDefs[i].fDirXY.fX,
+                                                                        fLightDefs[i].fDirXY.fY,
+                                                                        fLightDefs[i].fDirZ)));
         }
-
-        // Draw labels
-        constexpr SkScalar kTextSize = 12.0f;
-        SkString widthLabel, heightLabel, typeLabel;
-        SkPaint labelPaint;
-        labelPaint.setTypeface(fLabelTypeface);
-        labelPaint.setAntiAlias(true);
-        labelPaint.setColor(0xFFFFFFFF);
-        labelPaint.setTextSize(kTextSize);
-
-        widthLabel.appendf("BevelWidth: %f", fBevelWidth);
-        heightLabel.appendf("BevelHeight: %f", fBevelHeight);
-        typeLabel.append("BevelType: ");
-
-        switch (fBevelType) {
-            case SkNormalSource::BevelType::kLinear:
-                typeLabel.append("Linear");
-                break;
-            case SkNormalSource::BevelType::kRoundedIn:
-                typeLabel.append("RoundedIn");
-                break;
-            case SkNormalSource::BevelType::kRoundedOut:
-                typeLabel.append("RoundedOut");
-                break;
-        }
-
-        canvas->drawText(widthLabel.c_str(), widthLabel.size(), 0,
-                         fWidthCtrlRect.fTop - kTextSize/2.0f, labelPaint);
-        canvas->drawText(heightLabel.c_str(), heightLabel.size(), 0,
-                         fHeightCtrlRect.fTop - kTextSize/2.0f, labelPaint);
-        canvas->drawText(typeLabel.c_str(), typeLabel.size(), 0,
-                         fTypeCtrlRect.fTop - kTextSize/2.0f, labelPaint);
-
-        canvas->restore(); // Return to modified matrix when drawing shapes
+        builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.4f, 0.4f, 0.4f)));
+        fLights = builder.finish();
 
         // Draw shapes
         SkScalar xPos = kCtrlRange + 25.0f;
@@ -183,116 +770,56 @@
     }
 
     bool onClick(Click *click) override {
-        SkScalar x = click->fCurr.fX;
-        SkScalar y = click->fCurr.fY;
+        // Control panel mouse handling
+        fControlPanelSelected = fControlPanel.inClick(click);
 
-        SkScalar dx = x - click->fPrev.fX;
-        SkScalar dy = y - click->fPrev.fY;
-
-        // Control deselection
-        if (Click::State::kUp_State == click->fState) {
-            fSelectedCtrlRect = nullptr;
-            return true;
-        }
-
-        // Control selection
-        if (nullptr == fSelectedCtrlRect && Click::State::kDown_State == click->fState) {
-            if (fWidthCtrlRect.contains(SkRect::MakeXYWH(x, y, 1, 1))) {
-                fSelectedCtrlRect = &fWidthCtrlRect;
-            } else if (fHeightCtrlRect.contains(SkRect::MakeXYWH(x, y, 1, 1))) {
-                fSelectedCtrlRect = &fHeightCtrlRect;
-            } else if (fTypeCtrlRect.contains(SkRect::MakeXYWH(x, y, 1, 1))) {
-                fSelectedCtrlRect = &fTypeCtrlRect;
-            }
-        }
-
-        if (nullptr != fSelectedCtrlRect) { // Control modification
-            fSelectedCtrlRect->offsetTo(SkScalarPin(x, 0.0f, kCtrlRange), fSelectedCtrlRect->fTop);
-
-            fBevelHeight = (fHeightCtrlRect.fLeft / kCtrlRange) * kBevelHeightMax * 2.0f
-                           - kBevelHeightMax;
-            fBevelWidth = (fWidthCtrlRect.fLeft / kCtrlRange) * kBevelWidthMax;
-            fBevelType = (SkNormalSource::BevelType)SkTMin(
-                    SkScalarFloorToInt(kBevelTypeCount * fTypeCtrlRect.fLeft / kCtrlRange),
-                    kBevelTypeCount - 1);
-
-            // Snap type controls to 3 positions
-            fTypeCtrlRect.offsetTo(kCtrlRange * ( ((int)fBevelType)/SkIntToScalar(kBevelTypeCount)
-                                                  + 1.0f/(2.0f * kBevelTypeCount) ),
-                                   fTypeCtrlRect.fTop);
-
-            // Ensuring width is non-zero
-            fBevelWidth = SkMaxScalar(1.0f, fBevelWidth);
-
+        if (fControlPanelSelected) { // Control modification
             fDirtyNormalSource = true;
 
             this->inval(nullptr);
             return true;
-        } else { // Moving light
-            if (dx != 0 || dy != 0) {
-                float recipX = 1.0f / kAppWidth;
-                float recipY = 1.0f / kAppHeight;
-
-                if (0 == click->fModifierKeys) { // No modifier
-                    fBlueLight = SkLights::Light::MakeDirectional(fBlueLight.color(),
-                            SkVector3::Make((kAppWidth/2.0f - x) * recipX * -3.0f,
-                                            (kAppHeight/2.0f - y) * recipY * -3.0f,
-                                            1.0f));
-                } else if (1 == click->fModifierKeys) { // Shift key
-                    fRedLight = SkLights::Light::MakeDirectional(fRedLight.color(),
-                            SkVector3::Make((kAppWidth/2.0f - x) * recipX * -3.0f,
-                                            (kAppHeight/2.0f - y) * recipY * -3.0f,
-                                            1.0f));
-                }
-
-                SkLights::Builder builder;
-                builder.add(fRedLight);
-                builder.add(fBlueLight);
-                builder.add(SkLights::Light::MakeAmbient(
-                        SkColor3f::Make(0.4f, 0.4f, 0.4f)));
-                fLights = builder.finish();
-
-                this->inval(nullptr);
-            }
-            return true;
         }
 
+        // TODO move shapes
+        this->inval(nullptr);
         return true;
     }
 
 private:
     static constexpr int kNumTestRects = 3;
 
-    static constexpr SkScalar kAppWidth = 400.0f;
-    static constexpr SkScalar kAppHeight = 400.0f;
     static constexpr SkScalar kShapeBoundsSize = 120.0f;
 
     static constexpr SkScalar kCtrlRange = 150.0f;
-    static constexpr SkScalar kBevelWidthMax = kShapeBoundsSize;
-    static constexpr SkScalar kBevelHeightMax = 50.0f;
-    static constexpr int      kBevelTypeCount = 3;
 
-    static constexpr SkScalar kSliderHeight = 20.0f;
-    static constexpr SkScalar kSliderWidth = 10.0f;
+    static constexpr int kNumLights = 3;
 
     const SkRect fShapeBounds;
 
-    static constexpr int kNumControls = 3;
-    SkRect fCtrlRangeRects[kNumControls];
-    SkRect* fSelectedCtrlRect;
-    SkRect fWidthCtrlRect;
-    SkRect fHeightCtrlRect;
-    SkRect fTypeCtrlRect;
-
     SkScalar fBevelWidth;
     SkScalar fBevelHeight;
-    SkNormalSource::BevelType fBevelType;
+    int      fBevelType;
+
     sk_sp<SkNormalSource> fNormalSource;
     bool fDirtyNormalSource;
 
     sk_sp<SkLights> fLights;
-    SkLights::Light fRedLight;
-    SkLights::Light fBlueLight;
+
+    struct LightDef {
+        SkVector fDirXY;
+        SkScalar fDirZ;
+        SkColor3f fColor;
+
+        LightDef() {}
+        LightDef(SkVector dirXY, SkScalar dirZ, SkColor3f color)
+            : fDirXY(dirXY)
+            , fDirZ(dirZ)
+            , fColor(color) {}
+    };
+    LightDef fLightDefs[kNumLights];
+
+    ControlPanel fControlPanel;
+    bool fControlPanelSelected;
 
     sk_sp<SkTypeface> fLabelTypeface;
 
