Explorar el Código

Merge pull request #443 from blackberry-gaming/next-ablake

Next ablake: Several UI fixes.
Sean Paul Taylor hace 13 años
padre
commit
f9be193d81

+ 2 - 2
gameplay/src/AbsoluteLayout.cpp

@@ -40,7 +40,7 @@ Layout::Type AbsoluteLayout::getType()
     return Layout::LAYOUT_ABSOLUTE;
 }
 
-void AbsoluteLayout::update(const Container* container)
+void AbsoluteLayout::update(const Container* container, const Vector2& offset)
 {
     GP_ASSERT(container);
 
@@ -53,7 +53,7 @@ void AbsoluteLayout::update(const Container* container)
         GP_ASSERT(control);
 
         align(control, container);
-        control->update(container->getClip(), Vector2::zero());
+        control->update(container, offset);
     }
 }
 

+ 1 - 1
gameplay/src/AbsoluteLayout.h

@@ -41,7 +41,7 @@ protected:
      *
      * @param container The container to update.
      */
-    void update(const Container* container);
+    void update(const Container* container, const Vector2& offset);
 
 private:
     

+ 2 - 2
gameplay/src/CheckBox.cpp

@@ -94,9 +94,9 @@ bool CheckBox::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int cont
     return Button::touchEvent(evt, x, y, contactIndex);
 }
 
-void CheckBox::update(const Rectangle& clip, const Vector2& offset)
+void CheckBox::update(const Control* container, const Vector2& offset)
 {
-    Label::update(clip, offset);
+    Label::update(container, offset);
 
     Vector2 size;
     if (_imageSize.isZero())

+ 2 - 2
gameplay/src/CheckBox.h

@@ -118,9 +118,9 @@ protected:
      * Called when a control's properties change.  Updates this control's internal rendering
      * properties, such as its text viewport.
      *
-     * @param clip The clipping rectangle of this control's parent container.
+     * @param container This control's parent container.
      */
-    void update(const Rectangle& clip, const Vector2& offset);
+    void update(const Control* container, const Vector2& offset);
 
     /**
      * Draw the checkbox icon associated with this control.

+ 33 - 33
gameplay/src/Container.cpp

@@ -290,10 +290,10 @@ Animation* Container::getAnimation(const char* id) const
     return NULL;
 }
 
-void Container::update(const Rectangle& clip, const Vector2& offset)
+void Container::update(const Control* container, const Vector2& offset)
 {
     // Update this container's viewport.
-    Control::update(clip, offset);
+    Control::update(container, offset);
 
     // Get scrollbar images and diminish clipping bounds to make room for scrollbars.
     if ((_scroll & SCROLL_HORIZONTAL) == SCROLL_HORIZONTAL)
@@ -302,6 +302,8 @@ void Container::update(const Rectangle& clip, const Vector2& offset)
         _scrollBarHorizontal = getImage("horizontalScrollBar", _state);
         _scrollBarRightCap = getImage("scrollBarRightCap", _state);
 
+        GP_ASSERT(_scrollBarLeftCap && _scrollBarHorizontal && _scrollBarRightCap);
+
         _viewportClipBounds.height -= _scrollBarHorizontal->getRegion().height;
     }
 
@@ -310,6 +312,8 @@ void Container::update(const Rectangle& clip, const Vector2& offset)
         _scrollBarTopCap = getImage("scrollBarTopCap", _state);
         _scrollBarVertical = getImage("verticalScrollBar", _state);
         _scrollBarBottomCap = getImage("scrollBarBottomCap", _state);
+
+        GP_ASSERT(_scrollBarTopCap && _scrollBarVertical && _scrollBarBottomCap);
         
         _viewportClipBounds.width -= _scrollBarVertical->getRegion().width;
     }
@@ -318,15 +322,15 @@ void Container::update(const Rectangle& clip, const Vector2& offset)
     std::sort(_controls.begin(), _controls.end(), &sortControlsByZOrder);
 
     GP_ASSERT(_layout);
-    _layout->update(this);
-
     if (_scroll != SCROLL_NONE)
-        this->updateScroll(this);
+        updateScroll();
+    else
+        _layout->update(this, Vector2::zero());
 }
 
-void Container::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, float targetHeight)
+void Container::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, bool cleared, float targetHeight)
 {
-    if (_skin && needsClear)
+    if (needsClear)
     {
         GL_ASSERT( glEnable(GL_SCISSOR_TEST) );
         GL_ASSERT( glClearColor(0, 0, 0, 0) );
@@ -337,6 +341,11 @@ void Container::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needs
         GL_ASSERT( glDisable(GL_SCISSOR_TEST) );
 
         needsClear = false;
+        cleared = true;
+    }
+    else if (!cleared)
+    {
+        needsClear = true;
     }
 
     spriteBatch->begin();
@@ -351,7 +360,7 @@ void Container::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needs
         GP_ASSERT(control);
         if (!needsClear || control->isDirty() || control->_clearBounds.intersects(boundsUnion))
         {
-            control->draw(spriteBatch, _viewportClipBounds, needsClear, targetHeight);
+            control->draw(spriteBatch, _viewportClipBounds, needsClear, cleared, targetHeight);
             Rectangle::combine(control->_clearBounds, boundsUnion, &boundsUnion);
         }
     }
@@ -363,7 +372,7 @@ void Container::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needs
 
         spriteBatch->begin();
 
-        if (_scrollBarBounds.height > 0 && (_scrolling || _velocity.y) && _scrollBarTopCap && _scrollBarVertical && _scrollBarBottomCap)
+        if (_scrollBarBounds.height > 0 && (_scrolling || _velocity.y))
         {
             const Rectangle& topRegion = _scrollBarTopCap->getRegion();
             const Theme::UVs& topUVs = _scrollBarTopCap->getUVs();
@@ -393,7 +402,7 @@ void Container::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needs
             spriteBatch->draw(bounds.x, bounds.y, bounds.width, bounds.height, bottomUVs.u1, bottomUVs.v1, bottomUVs.u2, bottomUVs.v2, bottomColor, clipRegion);
         }
 
-        if (_scrollBarBounds.width > 0 && (_scrolling || _velocity.x) && _scrollBarLeftCap && _scrollBarHorizontal && _scrollBarRightCap)
+        if (_scrollBarBounds.width > 0 && (_scrolling || _velocity.x))
         {
             const Rectangle& leftRegion = _scrollBarLeftCap->getRegion();
             const Theme::UVs& leftUVs = _scrollBarLeftCap->getUVs();
@@ -523,9 +532,8 @@ bool Container::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int con
         break;
     }
 
-    if (!eventConsumed)
+    if (!eventConsumed && _scroll != SCROLL_NONE)
     {
-        // Pass the event on to the layout.
         if (touchEventScroll(evt, x - xPos, y - yPos, contactIndex))
         {
             _dirty = true;
@@ -591,24 +599,21 @@ Layout::Type Container::getLayoutType(const char* layoutString)
     }
 }
 
-void Container::updateScroll(const Container* container)
+void Container::updateScroll()
 {
-    GP_ASSERT(container);
-
     // Update Time.
     static long lastFrameTime = Game::getGameTime();
     long frameTime = Game::getGameTime();
     long elapsedTime = (frameTime - lastFrameTime);
     lastFrameTime = frameTime;
 
-    const Rectangle& containerBounds = container->getBounds();
-    const Theme::Border& containerBorder = container->getBorder(container->getState());
-    const Theme::Padding& containerPadding = container->getPadding();
+    const Theme::Border& containerBorder = getBorder(_state);
+    const Theme::Padding& containerPadding = getPadding();
 
     // Calculate total width and height.
     float totalWidth = 0;
     float totalHeight = 0;
-    std::vector<Control*> controls = container->getControls();
+    std::vector<Control*> controls = getControls();
     unsigned int controlsCount = controls.size();
     for (unsigned int i = 0; i < controlsCount; i++)
     {
@@ -630,10 +635,10 @@ void Container::updateScroll(const Container* container)
         }
     }
 
-    float vWidth = container->getImageRegion("verticalScrollBar", container->getState()).width;
-    float hHeight = container->getImageRegion("horizontalScrollBar", container->getState()).height;
-    float clipWidth = containerBounds.width - containerBorder.left - containerBorder.right - containerPadding.left - containerPadding.right - vWidth;
-    float clipHeight = containerBounds.height - containerBorder.top - containerBorder.bottom - containerPadding.top - containerPadding.bottom - hHeight;
+    float vWidth = getImageRegion("verticalScrollBar", _state).width;
+    float hHeight = getImageRegion("horizontalScrollBar", _state).height;
+    float clipWidth = _bounds.width - containerBorder.left - containerBorder.right - containerPadding.left - containerPadding.right - vWidth;
+    float clipHeight = _bounds.height - containerBorder.top - containerBorder.bottom - containerPadding.top - containerPadding.bottom - hHeight;
 
     // Apply and dampen inertia.
     if (!_scrolling && !_velocity.isZero())
@@ -692,11 +697,7 @@ void Container::updateScroll(const Container* container)
                          scrollWidth, scrollHeight);
 
     // Position controls within scroll area.
-    for (unsigned int i = 0; i < controlsCount; i++)
-    {
-        Control* control = controls.at(i);
-        control->update(container->getClip(), _scrollPosition);
-    }
+    _layout->update(this, _scrollPosition);
 }
 
 bool Container::touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
@@ -709,7 +710,7 @@ bool Container::touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned i
         _velocity.set(0, 0);
         _scrolling = true;
         _startTimeX = _startTimeY = 0;
-        break;
+        return true;
 
     case Touch::TOUCH_MOVE:
         if (_scrolling)
@@ -753,12 +754,12 @@ bool Container::touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned i
         break;
 
     case Touch::TOUCH_RELEASE:
+        _scrolling = false;
         long timeSinceLastMove = Game::getAbsoluteTime() - _lastTime;
         if (timeSinceLastMove > STOP_TIME)
         {
             _velocity.set(0, 0);
-            _scrolling = false;
-            break;
+            return true;
         }
 
         int dx = _lastX - _firstX;
@@ -778,8 +779,7 @@ bool Container::touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned i
 
         _velocity.set(vx, vy);
 
-        _scrolling = false;
-        break;
+        return true;
     }
 
     return false;

+ 4 - 4
gameplay/src/Container.h

@@ -177,9 +177,9 @@ protected:
      * Updates each control within this container,
      * and positions them according to the container's layout.
      *
-     * @param clip The clipping rectangle of this container's parent container.
+     * @param container This container's parent container.
      */
-    virtual void update(const Rectangle& clip, const Vector2& offset);
+    virtual void update(const Control* container, const Vector2& offset);
 
     /**
      * Touch callback on touch events.  Controls return true if they consume the touch event.
@@ -229,12 +229,12 @@ protected:
      */
     void addControls(Theme* theme, Properties* properties);
 
-    virtual void draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, float targetHeight);
+    virtual void draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, bool cleared, float targetHeight);
 
     /**
      * Update scroll position and velocity.
      */
-    void updateScroll(const Container* container);
+    void updateScroll();
 
     bool touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
 

+ 7 - 4
gameplay/src/Control.cpp

@@ -731,8 +731,11 @@ void Control::notifyListeners(Listener::EventType eventType)
     }
 }
 
-void Control::update(const Rectangle& clip, const Vector2& offset)
+void Control::update(const Control* container, const Vector2& offset)
 {
+    const Rectangle& clip = container->getClip();
+    const Rectangle& absoluteViewport = container->_viewportBounds;
+
     _clearBounds.set(_absoluteClipBounds);
 
     // Calculate the clipped bounds.
@@ -774,8 +777,8 @@ void Control::update(const Rectangle& clip, const Vector2& offset)
     _clipBounds.set(x, y, width, height);
 
     // Calculate the absolute bounds.
-    x = _bounds.x + offset.x + clip.x;
-    y = _bounds.y + offset.y + clip.y;
+    x = _bounds.x + offset.x + absoluteViewport.x;
+    y = _bounds.y + offset.y + absoluteViewport.y;
     _absoluteBounds.set(x, y, _bounds.width, _bounds.height);
 
     // Calculate the absolute viewport bounds.
@@ -899,7 +902,7 @@ void Control::drawText(const Rectangle& position)
 {
 }
 
-void Control::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, float targetHeight)
+void Control::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, bool cleared, float targetHeight)
 {
     if (needsClear)
     {

+ 15 - 6
gameplay/src/Control.h

@@ -24,7 +24,6 @@ class Control : public Ref, public AnimationTarget
     friend class AbsoluteLayout;
     friend class VerticalLayout;
     friend class FlowLayout;
-    friend class ScrollLayout;
 
 public:
 
@@ -659,9 +658,19 @@ public:
      */
     Theme::Style* getStyle() const;
 
+    /**
+     * Get this control's z-index.
+     *
+     * @return This control's z-index.
+     */
     int getZIndex() const;
 
-    void setZIndex(int zOrder);
+    /**
+     * Set this control's z-index.
+     *
+     * @param zIndex The new z-index.
+     */
+    void setZIndex(int zIndex);
 
     /**
      * Add a listener to be notified of specific events affecting
@@ -739,10 +748,10 @@ protected:
      * Called when a control's properties change.  Updates this control's internal rendering
      * properties, such as its text viewport.
      *
-     * @param clip The clipping rectangle of this control's parent container.
-     * @param offset Layout-computed positioning offset to add to the control's position.
+     * @param container This control's parent container.
+     * @param offset Positioning offset to add to the control's position.
      */
-    virtual void update(const Rectangle& clip, const Vector2& offset);
+    virtual void update(const Control* container, const Vector2& offset);
 
     /**
      * Draw the images associated with this control.
@@ -761,7 +770,7 @@ protected:
      */
     virtual void drawText(const Rectangle& clip);
 
-    virtual void draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, float targetHeight);
+    virtual void draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, bool cleared, float targetHeight);
 
     /**
      * Initialize properties common to STATE_ALL Controls.

+ 2 - 2
gameplay/src/FlowLayout.cpp

@@ -39,7 +39,7 @@ Layout::Type FlowLayout::getType()
     return Layout::LAYOUT_FLOW;
 }
 
-void FlowLayout::update(const Container* container)
+void FlowLayout::update(const Container* container, const Vector2& offset)
 {
     GP_ASSERT(container);
     const Rectangle& containerBounds = container->getBounds();
@@ -80,7 +80,7 @@ void FlowLayout::update(const Container* container)
         control->setPosition(xPosition, yPosition);
         if (control->isDirty() || control->isContainer())
         {
-            control->update(container->getClip(), Vector2::zero());
+            control->update(container, offset);
         }
 
         xPosition += bounds.width + margin.right;

+ 1 - 1
gameplay/src/FlowLayout.h

@@ -34,7 +34,7 @@ protected:
      *
      * @param container The container to update.
      */
-    void update(const Container* container);
+    void update(const Container* container, const Vector2& offset);
 
 private:
 

+ 1 - 2
gameplay/src/Font.cpp

@@ -187,7 +187,6 @@ Font::Text* Font::createText(const char* text, const Rectangle& area, const Vect
     bool wrap, bool rightToLeft, const Rectangle* clip)
 {
     GP_ASSERT(text);
-    GP_ASSERT(clip);
     GP_ASSERT(_glyphs);
     GP_ASSERT(_batch);
 
@@ -628,7 +627,7 @@ void Font::drawText(const char* text, const Rectangle& area, const Vector4& colo
         }
 
         bool draw = true;
-        if (yPos < area.y)
+        if (yPos < area.y - size)
         {
             // Skip drawing until line break or wrap.
             draw = false;

+ 4 - 4
gameplay/src/Form.cpp

@@ -417,10 +417,10 @@ void Form::update()
         }
 
         GP_ASSERT(_layout);
-        _layout->update(this);
-
         if (_scroll != SCROLL_NONE)
-            this->updateScroll(this);
+            updateScroll();
+        else
+            _layout->update(this, Vector2::zero());
     }
 }
 
@@ -451,7 +451,7 @@ void Form::draw()
 
         GP_ASSERT(_theme);
         _theme->setProjectionMatrix(_projectionMatrix);
-        Container::draw(_theme->getSpriteBatch(), Rectangle(0, 0, _bounds.width, _bounds.height), _skin == NULL, _bounds.height);
+        Container::draw(_theme->getSpriteBatch(), Rectangle(0, 0, _bounds.width, _bounds.height), _skin != NULL, false, _bounds.height);
         _theme->setProjectionMatrix(_defaultProjectionMatrix);
 
         // Rebind the default framebuffer and game viewport.

+ 9 - 1
gameplay/src/FrameBuffer.cpp

@@ -10,6 +10,7 @@ namespace gameplay
 
 static unsigned int __maxRenderTargets = 0;
 static std::vector<FrameBuffer*> __frameBuffers;
+static FrameBufferHandle __defaultHandle = 0;
 
 FrameBuffer::FrameBuffer(const char* id) :
     _id(id ? id : ""), _handle(0), _renderTargets(NULL), _depthStencilTarget(NULL)
@@ -41,6 +42,13 @@ FrameBuffer::~FrameBuffer()
     }
 }
 
+void FrameBuffer::initialize()
+{
+    GLint fbo;
+    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo);
+    __defaultHandle = (FrameBufferHandle)fbo;
+}
+
 FrameBuffer* FrameBuffer::create(const char* id)
 {
     // Create GL FBO resource.
@@ -230,7 +238,7 @@ void FrameBuffer::bind()
 
 void FrameBuffer::bindDefault()
 {
-    GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, 0) );
+    GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __defaultHandle) );
 }
 
 }

+ 4 - 0
gameplay/src/FrameBuffer.h

@@ -19,6 +19,8 @@ namespace gameplay
  */
 class FrameBuffer : public Ref
 {
+    friend class Game;
+
 public:
 
     /**
@@ -118,6 +120,8 @@ private:
      */
     ~FrameBuffer();
 
+    static void initialize();
+
     std::string _id;
     FrameBufferHandle _handle;
     RenderTarget** _renderTargets;

+ 2 - 1
gameplay/src/Game.cpp

@@ -3,6 +3,7 @@
 #include "Platform.h"
 #include "RenderState.h"
 #include "FileSystem.h"
+#include "FrameBuffer.h"
 
 // Extern global variables
 GLenum __gl_error_code = GL_NO_ERROR;
@@ -92,8 +93,8 @@ bool Game::startup()
         return false;
 
     setViewport(Rectangle(0.0f, 0.0f, (float)_width, (float)_height));
-
     RenderState::initialize();
+    FrameBuffer::initialize();
 
     _animationController = new AnimationController();
     _animationController->initialize();

+ 2 - 2
gameplay/src/Label.cpp

@@ -67,9 +67,9 @@ const char* Label::getText()
     return _text.c_str();
 }
 
-void Label::update(const Rectangle& clip, const Vector2& offset)
+void Label::update(const Control* container, const Vector2& offset)
 {
-    Control::update(clip, offset);
+    Control::update(container, offset);
 
     _textBounds.set(_viewportBounds);
 

+ 2 - 2
gameplay/src/Label.h

@@ -90,10 +90,10 @@ protected:
      * Called when a label's properties change. Updates this label's internal rendering
      * properties, such as its text viewport.
      *
-     * @param clip The clipping rectangle of this label's parent container.
+     * @param container This label's parent container.
      * @param offset The scroll offset of this label's parent container.
      */
-    void update(const Rectangle& clip, const Vector2& offset);
+    void update(const Control* container, const Vector2& offset);
 
     /**
      * Draw this label's text.

+ 2 - 1
gameplay/src/Layout.h

@@ -3,6 +3,7 @@
 
 #include "Ref.h"
 #include "Touch.h"
+#include "Vector2.h"
 
 namespace gameplay
 {
@@ -68,7 +69,7 @@ protected:
      *
      * @param container The container to update.
      */
-    virtual void update(const Container* container) = 0;
+    virtual void update(const Container* container, const Vector2& offset) = 0;
 
     /**
      * Align a control within a container.

+ 2 - 2
gameplay/src/RadioButton.cpp

@@ -122,9 +122,9 @@ void RadioButton::clearSelected(const std::string& groupId)
     }
 }
 
-void RadioButton::update(const Rectangle& clip, const Vector2& offset)
+void RadioButton::update(const Control* container, const Vector2& offset)
 {
-    Label::update(clip, offset);
+    Label::update(container, offset);
 
     Vector2 size;
     if (_imageSize.isZero())

+ 2 - 2
gameplay/src/RadioButton.h

@@ -112,9 +112,9 @@ protected:
      * Called when a control's properties change.  Updates this control's internal rendering
      * properties, such as its text viewport.
      *
-     * @param clip The clipping rectangle of this control's parent container.
+     * @param container This control's parent container.
      */
-    void update(const Rectangle& clip, const Vector2& offset);
+    void update(const Control* container, const Vector2& offset);
 
     /**
      * Draw the images associated with this control.

+ 2 - 2
gameplay/src/Slider.cpp

@@ -141,9 +141,9 @@ bool Slider::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contac
     return Control::touchEvent(evt, x, y, contactIndex);
 }
 
-void Slider::update(const Rectangle& clip, const Vector2& offset)
+void Slider::update(const Control* container, const Vector2& offset)
 {
-    Label::update(clip, offset);
+    Label::update(container, offset);
 
     _minImage = getImage("minCap", _state);
     _maxImage = getImage("maxCap", _state);

+ 2 - 2
gameplay/src/Slider.h

@@ -153,10 +153,10 @@ protected:
      * Called when a slider's properties change. Updates this slider's internal rendering
      * properties, such as its text viewport.
      *
-     * @param clip The clipping rectangle of this slider's parent container.
+     * @param container This slider's parent container.
      * @param offset The scroll offset of this slider's parent container.
      */
-    void update(const Rectangle& clip, const Vector2& offset);
+    void update(const Control* container, const Vector2& offset);
 
     /**
      * The minimum value for the Slider.

+ 2 - 2
gameplay/src/TextBox.cpp

@@ -291,9 +291,9 @@ void TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
     _lastKeypress = key;
 }
 
-void TextBox::update(const Rectangle& clip, const Vector2& offset)
+void TextBox::update(const Control* container, const Vector2& offset)
 {
-    Label::update(clip, offset);
+    Label::update(container, offset);
 
     _fontSize = getFontSize(_state);
     _caretImage = getImage("textCaret", _state);

+ 2 - 2
gameplay/src/TextBox.h

@@ -110,9 +110,9 @@ protected:
      * Called when a control's properties change.  Updates this control's internal rendering
      * properties, such as its text viewport.
      *
-     * @param clip The clipping rectangle of this control's parent container.
+     * @param container This control's parent container.
      */
-    void update(const Rectangle& clip, const Vector2& offset);
+    void update(const Control* container, const Vector2& offset);
 
     /**
      * Draw the images associated with this control.

+ 3 - 3
gameplay/src/VerticalLayout.cpp

@@ -43,7 +43,7 @@ Layout::Type VerticalLayout::getType()
     return Layout::LAYOUT_VERTICAL;
 }
 
-void VerticalLayout::update(const Container* container)
+void VerticalLayout::update(const Container* container, const Vector2& offset)
 {
     GP_ASSERT(container);
 
@@ -73,7 +73,7 @@ void VerticalLayout::update(const Container* container)
     {
         Control* control = controls.at(i);
         GP_ASSERT(control);
-            
+
         align(control, container);
 
         const Rectangle& bounds = control->getBounds();
@@ -82,7 +82,7 @@ void VerticalLayout::update(const Container* container)
         yPosition += margin.top;
 
         control->setPosition(margin.left, yPosition);
-        control->update(container->getClip(), Vector2::zero());
+        control->update(container, offset);
 
         yPosition += bounds.height + margin.bottom;
 

+ 1 - 1
gameplay/src/VerticalLayout.h

@@ -67,7 +67,7 @@ protected:
      *
      * @param container The container to update.
      */
-    void update(const Container* container);
+    void update(const Container* container, const Vector2& offset);
 
     /**
      * Flag determining whether this layout will start laying out controls from the bottom of the container.