mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
383 lines
12 KiB
C++
383 lines
12 KiB
C++
/*
|
|
* GDevelop Core
|
|
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
|
|
* Copyright 2014-2016 Victor Levasseur (victorlevasseur52@gmail.com).
|
|
* This project is released under the MIT License.
|
|
*/
|
|
|
|
#include "LayersEditorPanel.h"
|
|
|
|
#include <wx/config.h>
|
|
#include "GDCore/Tools/Log.h"
|
|
#include "GDCore/CommonTools.h"
|
|
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/LayoutEditorCanvas.h"
|
|
#include "GDCore/Project/InitialInstancesContainer.h"
|
|
#include "GDCore/Project/Project.h"
|
|
#include "GDCore/Project/Layout.h"
|
|
#include "GDCore/Project/Layer.h"
|
|
#include "GDCore/Tools/HelpFileAccess.h"
|
|
#include "GDCore/IDE/Dialogs/ObjectsOnBadLayerDialog.h"
|
|
#include "GDCore/IDE/wxTools/SkinHelper.h"
|
|
#include "LayoutEditorPropertiesPnl.h"
|
|
|
|
const long LayersEditorPanel::idMenuEdit = wxNewId();
|
|
const long LayersEditorPanel::idMenuAdd = wxNewId();
|
|
const long LayersEditorPanel::idMenuDel = wxNewId();
|
|
const long LayersEditorPanel::idMenuUp = wxNewId();
|
|
const long LayersEditorPanel::idMenuDown = wxNewId();
|
|
|
|
using namespace gd;
|
|
|
|
LayersEditorPanel::LayersEditorPanel(wxWindow* parent, gd::Project & project, gd::Layout & layout, gd::MainFrameWrapper & mainFrameWrapper) :
|
|
LayersEditorPanelBase(parent),
|
|
gd::LayoutEditorCanvasAssociatedEditor(),
|
|
m_imageList(new wxImageList(16, 16, 1)),
|
|
m_project(project),
|
|
m_layout(layout),
|
|
m_layoutCanvas(NULL),
|
|
m_mainFrameWrapper(mainFrameWrapper),
|
|
propPnl(NULL),
|
|
propPnlManager(NULL)
|
|
{
|
|
//Connect the wxListCtrl to events
|
|
Connect(LayersEditorPanelBase::LAYERS_LIST_ID,wxEVT_COMMAND_LIST_ITEM_SELECTED,(wxObjectEventFunction)&LayersEditorPanel::OnlayersListItemSelect1);
|
|
Connect(LayersEditorPanelBase::LAYERS_LIST_ID,wxEVT_COMMAND_LIST_ITEM_ACTIVATED,(wxObjectEventFunction)&LayersEditorPanel::OnlayersListItemActivated);
|
|
Connect(LayersEditorPanelBase::LAYERS_LIST_ID,wxEVT_COMMAND_LIST_ITEM_FOCUSED,(wxObjectEventFunction)&LayersEditorPanel::OnlayersListItemFocused);
|
|
Connect(LayersEditorPanelBase::LAYERS_LIST_ID,wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK,(wxObjectEventFunction)&LayersEditorPanel::OnlayersListItemRClick);
|
|
|
|
//Create the context menu
|
|
MenuItem1 = new wxMenuItem((&contextMenu), idMenuEdit, _("Edit the layer properties"), wxEmptyString, wxITEM_NORMAL);
|
|
MenuItem1->SetBitmap(gd::SkinHelper::GetIcon("rename", 16));
|
|
contextMenu.Append(MenuItem1);
|
|
contextMenu.AppendSeparator();
|
|
MenuItem2 = new wxMenuItem((&contextMenu), idMenuAdd, _("Add a layer"), wxEmptyString, wxITEM_NORMAL);
|
|
MenuItem2->SetBitmap(gd::SkinHelper::GetIcon("add", 16));
|
|
contextMenu.Append(MenuItem2);
|
|
MenuItem3 = new wxMenuItem((&contextMenu), idMenuDel, _("Delete the layer"), wxEmptyString, wxITEM_NORMAL);
|
|
MenuItem3->SetBitmap(gd::SkinHelper::GetIcon("delete", 16));
|
|
contextMenu.Append(MenuItem3);
|
|
contextMenu.AppendSeparator();
|
|
MenuItem4 = new wxMenuItem((&contextMenu), idMenuUp, _("Move over"), wxEmptyString, wxITEM_NORMAL);
|
|
MenuItem4->SetBitmap(gd::SkinHelper::GetIcon("up", 16));
|
|
contextMenu.Append(MenuItem4);
|
|
MenuItem5 = new wxMenuItem((&contextMenu), idMenuDown, _("Move below"), wxEmptyString, wxITEM_NORMAL);
|
|
MenuItem5->SetBitmap(gd::SkinHelper::GetIcon("down", 16));
|
|
contextMenu.Append(MenuItem5);
|
|
|
|
//Connect menu's events
|
|
Connect(idMenuEdit,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&LayersEditorPanel::OnEditSelected1);
|
|
Connect(idMenuAdd,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&LayersEditorPanel::OnAddLayerClicked);
|
|
Connect(idMenuDel,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&LayersEditorPanel::OnDeleteLayerClicked);
|
|
Connect(idMenuUp,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&LayersEditorPanel::OnLayerUpClicked);
|
|
Connect(idMenuDown,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&LayersEditorPanel::OnLayerDownClicked);
|
|
|
|
//Add images to the image list
|
|
m_imageList->Add(wxBitmap("res/rightArrowGrey.png", wxBITMAP_TYPE_ANY));
|
|
m_imageList->Add(wxBitmap("res/1rightarrow.png", wxBITMAP_TYPE_ANY));
|
|
m_imageList->Add(wxBitmap("res/eye.png", wxBITMAP_TYPE_ANY));
|
|
m_imageList->Add(wxBitmap("res/eyeGrey.png", wxBITMAP_TYPE_ANY));
|
|
m_layersList->AssignImageList(m_imageList, wxIMAGE_LIST_SMALL);
|
|
|
|
m_layersList->InsertColumn(1, _("Layer"));
|
|
m_layersList->InsertColumn(2, _("Visible"));
|
|
|
|
gd::SkinHelper::ApplyCurrentSkin(*m_toolbar);
|
|
m_toolbar->Realize(); //Force m_toolbar update to get a good size
|
|
|
|
Refresh();
|
|
}
|
|
|
|
LayersEditorPanel::~LayersEditorPanel()
|
|
{
|
|
|
|
}
|
|
|
|
void LayersEditorPanel::SetAssociatedPropertiesPanel(LayoutEditorPropertiesPnl * propPnl_, wxAuiManager * manager_)
|
|
{
|
|
propPnl = propPnl_;
|
|
propPnlManager = manager_;
|
|
}
|
|
|
|
void LayersEditorPanel::Refresh()
|
|
{
|
|
m_layersList->DeleteAllItems();
|
|
|
|
for (std::size_t i = 0; i < m_layout.GetLayersCount(); ++i)
|
|
{
|
|
gd::String name = m_layout.GetLayer(i).GetName();
|
|
if ( name == "" ) name = _("Base layer");
|
|
m_layersList->InsertItem(0, name);
|
|
|
|
if ( m_layout.GetLayer(i).GetVisibility() )
|
|
m_layersList->SetItemColumnImage(0, 1, 2);
|
|
else
|
|
m_layersList->SetItemColumnImage(0, 1, 3);
|
|
|
|
m_layersList->SetItemImage(0,-1,0);
|
|
}
|
|
m_layersList->SetColumnWidth( 0, wxLIST_AUTOSIZE );
|
|
m_layersList->SetColumnWidth( 1, wxLIST_AUTOSIZE );
|
|
|
|
UpdateSelectedLayerIcon();
|
|
}
|
|
|
|
void LayersEditorPanel::UpdateSelectedLayerIcon()
|
|
{
|
|
if ( !m_layoutCanvas )
|
|
return;
|
|
|
|
for (std::size_t i = 0; i<m_layout.GetLayersCount(); ++i)
|
|
{
|
|
if ( m_layout.GetLayer(i).GetName() == m_layoutCanvas->GetCurrentLayer() )
|
|
m_layersList->SetItemImage(m_layout.GetLayersCount()-i-1,1,1);
|
|
else
|
|
m_layersList->SetItemImage(m_layout.GetLayersCount()-i-1,-1,-1);
|
|
}
|
|
}
|
|
|
|
Layer* LayersEditorPanel::GetSelectedLayer()
|
|
{
|
|
long itemIndex = -1;
|
|
|
|
for (;;)
|
|
{
|
|
itemIndex = m_layersList->GetNextItem(itemIndex,wxLIST_NEXT_ALL,wxLIST_STATE_SELECTED);
|
|
if (itemIndex == -1) break;
|
|
|
|
// Got the selected item index
|
|
std::size_t layerId = m_layout.GetLayersCount()-itemIndex-1;
|
|
if ( layerId < m_layout.GetLayersCount() )
|
|
{
|
|
return &m_layout.GetLayer(layerId);
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void LayersEditorPanel::EditSelectedLayer()
|
|
{
|
|
gd::Layer * layer = GetSelectedLayer();
|
|
if ( !layer ) return;
|
|
|
|
if ( propPnl && propPnlManager ) {
|
|
propPnlManager->GetPane("PROPERTIES").Show();
|
|
propPnlManager->Update();
|
|
}
|
|
}
|
|
|
|
/** Item double clicked: Toggle visibility or edit the layer
|
|
*/
|
|
void LayersEditorPanel::OnlayersListItemActivated(wxListEvent& event)
|
|
{
|
|
//Get selected layer
|
|
Layer * selectedLayer = GetSelectedLayer();
|
|
if ( !selectedLayer ) return;
|
|
|
|
//Get selected column
|
|
wxPoint click_point = ::wxGetMousePosition();
|
|
wxPoint list_point = m_layersList->GetScreenPosition();
|
|
|
|
// delta x
|
|
int dx = click_point.x - list_point.x;
|
|
|
|
// work out the column
|
|
int ex = 0; // cumulative sum of column widths
|
|
int column = -1;
|
|
for (column = 0; column < m_layersList->GetColumnCount(); column++) {
|
|
ex += m_layersList->GetColumnWidth(column);
|
|
if (ex > dx) break;
|
|
}
|
|
|
|
if ( column == 1 )
|
|
{
|
|
selectedLayer->SetVisibility(!selectedLayer->GetVisibility());
|
|
Refresh();
|
|
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
EditSelectedLayer();
|
|
}
|
|
}
|
|
|
|
void LayersEditorPanel::OnEditSelected1(wxCommandEvent& event)
|
|
{
|
|
EditSelectedLayer();
|
|
}
|
|
|
|
/** Item selected: Update the current layer
|
|
*/
|
|
void LayersEditorPanel::OnlayersListItemSelect1(wxListEvent& event)
|
|
{
|
|
//Get selected layer
|
|
Layer * layer = GetSelectedLayer();
|
|
if ( !layer ) return;
|
|
|
|
if ( propPnl ) propPnl->SelectedLayer(layer);
|
|
|
|
if ( m_layoutCanvas ) m_layoutCanvas->SetCurrentLayer(layer->GetName());
|
|
UpdateSelectedLayerIcon();
|
|
}
|
|
|
|
/** Item focused: Update the current layer
|
|
*/
|
|
void LayersEditorPanel::OnlayersListItemFocused(wxListEvent& event)
|
|
{
|
|
//Get selected layer
|
|
Layer * layer = GetSelectedLayer();
|
|
if ( !layer ) return;
|
|
|
|
if ( propPnl ) propPnl->SelectedLayer(layer);
|
|
|
|
if ( m_layoutCanvas ) m_layoutCanvas->SetCurrentLayer(layer->GetName());
|
|
UpdateSelectedLayerIcon();
|
|
}
|
|
|
|
void LayersEditorPanel::OnlayersListItemRClick(wxListEvent& event)
|
|
{
|
|
PopupMenu(&contextMenu);
|
|
}
|
|
|
|
void LayersEditorPanel::OnAddLayerClicked(wxCommandEvent& event)
|
|
{
|
|
gd::String name = _("New layer");
|
|
|
|
bool alreadyExist = false;
|
|
unsigned int nb = 0;
|
|
for (std::size_t i = 0;i<m_layout.GetLayersCount();++i)
|
|
{
|
|
if ( m_layout.GetLayer(i).GetName() == name )
|
|
alreadyExist = true;
|
|
}
|
|
while ( alreadyExist )
|
|
{
|
|
++nb;
|
|
name = _("New layer ") + gd::String::From(nb);
|
|
|
|
alreadyExist = false;
|
|
for (std::size_t i = 0;i<m_layout.GetLayersCount();++i)
|
|
{
|
|
if ( m_layout.GetLayer(i).GetName() == name )
|
|
alreadyExist = true;
|
|
}
|
|
}
|
|
|
|
m_layout.InsertNewLayer(name, m_layout.GetLayersCount()-1);
|
|
m_layout.GetLayer(name).SetCameraCount(1);
|
|
|
|
if (onChangeCb) onChangeCb("layer-added");
|
|
Refresh();
|
|
}
|
|
|
|
void LayersEditorPanel::OnDeleteLayerClicked(wxCommandEvent& event)
|
|
{
|
|
//Get selected layer
|
|
Layer * selectedLayer = GetSelectedLayer();
|
|
if ( !selectedLayer || selectedLayer->GetName().empty() ) return;
|
|
|
|
gd::String name = selectedLayer->GetName();
|
|
|
|
for (std::size_t i = 0;i<m_layout.GetLayersCount();++i)
|
|
{
|
|
if ( &m_layout.GetLayer(i) == selectedLayer )
|
|
{
|
|
//Ask the user what he wants to do with the existing instances.
|
|
if ( m_layout.GetInitialInstances().SomeInstancesAreOnLayer(name) )
|
|
{
|
|
std::vector<gd::String> availableLayers;
|
|
for (std::size_t j = 0;j<m_layout.GetLayersCount();++j)
|
|
{
|
|
if (i!=j) availableLayers.push_back(m_layout.GetLayer(j).GetName());
|
|
}
|
|
|
|
ObjectsOnBadLayerDialog dialog(this, availableLayers);
|
|
int choice = dialog.ShowModal();
|
|
|
|
if ( choice == 0 ) return; //Cancel
|
|
else if ( choice == 1 )
|
|
m_layout.GetInitialInstances().RemoveAllInstancesOnLayer(name);
|
|
else if ( choice == 2 )
|
|
m_layout.GetInitialInstances().MoveInstancesToLayer(name, dialog.moveOnLayerNamed);
|
|
}
|
|
|
|
//Delete the layer and select base layer
|
|
m_layout.RemoveLayer(name);
|
|
if ( m_layoutCanvas ) m_layoutCanvas->SetCurrentLayer("");
|
|
if ( propPnl ) propPnl->SelectedLayer(NULL);
|
|
if (onChangeCb) onChangeCb("layer-deleted");
|
|
Refresh();
|
|
return;
|
|
}
|
|
}
|
|
gd::LogWarning(_("Can't find the layer to delete !"));
|
|
}
|
|
|
|
void LayersEditorPanel::OnEditLayerClicked(wxCommandEvent& event)
|
|
{
|
|
EditSelectedLayer();
|
|
}
|
|
|
|
void LayersEditorPanel::OnHelpClicked(wxCommandEvent& event)
|
|
{
|
|
gd::HelpFileAccess::Get()->OpenPage("game_develop/documentation/manual/editors/scene_editor/edit_layer");
|
|
}
|
|
|
|
void LayersEditorPanel::OnLayerDownClicked(wxCommandEvent& event)
|
|
{
|
|
//Get selected layer
|
|
Layer * selectedLayer = GetSelectedLayer();
|
|
if ( !selectedLayer ) return;
|
|
|
|
for (std::size_t i = 0;i<m_layout.GetLayersCount();++i)
|
|
{
|
|
if ( &m_layout.GetLayer(i) == selectedLayer )
|
|
{
|
|
if ( i >= 1 )
|
|
{
|
|
//Move the layer
|
|
m_layout.SwapLayers(i,i-1);
|
|
if (onChangeCb) onChangeCb("layer-moved-down");
|
|
Refresh();
|
|
|
|
//Focus it again
|
|
m_layersList->SetItemState(m_layout.GetLayersCount()-i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
gd::LogWarning(_("Can't find the layer to move !"));
|
|
}
|
|
|
|
void LayersEditorPanel::OnLayerUpClicked(wxCommandEvent& event)
|
|
{
|
|
//Get selected layer
|
|
Layer * selectedLayer = GetSelectedLayer();
|
|
if ( !selectedLayer ) return;
|
|
|
|
for (std::size_t i = 0;i<m_layout.GetLayersCount();++i)
|
|
{
|
|
if ( &m_layout.GetLayer(i) == selectedLayer )
|
|
{
|
|
if ( i <= m_layout.GetLayersCount()-1-1 )
|
|
{
|
|
//Move the layer
|
|
m_layout.SwapLayers(i,i+1);
|
|
if (onChangeCb) onChangeCb("layer-moved-up");
|
|
Refresh();
|
|
|
|
//Focus it again
|
|
m_layersList->SetItemState(m_layout.GetLayersCount()-i-1-1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
gd::LogWarning(_("Can't find the layer to move !"));
|
|
}
|
|
|
|
void LayersEditorPanel::OnRefreshClicked(wxCommandEvent& event)
|
|
{
|
|
Refresh();
|
|
}
|