mirror of
https://github.com/Heretek-AI/GDevelop.git
synced 2026-07-23 18:45:48 -04:00
196 lines
7.7 KiB
C++
196 lines
7.7 KiB
C++
/**
|
|
|
|
Game Develop - Tile Map Extension
|
|
Copyright (c) 2014 Victor Levasseur (victorlevasseur52@gmail.com)
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
warranty. In no event will the authors be held liable for any damages
|
|
arising from the use of this software.
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it
|
|
freely, subject to the following restrictions:
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
claim that you wrote the original software. If you use this software
|
|
in a product, an acknowledgment in the product documentation would be
|
|
appreciated but is not required.
|
|
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
misrepresented as being the original software.
|
|
|
|
3. This notice may not be removed or altered from any source
|
|
distribution.
|
|
|
|
*/
|
|
|
|
#include "TileEditor.h"
|
|
|
|
#include <algorithm>
|
|
#include <wx/dcbuffer.h>
|
|
#include <wx/event.h>
|
|
#include "GDCore/IDE/CommonBitmapManager.h"
|
|
|
|
TileEditor::TileEditor(wxWindow* parent) :
|
|
TileEditorBase(parent),
|
|
m_tileset(NULL),
|
|
m_currentTile(0),
|
|
m_predefinedShapesMenu(new wxMenu())
|
|
{
|
|
m_tilePreviewPanel->SetBackgroundStyle(wxBG_STYLE_PAINT);
|
|
UpdateScrollbars();
|
|
|
|
//Create the predefined shape menu
|
|
m_predefinedShapesMenu->Append(RECTANGLE_SHAPE_TOOL_ID, _("Rectangle Shape"));
|
|
m_predefinedShapesMenu->AppendSeparator();
|
|
m_predefinedShapesMenu->Append(TRIANGLE_TL_SHAPE_TOOL_ID, _("Triangle Shape (top-left)"));
|
|
m_predefinedShapesMenu->Append(TRIANGLE_TR_SHAPE_TOOL_ID, _("Triangle Shape (top-right)"));
|
|
m_predefinedShapesMenu->Append(TRIANGLE_BR_SHAPE_TOOL_ID, _("Triangle Shape (bottom-right)"));
|
|
m_predefinedShapesMenu->Append(TRIANGLE_BL_SHAPE_TOOL_ID, _("Triangle Shape (bottom-left)"));
|
|
m_predefinedShapesMenu->AppendSeparator();
|
|
m_predefinedShapesMenu->Append(SEMIRECT_T_SHAPE_TOOL_ID, _("Half-rectangle (top)"));
|
|
m_predefinedShapesMenu->Append(SEMIRECT_R_SHAPE_TOOL_ID, _("Half-rectangle (right)"));
|
|
m_predefinedShapesMenu->Append(SEMIRECT_B_SHAPE_TOOL_ID, _("Half-rectangle (bottom)"));
|
|
m_predefinedShapesMenu->Append(SEMIRECT_L_SHAPE_TOOL_ID, _("Half-rectangle (left)"));
|
|
|
|
Connect(RECTANGLE_SHAPE_TOOL_ID, SEMIRECT_L_SHAPE_TOOL_ID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TileEditor::OnPredefinedShapeMenuItemClicked), NULL, this);
|
|
}
|
|
|
|
TileEditor::~TileEditor()
|
|
{
|
|
}
|
|
|
|
void TileEditor::SetTileSet(TileSet *tileset)
|
|
{
|
|
m_tileset = tileset;
|
|
UpdateScrollbars();
|
|
m_tilePreviewPanel->Refresh();
|
|
|
|
//Update the tools according to the selected tile
|
|
TileSelectionEvent event(TILE_SELECTION_CHANGED, -1, m_currentTile);
|
|
OnTileSetSelectionChanged(event);
|
|
}
|
|
|
|
void TileEditor::OnTileSetSelectionChanged(TileSelectionEvent &event)
|
|
{
|
|
if(!m_tileset || m_tileset->IsDirty())
|
|
return;
|
|
|
|
m_currentTile = event.GetSelectedTile();
|
|
m_mainToolbar->ToggleTool(COLLIDABLE_TOOL_ID, m_tileset->GetTileHitbox(m_currentTile).collidable);
|
|
UpdateScrollbars();
|
|
m_tilePreviewPanel->Refresh();
|
|
}
|
|
|
|
void TileEditor::OnPreviewErase(wxEraseEvent& event)
|
|
{
|
|
|
|
}
|
|
|
|
void TileEditor::UpdateScrollbars()
|
|
{
|
|
if(!m_tileset || m_tileset->IsDirty()) //If no tileset, stop rendering here
|
|
return;
|
|
|
|
//Compute the virtual size and the default scroll position to have a centered tile.
|
|
wxBitmap tileBitmap = m_tileset->GetTileBitmap(m_currentTile);
|
|
|
|
int virtualWidth = std::max(m_tilePreviewPanel->GetClientSize().GetWidth(), tileBitmap.GetWidth());
|
|
int virtualHeight = std::max(m_tilePreviewPanel->GetClientSize().GetHeight(), tileBitmap.GetHeight());
|
|
|
|
m_tilePreviewPanel->SetVirtualSize(virtualWidth, virtualHeight);
|
|
|
|
m_tilePreviewPanel->Scroll(virtualWidth/2 - m_tilePreviewPanel->GetClientSize().GetWidth()/2,
|
|
virtualHeight/2 - m_tilePreviewPanel->GetClientSize().GetHeight()/2);
|
|
}
|
|
|
|
void TileEditor::OnPreviewPaint(wxPaintEvent& event)
|
|
{
|
|
//Prepare the render
|
|
wxAutoBufferedPaintDC dc(m_tilePreviewPanel);
|
|
m_tilePreviewPanel->DoPrepareDC(dc);
|
|
|
|
wxPoint minPos = m_tilePreviewPanel->GetViewStart();
|
|
int width, height;
|
|
m_tilePreviewPanel->GetVirtualSize(&width, &height);
|
|
wxPoint maxPos = minPos + wxPoint(width, height);
|
|
|
|
//Draw the background
|
|
dc.SetBrush(gd::CommonBitmapManager::Get()->transparentBg);
|
|
dc.DrawRectangle(minPos.x, minPos.y, width, height);
|
|
|
|
if(!m_tileset || m_tileset->IsDirty()) //If no tileset, stop rendering here
|
|
return;
|
|
|
|
//Draw the tile
|
|
wxBitmap tileBitmap = m_tileset->GetTileBitmap(m_currentTile);
|
|
dc.DrawBitmap(tileBitmap, width/2 - tileBitmap.GetWidth()/2, height/2 - tileBitmap.GetHeight()/2);
|
|
|
|
//Draw the hitbox
|
|
dc.SetBrush(wxBrush(wxColour(128,128,128), wxBRUSHSTYLE_FDIAGONAL_HATCH));
|
|
dc.SetPen(wxPen(wxColour(100,100,100)));
|
|
|
|
wxPointList list;
|
|
for (unsigned int i = 0; i < m_tileset->GetTileHitbox(m_currentTile).hitbox.vertices.size();++i)
|
|
{
|
|
list.push_back(new wxPoint(m_tileset->GetTileHitbox(m_currentTile).hitbox.vertices[i].x,
|
|
m_tileset->GetTileHitbox(m_currentTile).hitbox.vertices[i].y));
|
|
}
|
|
|
|
dc.DrawPolygon(&list, width/2 - tileBitmap.GetWidth()/2, height/2 - tileBitmap.GetHeight()/2);
|
|
}
|
|
|
|
void TileEditor::OnCollidableToolToggled(wxCommandEvent& event)
|
|
{
|
|
m_tileset->GetTileHitbox(m_currentTile).collidable = event.IsChecked();
|
|
}
|
|
|
|
void TileEditor::OnPredefinedShapeToolClicked(wxCommandEvent& event)
|
|
{
|
|
PopupMenu(m_predefinedShapesMenu);
|
|
}
|
|
|
|
void TileEditor::OnPredefinedShapeMenuItemClicked(wxCommandEvent& event)
|
|
{
|
|
if(!m_tileset || m_tileset->IsDirty())
|
|
return;
|
|
|
|
//Set the predefined shapes as hitbox
|
|
switch(event.GetId())
|
|
{
|
|
case RECTANGLE_SHAPE_TOOL_ID:
|
|
m_tileset->GetTileHitbox(m_currentTile) = TileHitbox::Rectangle(m_tileset->tileSize);
|
|
break;
|
|
case TRIANGLE_TL_SHAPE_TOOL_ID:
|
|
m_tileset->GetTileHitbox(m_currentTile) = TileHitbox::Triangle(m_tileset->tileSize, TileHitbox::TopLeft);
|
|
break;
|
|
case TRIANGLE_TR_SHAPE_TOOL_ID:
|
|
m_tileset->GetTileHitbox(m_currentTile) = TileHitbox::Triangle(m_tileset->tileSize, TileHitbox::TopRight);
|
|
break;
|
|
case TRIANGLE_BR_SHAPE_TOOL_ID:
|
|
m_tileset->GetTileHitbox(m_currentTile) = TileHitbox::Triangle(m_tileset->tileSize, TileHitbox::BottomRight);
|
|
break;
|
|
case TRIANGLE_BL_SHAPE_TOOL_ID:
|
|
m_tileset->GetTileHitbox(m_currentTile) = TileHitbox::Triangle(m_tileset->tileSize, TileHitbox::BottomLeft);
|
|
break;
|
|
case SEMIRECT_T_SHAPE_TOOL_ID:
|
|
m_tileset->GetTileHitbox(m_currentTile) = TileHitbox::Rectangle(sf::Vector2f(m_tileset->tileSize.x, m_tileset->tileSize.y/2.f));
|
|
break;
|
|
case SEMIRECT_R_SHAPE_TOOL_ID:
|
|
m_tileset->GetTileHitbox(m_currentTile) = TileHitbox::Rectangle(sf::Vector2f(m_tileset->tileSize.x/2.f, m_tileset->tileSize.y));
|
|
m_tileset->GetTileHitbox(m_currentTile).hitbox.Move(m_tileset->tileSize.x/2.f, 0);
|
|
break;
|
|
case SEMIRECT_B_SHAPE_TOOL_ID:
|
|
m_tileset->GetTileHitbox(m_currentTile) = TileHitbox::Rectangle(sf::Vector2f(m_tileset->tileSize.x, m_tileset->tileSize.y/2.f));
|
|
m_tileset->GetTileHitbox(m_currentTile).hitbox.Move(0, m_tileset->tileSize.y/2.f);
|
|
break;
|
|
case SEMIRECT_L_SHAPE_TOOL_ID:
|
|
m_tileset->GetTileHitbox(m_currentTile) = TileHitbox::Rectangle(sf::Vector2f(m_tileset->tileSize.x/2.f, m_tileset->tileSize.y));
|
|
break;
|
|
}
|
|
|
|
//Update the tools according to the properties' changes
|
|
TileSelectionEvent tileEvent(TILE_SELECTION_CHANGED, -1, m_currentTile);
|
|
OnTileSetSelectionChanged(tileEvent);
|
|
}
|