Просмотр исходного кода

Initial sprite editor rework started, automatic sprite frame generation

Ivan Safrin 11 лет назад
Родитель
Сommit
bfd7abe28f

+ 61 - 66
IDE/Contents/Include/PolycodeSpriteEditor.h

@@ -28,63 +28,66 @@
 
 using namespace Polycode;
 
-class SpriteAnimationEntry : public PropProp {
-	public:
-		SpriteAnimationEntry(SpriteAnimation *animation);
-		~SpriteAnimationEntry();
-		
-		void setPropWidth(Number width);
-		
-		void handleEvent(Event *event);
-		
-		UITextInput *nameInput;
-		UITextInput *framesInput;
-		UITextInput *speedInput;
-						
-		UIImageButton *removeButton;
-		UIImageButton *playButton;	
-		
-		SpriteAnimation *animation;
-};
-
 
-class SpritePreviewProp : public PropProp {
-	public:
-		SpritePreviewProp();
-		void setSprite(SceneSprite *sprite);	
-		void setPropWidth(Number width);		
-		void setSpriteScale(Number scale);		
-		SceneSprite *previewSprite;
-		Number propWidth;
+class SpriteFrame {
+    public:
+        Polycode::Rectangle coordinates;
+        Vector2 anchorPoint;
 };
 
-class SpritePreviewSheet : public PropSheet {
-	public:
-		SpritePreviewSheet();
-		void handleEvent(Event *event);
-		void setSprite(SceneSprite *sprite);
-		
-	protected:
-		SliderProp *zoomProp;
-		SpritePreviewProp *previewProp;
+class SceneSpriteRewrite : public SceneMesh {
+    public:
+        SceneSpriteRewrite(String imageFileName);
+        ~SceneSpriteRewrite();
+    
+    
+    
+        // frame manipulation
+        void addSpriteFrame(const SpriteFrame &frame);
+        unsigned int getNumFrames() const;
+        SpriteFrame getSpriteFrame(unsigned int index) const;
+        void clearFrames();
+    
+        // automatic frame generation
+        void createGridFrames(Number width, Number height);
+        void createFramesFromIslands(unsigned int minDistance);
+    
+    protected:
+    
+        std::vector<SpriteFrame> frames;
 };
 
-class SpriteAnimationsSheet : public PropSheet {
-	public:
-		SpriteAnimationsSheet();
-		void setSprite(SceneSprite *sprite);		
-		void refreshAnimationEntries();	
-		void handleEvent(Event *event);
-		void Update();
-		void Resize(Number width, Number height);
-		
-	protected:
-	
-		int removeIndex;
-		SceneSprite *sprite;
-		int lastNumProps;
-		UILabel *animHelpLabel;
-		UIButton *addAnimationButton;
+class SpriteSheetEditor : public UIElement {
+    public:
+        SpriteSheetEditor(SceneSpriteRewrite *sprite);
+        ~SpriteSheetEditor();
+    
+        void handleEvent(Event *event);
+    
+        void Update();
+    
+        void Resize(Number width, Number height);
+    
+    protected:
+    
+        SceneSpriteRewrite *sprite;
+        UIRect *previewImage;
+    
+        UIImage *previewBg;
+    
+        SceneMesh *frameVisualizerMesh;
+    
+        Entity *bottomMenu;
+        UIRect *bottomMenuRect;
+        UIButton *changeImageButton;
+        UIButton *generateFramesButton;
+    
+        UITextInput *uniformGridWidthInput;
+        UITextInput *uniformGridHeightInput;
+    
+        UITextInput *minimumDistanceInput;
+    
+        UIComboBox *generateTypeDropdown;
 };
 
 class PolycodeSpriteEditor : public PolycodeEditor {
@@ -96,24 +99,16 @@ class PolycodeSpriteEditor : public PolycodeEditor {
 		
 		bool openFile(OSFileEntry filePath);
 		void Resize(int x, int y);
-		
 		void saveFile();
 				
 	protected:
 	
-		SpriteAnimationsSheet *animationsSheet;
-			
-		PropList *propList;		
-		UIRect *headerBg;	
-		
-		TextureProp *textureProp;
-		NumberProp *widthProp;
-		NumberProp *heightProp;	
-		
-		bool initialLoad;
-		
-		SceneSprite *previewSprite;		
-		SpritePreviewSheet *previewPropSheet;
+        SceneSpriteRewrite *sprite;
+        UIVSizer *mainSizer;
+        UIHSizer *topSizer;
+    
+        SpriteSheetEditor *spriteSheetEditor;
+    
 };
 
 class PolycodeSpriteEditorFactory : public PolycodeEditorFactory {

BIN
IDE/Contents/Resources/Images/main/stipple.png


BIN
IDE/Contents/Resources/ImagesRetina/main/grid_dark.png


BIN
IDE/Contents/Resources/ImagesRetina/main/stipple.png


+ 319 - 318
IDE/Contents/Source/PolycodeSpriteEditor.cpp

@@ -28,371 +28,372 @@ extern PolycodeFrame *globalFrame;
 extern UIGlobalMenu *globalMenu;
 
 
-SpriteAnimationEntry::SpriteAnimationEntry(SpriteAnimation *animation) : PropProp("","") {
-	
-	this->animation = animation;
-	
-	removeButton = new UIImageButton("main/remove_icon.png", 1.0, 12, 12);
-	removeButton->setPosition(0, 5);
-	removeButton->addEventListener(this, UIEvent::CLICK_EVENT);
-	addChild(removeButton);
-
-	nameInput = new UITextInput(false, 82, 12);
-	nameInput->setText(animation->name);
-	nameInput->setPosition(20, 0);
-	nameInput->addEventListener(this, UIEvent::CHANGE_EVENT);
-	addChild(nameInput);
-
-	framesInput = new UITextInput(false, 142, 12);
-	framesInput->setText(animation->frames);
-	framesInput->setPosition(115, 0);
-	framesInput->addEventListener(this, UIEvent::CHANGE_EVENT);
-	addChild(framesInput);
-
-	speedInput = new UITextInput(false, 42, 12);
-	speedInput->setText(String::NumberToString(animation->speed));
-	speedInput->setPosition(270, 0);
-	speedInput->addEventListener(this, UIEvent::CHANGE_EVENT);
-	addChild(speedInput);
-	
-	playButton = new UIImageButton("main/play_icon.png", 1.0, 16, 16);
-	playButton->setPosition(330, 3);
-	playButton->addEventListener(this, UIEvent::CLICK_EVENT);
-	addChild(playButton);
-	
-	setHeight(30);
-	
-}
-
-void SpriteAnimationEntry::setPropWidth(Number width) {
-	Number fieldsWidth = width - 40 - 15 - PROP_PADDING;
-	
-	nameInput->Resize(fieldsWidth * 0.4, nameInput->getHeight());
-	framesInput->Resize(fieldsWidth * 0.4, framesInput->getHeight());
-	speedInput->Resize(fieldsWidth * 0.2, speedInput->getHeight());
-	
-	framesInput->setPositionX(nameInput->getPosition().x + nameInput->getWidth() + 5);
-	speedInput->setPositionX(framesInput->getPosition().x + framesInput->getWidth() + 5);
-	playButton->setPositionX(speedInput->getPosition().x + speedInput->getWidth() + 5);
+SceneSpriteRewrite::SceneSpriteRewrite(String imageFileName) : SceneMesh(Mesh::QUAD_MESH) {
+    Texture *spriteTexture = Services()->getMaterialManager()->createTextureFromFile(imageFileName, true, Services()->getMaterialManager()->mipmapsDefault);
+    setTexture(spriteTexture);
 }
 
-void SpriteAnimationEntry::handleEvent(Event *event) {
-
-	if(event->getEventCode() == UIEvent::CHANGE_EVENT && event->getEventType() == "UIEvent") {
-		if(event->getDispatcher() == nameInput) {
-			animation->name = nameInput->getText();
-		}
-
-		if(event->getDispatcher() == framesInput) {
-			animation->setOffsetsFromFrameString(framesInput->getText());
-		}
-
-		if(event->getDispatcher() == speedInput) {
-			animation->speed = atof(speedInput->getText().c_str());
-		}
-
-	}
-	
-	if(event->getEventCode() == UIEvent::CLICK_EVENT && event->getEventType() == "UIEvent") {
-		if(event->getDispatcher() == removeButton) {
-			dispatchEvent(new Event(), Event::CANCEL_EVENT);
-		}
-
-		if(event->getDispatcher() == playButton) {
-			dispatchEvent(new Event(), Event::CHANGE_EVENT);
-		}
-
-	}
+void SceneSpriteRewrite::addSpriteFrame(const SpriteFrame &frame) {
+    frames.push_back(frame);
 }
 
-SpriteAnimationEntry::~SpriteAnimationEntry() {
-	delete nameInput;
-	delete framesInput;
-	delete speedInput;
-	delete removeButton;
-	delete playButton;
+unsigned int SceneSpriteRewrite::getNumFrames() const {
+    return frames.size();
 }
 
-SpritePreviewSheet::SpritePreviewSheet() : PropSheet("SPRITE PREVIEW", ""){
-	zoomProp = new SliderProp("Zoom", 0.1, 16);
-	addProp(zoomProp);
-	zoomProp->addEventListener(this, Event::CHANGE_EVENT);	
-	
-	zoomProp->set(1.0);
-	
-	previewProp = new SpritePreviewProp();
-	addProp(previewProp);
+SpriteFrame SceneSpriteRewrite::getSpriteFrame(unsigned int index) const {
+    if(index < frames.size()) {
+        return frames[index];
+    } else {
+        return SpriteFrame();
+    }
 }
 
-void SpritePreviewSheet::handleEvent(Event *event) {
-	if(event->getDispatcher() == zoomProp) {
-        previewProp->setSpriteScale(zoomProp->get());
-		
-		if(previewProp->previewSprite) {
-			propHeight = (previewProp->previewSprite->getHeight() * previewProp->previewSprite->getScale().y) + zoomProp->getHeight()+ 50;						
-			dispatchEvent(new Event(), Event::COMPLETE_EVENT);
-		}
-	}
-	PropSheet::handleEvent(event);
+SceneSpriteRewrite::~SceneSpriteRewrite() {
+    
 }
 
-void SpritePreviewSheet::setSprite(SceneSprite *sprite) {
-	previewProp->setSprite(sprite);
-	propHeight = sprite->getHeight() + zoomProp->getHeight()+ 50;	
-	dispatchEvent(new Event(), Event::COMPLETE_EVENT);
+void SceneSpriteRewrite::clearFrames() {
+    frames.clear();
 }
 
-SpritePreviewProp::SpritePreviewProp() : PropProp("", "") {
-	previewSprite = NULL;
+void SceneSpriteRewrite::createGridFrames(Number width, Number height) {
+    
+    for(Number x = 0.0; x+width <= 1.0; x += width) {
+        for(Number y = 0.0; y+height <= 1.0; y += height) {
+            SpriteFrame frame;
+            frame.coordinates = Polycode::Rectangle(x, y, width, height);
+            addSpriteFrame(frame);
+        }
+    }
 }
 
-void SpritePreviewProp::setPropWidth(Number width) {
-	if(previewSprite) {
-		previewSprite->setPosition(((width-(previewSprite->getWidth()* previewSprite->getScale().x))/2.0) - propContents->getPosition().x, 0.0);
-	}
-	propWidth = width;
+Polycode::Rectangle createBoxAtCoordinate(Image *image, unsigned int x, unsigned int y) {
+    Polycode::Rectangle rect;
+    
+    rect.x = x;
+    rect.y = y;
+    
+    while(x < image->getWidth()) {
+        if(image->getPixel(x, y).a == 0.0) {
+            break;
+        }
+        x++;
+    }
+    rect.w = x - rect.x;
+    
+    // look down at first x
+    Number y1 = y;
+    while(y1 < image->getHeight()) {
+        if(image->getPixel(rect.x, y1).a == 0.0) {
+            break;
+        }
+        y1++;
+    }
+    Number h1 = y1;
+    
+    // look down at last x
+    while(y < image->getHeight()) {
+        if(image->getPixel(x, y).a == 0.0) {
+            break;
+        }
+        y++;
+    }
+    Number h2 = y;
+
+    if(h1 > h2) {
+        h2 = h1;
+    }
+    
+    rect.h = h2 - rect.y;
+    
+
+    
+    return rect;
 }
 
-void SpritePreviewProp::setSprite(SceneSprite *sprite) {
-	previewSprite = sprite;
-	propContents->addChild(sprite);
-    setSpriteScale(1.0);
+bool rectIntersect(const Polycode::Rectangle &r1, const Polycode::Rectangle &r2, Number minDistance) {
+    return !(r2.x - minDistance > r1.x + r1.w ||
+             r2.x + r2.w + minDistance < r1.x ||
+             r2.y - minDistance > r1.y + r1.h ||
+             r2.y + r2.h + minDistance < r1.y);
 }
 
-void SpritePreviewProp::setSpriteScale(Number scale) {
-	if(!previewSprite) {
-		return;
-	}
-	previewSprite->setScale(scale, scale);
-	setPropWidth(propWidth);
-    this->setHeight((previewSprite->getHeight() * scale) + 20);
+void SceneSpriteRewrite::createFramesFromIslands(unsigned int minDistance) {
+    String imageFileName = getTexture()->getResourcePath();
+    
+    Image *image = new Image(imageFileName);
+    
+    
+    std::vector<Polycode::Rectangle> rects;
+    
+    for(int y=0; y < image->getHeight(); y++) {
+        for(int x=0; x < image->getWidth(); x++) {
+            if(image->getPixel(x, y).a > 0.0) {
+                Polycode::Rectangle rect = createBoxAtCoordinate(image,x,y);
+                rects.push_back(rect);
+                x += rect.w;
+            }
+        }
+    }
+    
+    while(rects.size() > 1) {
+
+        bool intersected = false;
+        for(int i=0; i < rects.size(); i++) {
+            for(int i2=0; i2 < rects.size(); i2++) {
+                if(i != i2) {
+                    if(rectIntersect(rects[i], rects[i2], minDistance)) {
+
+                        Polycode::Rectangle newRect;
+                        
+                        newRect.x = std::min(rects[i].x, rects[i2].x);
+                        newRect.y = std::min(rects[i].y, rects[i2].y);
+                        
+                        newRect.w = std::max(rects[i].x + rects[i].w, rects[i2].x + rects[i2].w) - newRect.x;
+                        newRect.h = std::max(rects[i].y + rects[i].h, rects[i2].y + rects[i2].h) - newRect.y;
+                        
+                        rects[i] = newRect;
+                        rects.erase(rects.begin() + i2);
+                        
+                        intersected = true;
+                        
+                        break;
+                    }
+                }
+            }
+        }
+
+        if(!intersected) {
+            break;
+        }
+  
+    }
+    
+    
+    for(int i=0; i < rects.size(); i++) {
+        SpriteFrame frame;
+        frame.coordinates = rects[i];
+        
+        frame.coordinates.x = frame.coordinates.x / ((Number)image->getWidth());
+        frame.coordinates.y = frame.coordinates.y / ((Number)image->getHeight());
+        frame.coordinates.w = frame.coordinates.w / ((Number)image->getWidth());
+        frame.coordinates.h = frame.coordinates.h / ((Number)image->getHeight());
+        
+        addSpriteFrame(frame);
+    }
+    
+    delete image;
+    
+    
 }
 
-SpriteAnimationsSheet::SpriteAnimationsSheet() : PropSheet("ANIMATIONS", "") {
-	animHelpLabel = new UILabel("Comma separated frames, ranges or repeats (e.g. 1,2,3-7,8x5)", 11);
-	contents->addChild(animHelpLabel);
-
-	propHeight = 230;
-		
-	addAnimationButton = new UIButton("Add Animation", 100);
-	contents->addChild(addAnimationButton);
-	addAnimationButton->addEventListener(this, UIEvent::CLICK_EVENT);
-	
-	setTopPadding(30);
-	lastNumProps = 0;
-	sprite = NULL;
-	removeIndex = -1;
+SpriteSheetEditor::SpriteSheetEditor(SceneSpriteRewrite *sprite) : UIElement() {
+    
+    this->sprite = sprite;
+    
+    enableScissor = true;
+    
+    previewBg = new UIImage("main/grid_dark.png");
+    addChild(previewBg);
+    
+    previewImage = new UIRect(10, 10);
+    previewImage->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
+    addChild(previewImage);
+    
+    frameVisualizerMesh = new SceneMesh(Mesh::LINE_MESH);
+    frameVisualizerMesh->setColor(1.0, 1.0, 1.0, 1.0);
+    addChild(frameVisualizerMesh);
+    frameVisualizerMesh->setAnchorPoint(-1.0, -1.0, 0.0);
+    
+    frameVisualizerMesh->loadTexture("main/stipple.png");
+    
+    frameVisualizerMesh->lineWidth = 1; //CoreServices::getInstance()->getRenderer()->getBackingResolutionScaleX();
+    
+    previewImage->setTexture(sprite->getTexture());
+    
+    bottomMenu = new Entity();
+    addChild(bottomMenu);
+    
+    bottomMenu->processInputEvents = true;
+    
+    bottomMenuRect = new UIRect(100, 100);
+	bottomMenu->addChild(bottomMenuRect);
+	bottomMenuRect->setAnchorPoint(-1.0, -1.0, 0.0);
+	bottomMenuRect->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderBgColor"));
+    
+    changeImageButton = new UIButton("Change image", 120);
+    bottomMenu->addChild(changeImageButton);
+    changeImageButton->addEventListener(this, UIEvent::CLICK_EVENT);
+    changeImageButton->setPosition(5.0, 3.0);
+    
+    generateFramesButton = new UIButton("Generate frames", 120);
+    bottomMenu->addChild(generateFramesButton);
+    generateFramesButton->addEventListener(this, UIEvent::CLICK_EVENT);
+    generateFramesButton->setPosition(130.0, 3.0);
+    
+    generateTypeDropdown = new UIComboBox(globalMenu, 120);
+    bottomMenu->addChild(generateTypeDropdown);
+    generateTypeDropdown->setPosition(260, 3.0);
+    
+    generateTypeDropdown->addComboItem("Uniform grid");
+    generateTypeDropdown->addComboItem("Detect islands");
+    
+    generateTypeDropdown->setSelectedIndex(0);
+    
+    uniformGridWidthInput = new UITextInput(false, 30, 12);
+    bottomMenu->addChild(uniformGridWidthInput);
+    uniformGridWidthInput->setPosition(385, 3);
+    uniformGridWidthInput->setText("32");
+    uniformGridWidthInput->setNumberOnly(true);
+
+    uniformGridHeightInput = new UITextInput(false, 30, 12);
+    bottomMenu->addChild(uniformGridHeightInput);
+    uniformGridHeightInput->setPosition(430, 3);
+    uniformGridHeightInput->setText("32");
+    uniformGridHeightInput->setNumberOnly(true);
+    
+    minimumDistanceInput = new UITextInput(false, 30, 12);
+    bottomMenu->addChild(minimumDistanceInput);
+    minimumDistanceInput->setPosition(475, 3);
+    minimumDistanceInput->setText("0");
+    minimumDistanceInput->setNumberOnly(true);
 }
 
-void SpriteAnimationsSheet::Update() {
-	if(removeIndex != -1) {
-		SpriteAnimationEntry *entryProp = (SpriteAnimationEntry*) props[removeIndex];
-		sprite->removeAnimation(entryProp->animation);
-		removeIndex = -1;
-		refreshAnimationEntries();		
-	}
+void SpriteSheetEditor::Update() {
+    Mesh *mesh = frameVisualizerMesh->getMesh();
+
+    mesh->clearMesh();
+    mesh->indexedMesh = true;
+    
+    unsigned int offset = 0;
+    for(int i=0; i < sprite->getNumFrames(); i++){
+        SpriteFrame frame = sprite->getSpriteFrame(i);
+        
+        mesh->addVertex(frame.coordinates.x, -frame.coordinates.y, 0.0, frame.coordinates.x, frame.coordinates.y);
+        mesh->addVertex(frame.coordinates.x+frame.coordinates.w, -frame.coordinates.y, 0.0, frame.coordinates.x+frame.coordinates.w, frame.coordinates.y);
+        mesh->addVertex(frame.coordinates.x+frame.coordinates.w, -frame.coordinates.y - frame.coordinates.h, 0.0, frame.coordinates.x+frame.coordinates.w, frame.coordinates.y + frame.coordinates.h);
+        mesh->addVertex(frame.coordinates.x, -frame.coordinates.y - frame.coordinates.h, 0.0, frame.coordinates.x, frame.coordinates.y + frame.coordinates.h);
+        
+        mesh->addIndexedFace(offset+0,offset+1);
+        mesh->addIndexedFace(offset+1,offset+2);
+        mesh->addIndexedFace(offset+2,offset+3);
+        mesh->addIndexedFace(offset+3,offset+0);
+        
+        offset += 4;
+    }
+    
+    mesh->dirtyArrays();
 }
 
-void SpriteAnimationsSheet::Resize(Number width, Number height) {
-	addAnimationButton->Resize(width - 60, addAnimationButton->getHeight());
-	animHelpLabel->setPosition((width-animHelpLabel->getWidth())/2.0, 0.0);
-	
-	PropSheet::Resize(width, height);
+void SpriteSheetEditor::handleEvent(Event *event) {
+    if(event->getDispatcher() == changeImageButton) {
+        globalFrame->assetBrowser->addEventListener(this, UIEvent::OK_EVENT);
+        std::vector<String> extensions;
+        extensions.push_back("png");
+        globalFrame->showAssetBrowser(extensions);
+    } else if(event->getDispatcher() == generateFramesButton) {
+        sprite->clearFrames();
+        
+        if(generateTypeDropdown->getSelectedIndex() == 0) {
+            Number frameWidth = uniformGridWidthInput->getText().toNumber() / ((Number)sprite->getTexture()->getWidth());
+            Number frameHeight = uniformGridHeightInput->getText().toNumber() / ((Number)sprite->getTexture()->getHeight());
+            sprite->createGridFrames(frameWidth, frameHeight);
+        } else {
+            sprite->createFramesFromIslands(minimumDistanceInput->getText().toInteger());
+        }
+    } else if(event->getDispatcher() == globalFrame->assetBrowser) {
+        String newImagePath = globalFrame->assetBrowser->getSelectedAssetPath();
+        
+        sprite->loadTexture(globalFrame->assetBrowser->getSelectedAssetPath());
+        previewImage->setTexture(sprite->getTexture());
+        
+        globalFrame->assetBrowser->removeAllHandlersForListener(this);
+        globalFrame->hideModal();
+        
+        Resize(getWidth(), getHeight());
+        
+    }
 }
 
-void SpriteAnimationsSheet::handleEvent(Event *event) {
-
-	if(event->getDispatcher() == addAnimationButton) {
-		if(sprite) {
-			sprite->addAnimation("new_animation", "0", 0.1);
-			refreshAnimationEntries();
-		}
-	} else {
-		for(int i=0; i < props.size(); i++) {
-			if(event->getDispatcher() == props[i]) {
-				SpriteAnimationEntry *entryProp = (SpriteAnimationEntry*) props[i];
-				
-				if(event->getEventCode() == Event::CANCEL_EVENT) {
-					removeIndex = i;
-					break;
-				} else if(event->getEventCode() == Event::CHANGE_EVENT) {
-					sprite->playAnimation(entryProp->nameInput->getText(), 0, false);
-				}
-			}
-		}
-	}
-	
-	PropSheet::handleEvent(event);
+SpriteSheetEditor::~SpriteSheetEditor() {
+    
 }
 
-void SpriteAnimationsSheet::setSprite(SceneSprite *sprite) {
-	this->sprite = sprite;
-	refreshAnimationEntries();
-}
-
-void SpriteAnimationsSheet::refreshAnimationEntries() {
-
-	if(!sprite) {
-		return;
-	}
-
-	for(int i=0; i < props.size(); i++) {
-		contents->removeChild(props[i]);
-		props[i]->removeAllHandlersForListener(this);
-		delete props[i];
-	}
-	props.clear();
-	propHeight = 30;
-	
-	for(int i=0; i < sprite->getNumAnimations(); i++) {			
-		SpriteAnimation *animation = sprite->getAnimationAtIndex(i);		
-		SpriteAnimationEntry *newEntry = new SpriteAnimationEntry(animation);
-		newEntry->addEventListener(this, Event::CHANGE_EVENT);
-		newEntry->addEventListener(this, Event::CANCEL_EVENT);
-		addProp(newEntry);
-		propHeight += 30;
-	}
-	
-	addAnimationButton->setPosition(15, propHeight);	
-	propHeight += 70;	
-	
-	if(lastNumProps != sprite->getNumAnimations()) {
-		dispatchEvent(new Event(), Event::COMPLETE_EVENT);
-	}
-	
-	lastNumProps = sprite->getNumAnimations();		
-	Resize(getWidth(), getHeight());	
+void SpriteSheetEditor::Resize(Number width, Number height) {
+    
+    previewBg->Resize(width, height-30.0);
+    previewBg->setImageCoordinates(0, 0, width, height-30);
+    
+    Vector2 screenPosition = getScreenPositionForMainCamera();
+    scissorBox.setRect(screenPosition.x, screenPosition.y, width, height);
+
+    
+    
+    Number imageAspectRatio = ((Number)previewImage->getTexture()->getHeight()) / ((Number)previewImage->getTexture()->getWidth());
+    
+    Number imageWidth = (height-30.0) / imageAspectRatio;
+    Number imageHeight = height-30.0;
+    
+    if(imageWidth > width) {
+        imageWidth = width;
+        imageHeight = width * imageAspectRatio;
+    }
+    
+    previewImage->Resize(imageWidth, imageHeight);
+
+    
+    previewImage->setPosition((width-previewImage->getWidth())/ 2.0, (height-previewImage->getHeight()-30.0)/2.0);
+    
+    frameVisualizerMesh->setPosition(previewImage->getPosition());
+    frameVisualizerMesh->setScale(previewImage->getWidth(), previewImage->getHeight(), 1.0);
+    
+    bottomMenuRect->Resize(width, 30.0);
+    bottomMenu->setPosition(0.0, height-30.0);
+    
+    UIElement::Resize(width, height);
 }
 
 PolycodeSpriteEditor::PolycodeSpriteEditor() : PolycodeEditor(true){
-	headerBg = new UIRect(10,10);
-	addChild(headerBg);
-	headerBg->setAnchorPoint(-1.0, -1.0, 0.0);
-	headerBg->color.setColorHexFromString(CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiHeaderBgColor"));
-	
-	initialLoad = false;
-
-	propList = new PropList("SPRITE EDITOR");
-	addChild(propList);
-	propList->setPosition(0, 0);
-		
-	previewPropSheet = new SpritePreviewSheet();
-	propList->addPropSheet(previewPropSheet);
-
-	PropSheet *baseProps = new PropSheet("IMAGE OPTIONS", "");
-	propList->addPropSheet(baseProps);
-	
-	textureProp = new TextureProp("Base image");
-	baseProps->addProp(textureProp);
-
-	widthProp = new NumberProp("Frame width");
-	widthProp->set(32);
-	baseProps->addProp(widthProp);	
-
-	heightProp = new NumberProp("Frame height");
-	heightProp->set(32);
-	baseProps->addProp(heightProp);	
-	
-	widthProp->addEventListener(this, Event::CHANGE_EVENT);	
-	textureProp->addEventListener(this, Event::CHANGE_EVENT);
-	heightProp->addEventListener(this, Event::CHANGE_EVENT);		
-			
-	baseProps->propHeight = 180;
-	
-	animationsSheet = new SpriteAnimationsSheet();
-	propList->addPropSheet(animationsSheet);	
-			
-	propList->updateProps();
-	
+    mainSizer = new UIVSizer(100, 100, 200, false);
+    addChild(mainSizer);
+    
+    topSizer = new UIHSizer(100, 100, 400, false);
+    mainSizer->addTopChild(topSizer);
+    
+    sprite = new SceneSpriteRewrite("default.png");
+    
+    SpriteFrame frame;
+    frame.coordinates = Polycode::Rectangle(0.1, 0.4, 0.41, 0.2);
+    sprite->addSpriteFrame(frame);
+    
+    frame.coordinates = Polycode::Rectangle(0.7, 0.6, 0.2, 0.3);
+    sprite->addSpriteFrame(frame);
+    
+    spriteSheetEditor = new SpriteSheetEditor(sprite);
+    topSizer->addLeftChild(spriteSheetEditor);
 }
 
 void PolycodeSpriteEditor::handleEvent(Event *event) {
 
-	if(!initialLoad) {	
-		if(event->getDispatcher() == textureProp) {
-			previewSprite->setTexture(textureProp->get());
-			previewSprite->recalculateSpriteDimensions();
-			previewSprite->getTexture()->reloadOnFileModify = true;
-		}
-
-		if(event->getDispatcher() == widthProp) {
-			previewSprite->setSpriteSize(widthProp->get(), heightProp->get());
-			previewSprite->setPrimitiveOptions(ScenePrimitive::TYPE_VPLANE, widthProp->get(), heightProp->get());
-			previewSprite->recalculateSpriteDimensions();		
-		}
-
-		if(event->getDispatcher() == heightProp) {
-			previewSprite->setSpriteSize(widthProp->get(), heightProp->get());
-			previewSprite->setPrimitiveOptions(ScenePrimitive::TYPE_VPLANE, widthProp->get(), heightProp->get());
-			previewSprite->recalculateSpriteDimensions();		
-		}
-	}
 }
 
 PolycodeSpriteEditor::~PolycodeSpriteEditor() {	
-	delete propList;
-	delete headerBg;
-	delete textureProp;
-	delete widthProp;
-	delete heightProp;
-	delete previewSprite;
+
 }
 
 bool PolycodeSpriteEditor::openFile(OSFileEntry filePath) {
-					
-	initialLoad = true;
-		
-	previewSprite = new SceneSprite(filePath.fullPath);
-    previewSprite->setBlendingMode(Renderer::BLEND_MODE_NORMAL);
-	previewSprite->setAnchorPoint(-1.0, -1.0, 0.0);
-	previewSprite->setPosition(400, 80);				
-	previewSprite->getTexture()->reloadOnFileModify = true;	
-	previewPropSheet->setSprite(previewSprite);
-	
-	if(previewSprite->getNumAnimations() > 0) {
-		previewSprite->playAnimation(previewSprite->getAnimationAtIndex(0)->name, 0, false);
-	}
-	
-	animationsSheet->setSprite(previewSprite);
 	
-	widthProp->set(previewSprite->getSpriteSize().x);
-	heightProp->set(previewSprite->getSpriteSize().y);
-		
-	textureProp->set(previewSprite->getTexture());
-				
-	PolycodeEditor::openFile(filePath);
-	
-	initialLoad = false;
-	return true;
+    PolycodeEditor::openFile(filePath);
+    return true;
 }
 
 void PolycodeSpriteEditor::saveFile() {
-	Object saveObject;
-	
-	saveObject.root.name = "sprite";
-	
-	ObjectEntry *image = saveObject.root.addChild("image");
-	image->addChild("frameWidth", widthProp->get());
-	image->addChild("frameHeight", heightProp->get());
-	image->addChild("fileName", previewSprite->getTexture()->getResourcePath());
-	
-	ObjectEntry *animations = saveObject.root.addChild("animations");
-
-	for(int i=0; i < previewSprite->getNumAnimations(); i++) {
-		ObjectEntry *animation = animations->addChild("animation");	
-		SpriteAnimation *anim = previewSprite->getAnimationAtIndex(i);
-		
-		animation->addChild("name", anim->name);
-		animation->addChild("frames", anim->frames);
-		animation->addChild("speed", anim->speed);			
-	}
-	saveObject.saveToXML(filePath);
+
 }
 
 void PolycodeSpriteEditor::Resize(int x, int y) {
-	headerBg->Resize(x, 30);
-	propList->Resize(x, y);
-	propList->updateProps();	
-	PolycodeEditor::Resize(x,y);	
+    mainSizer->Resize(x, y);
+	PolycodeEditor::Resize(x,y);
 }