Files
eepp/src/eepp/maps/mapeditor/uimap.cpp
Martín Lucas Golini 1361f5e002 Testing if i can move to UI float positions without breaking everything.
--HG--
branch : dev-2.1-float
2018-01-29 03:04:40 -03:00

600 lines
14 KiB
C++

#include <eepp/maps/mapeditor/uimap.hpp>
#include <eepp/maps/mapeditor/mapobjectproperties.hpp>
#include <eepp/maps/gameobjectobject.hpp>
#include <eepp/maps/mapobjectlayer.hpp>
#include <eepp/graphics/renderer/renderer.hpp>
#include <eepp/ui/uimanager.hpp>
#include <eepp/ui/uipopupmenu.hpp>
namespace EE { namespace Maps { namespace Private {
UIMap * UIMap::New( UITheme * Theme, TileMap * Map ) {
return eeNew( UIMap, ( Theme, Map ) );
}
UIMap::UIMap( UITheme * Theme, TileMap * Map ) :
UIWindow( SIMPLE_LAYOUT, UIWindowStyleConfig( UI_WIN_NO_BORDER | UI_WIN_FRAME_BUFFER ) ),
mMap( Map ),
mCurLayer( NULL ),
mEditingMode( 0 ),
mEditingObjMode( SELECT_OBJECTS ),
mAddLight( NULL ),
mSelLight( NULL ),
mClampToTile(true),
mObjRECTEditing(false),
mObjPolyEditing(false),
mObjDragging( false ),
mSelObj( NULL ),
mTheme( Theme ),
mSelPointIndex( eeINDEX_NOT_FOUND ),
mSelPoint( false ),
mTileBox( NULL )
{
if ( NULL == Map ) {
mMap = eeNew( TileMap, () );
}
mContainer->setVisible( false )->setEnabled( false );
mMap->setBackColor( Color( 100, 100, 100, 100 ) );
mMap->setGridLinesColor( Color( 150, 150, 150, 150 ) );
mMap->setScale( PixelDensity::getPixelDensity() );
mMap->setDrawCallback( cb::Make0( this, &UIMap::mapDraw ) );
mMap->setViewSize( mRealSize );
mDragButton = EE_BUTTON_MMASK;
setDragEnabled( true );
updateScreenPos();
}
UIMap::~UIMap() {
eeSAFE_DELETE( mMap );
}
Uint32 UIMap::onDrag( const Vector2f& Pos ) {
if ( ( EDITING_OBJECT == mEditingMode && NULL != mSelObj ) ||
( EDITING_LIGHT == mEditingMode && NULL != mSelLight ) ) {
mDragPoint = Pos;
return 0;
}
Vector2f nPos( -( mDragPoint - Pos ) );
Vector2f nPosf( nPos.x, nPos.y );
mMap->move( nPosf );
mDragPoint = Pos;
if ( mUpdateScrollCb.IsSet() ) {
mUpdateScrollCb();
}
return 0;
}
void UIMap::replaceMap( TileMap * newMap ) {
eeSAFE_DELETE( mMap );
mMap = newMap;
updateScreenPos();
}
TileMap * UIMap::Map() const {
return mMap;
}
void UIMap::draw() {
UIWindow::draw();
if ( NULL != mMap ) {
mMap->draw();
}
}
void UIMap::updateScreenPos() {
UIWindow::updateScreenPos();
if ( NULL != mMap ) {
mMap->setPosition( Vector2i( mScreenPos.x, mScreenPos.y ) );
}
}
void UIMap::update( const Time& time ) {
UIWindow::update( time );
if ( NULL != mMap ) {
invalidate();
invalidateDraw();
mMap->update();
if ( mEnabled && mVisible && isMouseOver() ) {
Uint32 Flags = UIManager::instance()->getInput()->getClickTrigger();
if ( EDITING_LIGHT == mEditingMode ) {
if ( NULL != mSelLight ) {
if ( Flags & EE_BUTTONS_WUWD ) {
if ( Flags & EE_BUTTON_WUMASK ) {
mSelLight->setRadius( mSelLight->getRadius() + 10 );
} else if ( Flags & EE_BUTTON_WDMASK ) {
mSelLight->setRadius( mSelLight->getRadius() - 10 );
}
if ( mLightRadiusChangeCb.IsSet() )
mLightRadiusChangeCb( mSelLight );
} else if ( Flags & EE_BUTTON_RMASK ) {
if ( mSelLight == mAddLight ) {
mMap->getLightManager()->removeLight( mAddLight );
eeSAFE_DELETE( mAddLight );
mSelLight = NULL;
} else if ( NULL != mSelLight ) {
if ( mSelLight->getAABB().contains( mMap->getMouseMapPosf() ) ) {
mMap->getLightManager()->removeLight( mSelLight );
eeSAFE_DELETE( mSelLight );
}
}
} else if ( Flags & EE_BUTTON_LMASK ) {
if ( mSelLight == mAddLight ) {
mAddLight = NULL;
} else {
tryToSelectLight();
}
}
Flags = UIManager::instance()->getInput()->getPressTrigger();
if ( Flags & EE_BUTTON_MMASK ) {
mSelLight->setPosition( mMap->getMouseMapPosf() );
}
} else {
if ( Flags & EE_BUTTON_LMASK ) {
tryToSelectLight();
}
}
} else if ( EDITING_OBJECT == mEditingMode ) {
manageObject( Flags );
}
}
}
}
Vector2f UIMap::getMouseMapPos() {
Vector2f mp( mMap->getMouseMapPosf() );
if ( mClampToTile ) {
Vector2i mpc( mMap->getTileCoords( mMap->getMouseTilePos() + 1 ) );
mp = Vector2f( mpc.x, mpc.y );
}
return mp;
}
void UIMap::selectPolyObj() {
if ( NULL != mCurLayer && mCurLayer->getType() == MAP_LAYER_OBJECT ) {
MapObjectLayer * tLayer = reinterpret_cast<MapObjectLayer*>( mCurLayer );
GameObject * tObj = tLayer->getObjectOver( mMap->getMouseMapPos(), MapObjectLayer::SEARCH_POLY );
if ( NULL != tObj ) {
if ( NULL != mSelObj ) {
mSelObj->setSelected( false );
}
mSelObj = reinterpret_cast<GameObjectObject*>( tObj );
mSelObj->setSelected( true );
} else {
if ( NULL != mSelObj ) {
mSelObj->setSelected( false );
mSelObj = NULL;
}
}
} else {
if ( mAlertCb.IsSet() ) {
mAlertCb( "No layer found", "An Object Layer must be selected first." )->setFocus();
}
}
}
void UIMap::selectPolyPoint() {
if ( NULL != mCurLayer && mCurLayer->getType() == MAP_LAYER_OBJECT && NULL != mSelObj ) {
if ( mSelObj->pointInside( mMap->getMouseMapPosf() ) ) {
mSelPointIndex = mSelObj->getPolygon().closestPoint( mMap->getMouseMapPosf() );
setPointRect( mSelObj->getPolygon().getAt( mSelPointIndex ) );
}
}
}
void UIMap::dragPoly( Uint32 Flags, Uint32 PFlags ) {
if ( ( PFlags & EE_BUTTON_MMASK ) && NULL != mSelObj ) {
if ( mSelObj->pointInside( mMap->getMouseMapPosf() ) ) {
if ( !mObjDragging ) {
mObjDragging = true;
mObjDragDist = getMouseMapPos() - mSelObj->getPosition();
}
}
mSelObj->setPosition( getMouseMapPos() - mObjDragDist );
if ( EDIT_POLYGONS == mEditingObjMode ) {
selectPolyPoint();
}
} else if ( Flags & EE_BUTTON_MMASK ) {
if ( mObjDragging ) {
mObjDragging = false;
mObjDragDist = Vector2f(0,0);
}
}
}
void UIMap::manageObject( Uint32 Flags ) {
Uint32 PFlags = UIManager::instance()->getInput()->getPressTrigger();
Uint32 LPFlags = UIManager::instance()->getInput()->getLastPressTrigger();
switch ( mEditingObjMode )
{
case INSERT_OBJECT:
{
if ( PFlags & EE_BUTTON_LMASK ) {
Vector2f mp( getMouseMapPos() );
if ( !mObjRECTEditing ) {
mObjRECTEditing = true;
mObjRECT = Rectf( mp, Sizef(0,0) );
} else {
if ( mObjRECT.getPosition().x < mp.x && mObjRECT.getPosition().y < mp.y ) {
mObjRECT = Rectf( mObjRECT.getPosition(), Sizef( mp - mObjRECT.getPosition() ) );
}
}
}
if ( Flags & EE_BUTTON_LMASK ){
if ( mObjRECTEditing ) {
mAddObjectCallback( GAMEOBJECT_TYPE_OBJECT, Polygon2f( mObjRECT ) );
mObjRECTEditing = false;
}
}
break;
}
case INSERT_POLYLINE:
case INSERT_POLYGON:
{
if ( Flags & EE_BUTTON_LMASK ) {
mObjPoly.pushBack( getMouseMapPos() );
} else if ( Flags & EE_BUTTON_RMASK ) {
mAddObjectCallback( ( INSERT_POLYGON == mEditingObjMode ) ? GAMEOBJECT_TYPE_POLYGON : GAMEOBJECT_TYPE_POLYLINE, mObjPoly );
mObjPoly.clear();
}
break;
}
case SELECT_OBJECTS:
{
if ( ( Flags & EE_BUTTON_LMASK ) ) {
selectPolyObj();
} else {
dragPoly( Flags, PFlags );
}
break;
}
case EDIT_POLYGONS:
{
if ( ( Flags & EE_BUTTON_LMASK ) ) {
if ( !mSelPoint ) {
selectPolyObj();
selectPolyPoint();
} else {
mSelPoint = false;
}
} else if ( !( LPFlags & EE_BUTTON_LMASK ) && ( PFlags & EE_BUTTON_LMASK ) ) {
if ( NULL != mSelObj && eeINDEX_NOT_FOUND != mSelPointIndex && mSelPointRect.contains( mMap->getMouseMapPosf() ) ) {
mSelPoint = true;
}
} else if ( ( PFlags & EE_BUTTON_LMASK ) ) {
if ( mSelPoint && NULL != mSelObj && eeINDEX_NOT_FOUND != mSelPointIndex ) {
mSelObj->setPolygonPoint( mSelPointIndex, getMouseMapPos() );
setPointRect( getMouseMapPos() );
}
} else {
dragPoly( Flags, PFlags );
}
break;
}
default:
{
}
}
}
void UIMap::setPointRect( Vector2f p ) {
mSelPointRect = Rectf( Vector2f( p.x - 10, p.y - 10 ), Sizef( 20, 20 ) );
}
void UIMap::tryToSelectLight() {
MapLight * tLight = mSelLight;
mSelLight = mMap->getLightManager()->getLightOver( mMap->getMouseMapPosf(), mSelLight );
if ( NULL != mSelLight && mSelLight != tLight ) {
if ( mLightSelCb.IsSet() )
mLightSelCb( mSelLight );
}
}
void UIMap::onSizeChange() {
if ( NULL != mMap ) {
mMap->setPosition( Vector2i( mScreenPos.x, mScreenPos.y ) );
mMap->setViewSize( mRealSize );
}
UIWindow::onSizeChange();
}
Uint32 UIMap::onMouseMove( const Vector2i& Pos, const Uint32 Flags ) {
if ( NULL != mMap ) {
if ( EDITING_LIGHT == mEditingMode && NULL != mAddLight ) {
mAddLight->setPosition( mMap->getMouseMapPosf() );
}
}
if ( NULL != mTileBox ) {
Vector2i mp( mMap->getMouseTilePos() );
if ( mLastMouseTilePos != mp ) {
mLastMouseTilePos = mp;
mTileBox->setText( String::toStr( mp.x ) + "," + String::toStr( mp.y ) );
}
}
return UIWindow::onMouseMove( Pos, Flags );
}
void UIMap::addLight( MapLight * Light ) {
if ( NULL != mMap->getLightManager() ) {
if ( NULL != mAddLight ) {
mMap->getLightManager()->removeLight( mAddLight );
eeSAFE_DELETE( mAddLight );
}
mAddLight = Light;
mSelLight = Light;
mMap->getLightManager()->addLight( Light );
if ( mLightSelCb.IsSet() )
mLightSelCb( mSelLight );
}
}
void UIMap::mapDraw() {
if ( EDITING_LIGHT == mEditingMode ) {
if ( NULL != mSelLight ) {
mP.setColor( Color( 255, 0, 0, (Uint8)mAlpha ) );
Vector2f Pos( mSelLight->getAABB().Left, mSelLight->getAABB().Top );
Rectf AB( mSelLight->getAABB() );
mP.setFillMode( DRAW_LINE );
mP.drawRectangle( Rectf( Pos, AB.getSize() ) );
}
} else if ( EDITING_OBJECT == mEditingMode ) {
switch ( mEditingObjMode ) {
case INSERT_OBJECT:
{
if ( mObjRECTEditing ) {
mP.setFillMode( DRAW_FILL );
mP.setColor( Color( 100, 100, 100, 20 ) );
mP.drawRectangle( mObjRECT );
mP.setFillMode( DRAW_LINE );
mP.setColor( Color( 255, 0, 0, 200 ) );
mP.drawRectangle( mObjRECT );
}
break;
}
case INSERT_POLYGON:
{
mP.setFillMode( DRAW_FILL );
mP.setColor( Color( 50, 50, 50, 50 ) );
mP.drawPolygon( mObjPoly );
mP.setFillMode( DRAW_LINE );
mP.setColor( Color( 255, 0, 0, 200 ) );
mP.drawPolygon( mObjPoly );
Polygon2f polyN( mObjPoly );
polyN.pushBack( getMouseMapPos() );
mP.setFillMode( DRAW_FILL );
mP.setColor( Color( 100, 100, 100, 100 ) );
mP.drawPolygon( polyN );
mP.setFillMode( DRAW_LINE );
mP.setColor( Color( 255, 255, 0, 200 ) );
mP.drawPolygon( polyN );
break;
}
case INSERT_POLYLINE:
{
mP.setFillMode( DRAW_LINE );
mP.setColor( Color( 255, 0, 0, 200 ) );
mP.drawPolygon( mObjPoly );
Polygon2f polyN( mObjPoly );
polyN.pushBack( getMouseMapPos() );
mP.setFillMode( DRAW_LINE );
mP.setColor( Color( 255, 255, 0, 200 ) );
mP.drawPolygon( polyN );
break;
}
case EDIT_POLYGONS:
{
if ( NULL != mSelObj && eeINDEX_NOT_FOUND != mSelPointIndex ) {
mP.setColor( Color( 255, 255, 100, 100 ) );
mP.setFillMode( DRAW_FILL );
mP.drawRectangle( mSelPointRect );
mP.setFillMode( DRAW_LINE );
mP.drawRectangle( mSelPointRect );
}
break;
}
}
}
}
void UIMap::setEditingLights( const bool& editing ) {
mEditingMode = ( editing ) ? EDITING_LIGHT : 0;
if ( editing && NULL != mMap->getLightManager() && NULL != mAddLight ) {
mMap->getLightManager()->removeLight( mAddLight );
mAddLight = NULL;
}
}
bool UIMap::isEditingLights() {
return EDITING_LIGHT == mEditingMode;
}
void UIMap::setEditingObjects( const bool& editing ) {
mEditingMode = ( editing ) ? EDITING_OBJECT : 0;
}
bool UIMap::isEditingObjects() {
return EDITING_OBJECT == mEditingMode;
}
void UIMap::editingDisable() {
mEditingMode = 0;
}
MapLight * UIMap::getSelectedLight() {
return mSelLight;
}
MapLight * UIMap::getAddLight() {
return mAddLight;
}
void UIMap::setLightSelectCb( LightSelectCb Cb ) {
mLightSelCb = Cb;
}
void UIMap::setLightRadiusChangeCb( LightRadiusChangeCb Cb ) {
mLightRadiusChangeCb = Cb;
}
void UIMap::setAddObjectCallback( ObjAddCb Cb ) {
mAddObjectCallback = Cb;
}
void UIMap::clearLights() {
mSelLight = NULL;
mAddLight = NULL;
}
void UIMap::onAlphaChange() {
UIWindow::onAlphaChange();
if ( NULL != mMap ) {
mMap->setBackAlpha( (Uint8)mAlpha );
}
}
void UIMap::setClampToTile( const bool& clamp ) {
mClampToTile = clamp;
}
const bool& UIMap::getClampToTile() const {
return mClampToTile;
}
void UIMap::setEditingObjMode( EDITING_OBJ_MODE mode ) {
mObjPoly.clear();
mSelPointIndex = eeINDEX_NOT_FOUND;
mEditingObjMode = mode;
}
void UIMap::setCurLayer( MapLayer * layer ) {
mCurLayer = layer;
}
void UIMap::setAlertCb( AlertCb Cb ) {
mAlertCb = Cb;
}
void UIMap::setUpdateScrollCb( UpdateScrollCb Cb ) {
mUpdateScrollCb = Cb;
}
Uint32 UIMap::onMessage( const UIMessage * Msg ) {
if ( Msg->getMsg() == UIMessage::Click && Msg->getSender() == this && ( Msg->getFlags() & EE_BUTTON_RMASK ) ) {
if ( SELECT_OBJECTS == mEditingObjMode && NULL != mSelObj && mSelObj->pointInside( mMap->getMouseMapPosf() ) ) {
createObjPopUpMenu();
}
}
return 0;
}
void UIMap::objItemClick( const UIEvent * Event ) {
if ( !Event->getControl()->isType( UI_TYPE_MENUITEM ) )
return;
if ( NULL != mSelObj && NULL != mCurLayer && mCurLayer->getType() == MAP_LAYER_OBJECT && mSelObj->getLayer() == mCurLayer ) {
const String& txt = reinterpret_cast<UIMenuItem*> ( Event->getControl() )->getText();
MapObjectLayer * tLayer = reinterpret_cast<MapObjectLayer*>( mCurLayer );
if ( "Duplicate Object" == txt ) {
tLayer->addGameObject( mSelObj->clone() );
} else if ( "Remove Object" == txt ) {
tLayer->removeGameObject( mSelObj );
mSelObj->setSelected( false );
mSelObj = NULL;
} else if ( "Object Properties..." == txt ) {
eeNew( MapObjectProperties, ( mSelObj ) );
}
}
}
void UIMap::createObjPopUpMenu() {
UIPopUpMenu * Menu = UIPopUpMenu::New();
Menu->add( "Duplicate Object" );
Menu->add( "Remove Object" );
Menu->addSeparator();
Menu->add( "Object Properties..." );
Menu->addEventListener( UIEvent::OnItemClicked, cb::Make1( this, &UIMap::objItemClick ) );
if ( Menu->show() ) {
Vector2f Pos = UIManager::instance()->getInput()->getMousePosf();
UIMenu::fixMenuPos( Pos , Menu );
Pos = PixelDensity::pxToDp( Pos );
Menu->setPosition( Pos );
}
}
void UIMap::setTileBox( UITextView * tilebox ) {
mTileBox = tilebox;
}
}}}