tibia-rme/source/editor_tabs.cpp
Eduardo Dantas 6d501a5ad2
feat: support reading assets from client 11 or higher (#70)
feat: migrate Remeres to 12.x assets system and modernized item handling

• Migrated old Remeres .dat/.spr system to new 12.x client /assets/ appearance & sprite format
• Removed OTB dependency and outdated client version structures
• Integrated Protobuf-based sprite reader (credit: @nekiro)
• Major refactor on graphics.cpp structure and brush icon handling
• Updated brushes and tags system
• Fixed top order drawing bugs and missing brushes icons
• Fixed outfit color paint and correct offset handling for non-32x32 sprites
• Re-enabled map saving and loading
• Improved creature sprite rendering and brush previews
• Added new item properties window with toggle for legacy/new layout

Co-authored-by: Marcos <66353315+marcosvf132@users.noreply.github.com>
Co-authored-by: Pedro Henrique Alves Cruz <phac@cin.ufpe.br>
2025-05-10 16:38:45 -03:00

214 lines
5 KiB
C++

//////////////////////////////////////////////////////////////////////
// This file is part of Remere's Map Editor
//////////////////////////////////////////////////////////////////////
// Remere's Map Editor is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Remere's Map Editor is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//////////////////////////////////////////////////////////////////////
#include "main.h"
#include "editor_tabs.h"
#include "editor.h"
#include "live_tab.h"
EditorTab::EditorTab() {
;
}
EditorTab::~EditorTab() {
;
}
BEGIN_EVENT_TABLE(MapTabbook, wxPanel)
EVT_AUINOTEBOOK_PAGE_CLOSE(wxID_ANY, MapTabbook::OnNotebookPageClose)
EVT_AUINOTEBOOK_PAGE_CHANGED(wxID_ANY, MapTabbook::OnNotebookPageChanged)
END_EVENT_TABLE()
MapTabbook::MapTabbook(wxWindow* parent, wxWindowID id) :
wxPanel(parent, id, wxDefaultPosition, wxDefaultSize) {
wxSizer* wxz = newd wxBoxSizer(wxHORIZONTAL);
notebook = newd wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
wxz->Add(notebook, 1, wxEXPAND);
SetSizerAndFit(wxz);
}
void MapTabbook::CycleTab(bool forward) {
if (!notebook) {
return;
}
int32_t pageCount = notebook->GetPageCount();
int32_t currentSelection = notebook->GetSelection();
int32_t selection;
if (forward) {
selection = (currentSelection + 1) % pageCount;
} else {
selection = (currentSelection - 1 + pageCount) % pageCount;
}
notebook->SetSelection(selection);
}
void MapTabbook::OnNotebookPageClose(wxAuiNotebookEvent &event) {
const auto editorTab = GetTab(event.GetSelection());
const auto mapTab = dynamic_cast<MapTab*>(editorTab);
if (!mapTab) {
return;
}
const auto editor = mapTab->GetEditor();
if (mapTab->IsUniqueReference() && mapTab->GetMap()) {
bool refresh = true;
if (editor->IsLive()) {
if (editor->hasChanges()) {
if (!g_gui.root->DoQuerySave(false)) {
refresh = false;
event.Veto();
}
}
} else if (editor->hasChanges()) {
if (!g_gui.root->DoQuerySave(false)) {
refresh = false;
event.Veto();
}
}
if (refresh) {
g_gui.RefreshPalettes(nullptr, false);
g_gui.UpdateMenus();
}
return;
}
const auto liveTab = dynamic_cast<LiveLogTab*>(editorTab);
if (liveTab && liveTab->IsConnected()) {
event.Veto();
}
}
void MapTabbook::OnNotebookPageChanged(wxAuiNotebookEvent &evt) {
g_gui.UpdateMinimap();
int32_t oldSelection = evt.GetOldSelection();
int32_t newSelection = evt.GetSelection();
MapTab* oldMapTab;
if (oldSelection != -1) {
oldMapTab = dynamic_cast<MapTab*>(GetTab(oldSelection));
} else {
oldMapTab = nullptr;
}
MapTab* newMapTab;
if (newSelection != -1) {
newMapTab = dynamic_cast<MapTab*>(GetTab(newSelection));
} else {
newMapTab = nullptr;
}
if (!newMapTab) {
g_gui.RefreshPalettes(nullptr);
} else if (!oldMapTab || !oldMapTab->HasSameReference(newMapTab)) {
g_gui.RefreshPalettes(newMapTab->GetMap());
g_gui.UpdateMenus();
}
if (oldMapTab) {
oldMapTab->VisibilityCheck();
}
if (newMapTab) {
newMapTab->VisibilityCheck();
}
}
void MapTabbook::OnAllowNotebookDND(wxAuiNotebookEvent &evt) {
evt.Allow();
}
// Wrappers
void MapTabbook::AddTab(EditorTab* tab, bool select) {
tab->GetWindow()->Reparent(notebook);
notebook->AddPage(tab->GetWindow(), tab->GetTitle(), select);
conv[tab->GetWindow()] = tab;
}
void MapTabbook::SetFocusedTab(int idx) {
notebook->SetSelection(idx);
}
EditorTab* MapTabbook::GetInternalTab(int idx) {
return conv[notebook->GetPage(idx)];
}
EditorTab* MapTabbook::GetCurrentTab() {
if (GetTabCount() == 0 || GetSelection() == -1) {
return nullptr;
}
return dynamic_cast<EditorTab*>(GetInternalTab(GetSelection()));
}
EditorTab* MapTabbook::GetTab(int index) {
return GetInternalTab(index);
}
wxWindow* MapTabbook::GetCurrentPage() {
if (GetTabCount() == 0) {
return nullptr;
}
return GetCurrentTab()->GetWindow();
}
void MapTabbook::OnSwitchEditorMode(EditorMode mode) {
for (int32_t i = 0; i < GetTabCount(); ++i) {
EditorTab* editorTab = GetTab(i);
if (editorTab) {
editorTab->OnSwitchEditorMode(mode);
}
}
}
void MapTabbook::SetTabLabel(int idx, wxString label) {
if (notebook) {
notebook->SetPageText(idx, label);
}
}
void MapTabbook::DeleteTab(int idx) {
if (notebook) {
notebook->DeletePage(idx);
}
}
int MapTabbook::GetTabCount() {
if (notebook) {
return notebook->GetPageCount();
}
return 0;
}
int MapTabbook::GetTabIndex(wxWindow* w) {
if (notebook) {
return notebook->GetPageIndex(w);
}
return 0;
}
int MapTabbook::GetSelection() {
if (notebook) {
return notebook->GetSelection();
}
return 0;
}