Ver Fonte

Adding source and destination regions to ImageControl as well as some comments.

Adam Blake há 12 anos atrás
pai
commit
51b796c31d
4 ficheiros alterados com 111 adições e 24 exclusões
  1. 54 17
      gameplay/src/ImageControl.cpp
  2. 45 6
      gameplay/src/ImageControl.h
  3. 6 0
      gameplay/src/Theme.cpp
  4. 6 1
      gameplay/src/Theme.h

+ 54 - 17
gameplay/src/ImageControl.cpp

@@ -4,14 +4,14 @@
 namespace gameplay
 {
 
-ImageControl::ImageControl() : _image(NULL), _texture(NULL), _batch(NULL)
+ImageControl::ImageControl() :
+    _srcRegion(Rectangle::empty()), _dstRegion(Rectangle::empty()), _batch(NULL),
+    _tw(0.0f), _th(0.0f), _uvs(Theme::UVs::full())
 {
 }
 
 ImageControl::~ImageControl()
 {
-    SAFE_RELEASE(_image);
-    SAFE_RELEASE(_texture);
     SAFE_DELETE(_batch);
 }
 
@@ -45,29 +45,57 @@ void ImageControl::initialize(Theme::Style* style, Properties* properties)
     {
         setImage(path);
     }
+
+    Vector4 region;
+    properties->getVector4("srcRegion", &region);
+    setSrcRegion(region.x, region.y, region.z, region.w);
+    properties->getVector4("dstRegion", &region);
+    setDstRegion(region.x, region.y, region.z, region.w);
 }
 
 void ImageControl::setImage(const char* path)
 {
-    SAFE_RELEASE(_image);
-    SAFE_RELEASE(_texture);
     SAFE_DELETE(_batch);
-
-    _image = Image::create(path);
-    _texture = Texture::create(_image);
-    _batch = SpriteBatch::create(_texture);
+    Texture* texture = Texture::create(path);
+    _batch = SpriteBatch::create(texture);
+    _tw = 1.0f / texture->getWidth();
+    _th = 1.0f / texture->getHeight();
+    texture->release();
 }
 
 void ImageControl::setImage(Image* image)
 {
-    SAFE_RELEASE(_image);
-    SAFE_RELEASE(_texture);
     SAFE_DELETE(_batch);
+    Texture* texture = Texture::create(image);
+    _batch = SpriteBatch::create(texture);
+    _tw = 1.0f / texture->getWidth();
+    _th = 1.0f / texture->getHeight();
+    texture->release();
+}
+
+void ImageControl::setSrcRegion(float x, float y, float width, float height)
+{
+    _srcRegion.set(x, y, width, height);
+
+    _uvs.u1 = x * _tw;
+    _uvs.u2 = (x + width) * _tw;
+    _uvs.v1 = 1.0f - (y * _th);
+    _uvs.v2 = 1.0f - ((y + height) * _tw);
+}
+
+const Rectangle& ImageControl::getSrcRegion() const
+{
+    return _srcRegion;
+}
 
-    image->addRef();
-    _image = image;
-    _texture = Texture::create(_image);
-    _batch = SpriteBatch::create(_texture);
+void ImageControl::setDstRegion(float x, float y, float width, float height)
+{
+    _dstRegion.set(x, y, width, height);
+}
+
+const Rectangle& ImageControl::getDstRegion() const
+{
+    return _dstRegion;
 }
 
 void ImageControl::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip)
@@ -78,8 +106,17 @@ void ImageControl::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip)
     _batch->setProjectionMatrix(spriteBatch->getProjectionMatrix());
 
     _batch->start();
-    _batch->draw(_viewportBounds.x, _viewportBounds.y, _viewportBounds.width, _viewportBounds.height,
-        0.0f, 0.0f, 1.0f, 1.0f, Vector4::one(), _viewportClipBounds);
+    if (_dstRegion.isEmpty())
+    {
+        _batch->draw(_viewportBounds.x, _viewportBounds.y, _viewportBounds.width, _viewportBounds.height,
+            _uvs.u1, _uvs.v1, _uvs.u2, _uvs.v2, Vector4::one(), _viewportClipBounds);
+    }
+    else
+    {
+        _batch->draw(_viewportBounds.x + _dstRegion.x, _viewportBounds.y + _dstRegion.y,
+            _dstRegion.width, _dstRegion.height,
+            _uvs.u1, _uvs.v1, _uvs.u2, _uvs.v2, Vector4::one(), _viewportClipBounds);
+    }
     _batch->finish();
 
     spriteBatch->start();

+ 45 - 6
gameplay/src/ImageControl.h

@@ -5,10 +5,34 @@
 #include "Theme.h"
 #include "Image.h"
 #include "SpriteBatch.h"
+#include "Rectangle.h"
 
 namespace gameplay
 {
 
+/**
+ * An ImageControl allows forms to display images from arbitrary files not specified in the theme.
+ *
+ * The following properties are available for image controls:
+
+ @verbatim
+     imageControl <control ID>
+     {
+         style          = <styleID>
+         alignment      = <Control::Alignment constant> // Note: 'position' will be ignored.
+         position       = <x, y>
+         autoWidth      = <bool>
+         autoHeight     = <bool>
+         size           = <width, height>
+         width          = <width>   // Can be used in place of 'size', e.g. with 'autoHeight = true'
+         height         = <height>  // Can be used in place of 'size', e.g. with 'autoWidth = true'
+         consumeEvents  = <bool>    // Whether the label propagates input events to the Game's input event handler. Default is true.
+         path           = <string>  // Path to image or texture atlas.
+         srcRegion      = <x, y, width, height>  // Region within file to create UVs from.
+         dstRegion      = <x, y, width, height>  // Region of control's viewport to draw into.
+     }
+ @endverbatim
+ */
 class ImageControl : public Control
 {
     friend class Container;
@@ -18,8 +42,16 @@ public:
     static ImageControl* create(const char* id, Theme::Style* style);
 
     void setImage(const char* path);
+    
     void setImage(Image* image);
-    //void setImageData(const char* data);
+
+    void setSrcRegion(float x, float y, float width, float height);
+
+    const Rectangle& getSrcRegion() const;
+
+    void setDstRegion(float x, float y, float width, float height);
+
+    const Rectangle& getDstRegion() const;
 
     Image* getImage() const;
 
@@ -33,14 +65,21 @@ protected:
 
     virtual void initialize(Theme::Style* style, Properties* properties);
 
-    //void update(const Control* container, const Vector2& offset);
-
-    //void draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, bool cleared, float targetHeight);
     void drawImages(SpriteBatch* spriteBatch, const Rectangle& clip);
 
-    Image* _image;
-    Texture* _texture;
+    /* Source region: Region of the file to use as a single image. */
+    Rectangle _srcRegion;
+    /* Destination region: Region within the control to draw the image. */
+    Rectangle _dstRegion;
+    /* The SpriteBatch used to draw the image. */
     SpriteBatch* _batch;
+    
+    /* One over texture width and height, for use when calculating UVs from a new source region. */
+    float _tw;
+    float _th;
+    
+    /* Calculated UVs. */
+    Theme::UVs _uvs;
 
 private:
 

+ 6 - 0
gameplay/src/Theme.cpp

@@ -506,6 +506,12 @@ const Theme::UVs& Theme::UVs::empty()
     return empty;
 }
 
+const Theme::UVs& Theme::UVs::full()
+{
+    static UVs full(0, 0, 1, 1);
+    return full;
+}
+
 /**********************
  * Theme::SideRegions *
  **********************/

+ 6 - 1
gameplay/src/Theme.h

@@ -170,10 +170,15 @@ public:
         UVs(float u1, float v1, float u2, float v2);
 
         /**
-         * Get's an empty UVs.
+         * Gets an empty UVs struct (0, 0, 0, 0).
          */
         static const UVs& empty();
 
+        /**
+         * Gets UVs covering an entire texture (0, 0, 1, 1).
+         */
+        static const UVs& full();
+
         /**
          * u component of the first UV coordinate.
          */