mirror of
https://github.com/glest/glest-source.git
synced 2025-02-24 03:32:35 +01:00
1788 lines
59 KiB
C++
1788 lines
59 KiB
C++
//
|
|
// map_editor:main.cpp:
|
|
//
|
|
// This file is part of ZetaGlest <https://github.com/ZetaGlest>
|
|
//
|
|
// Copyright (C) 2018 The ZetaGlest team
|
|
//
|
|
// ZetaGlest is a fork of MegaGlest <https://megaglest.org>
|
|
//
|
|
// This program 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.
|
|
|
|
// This program 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 <https://www.gnu.org/licenses/>
|
|
|
|
#include "main.h"
|
|
#include <ctime>
|
|
#include "conversion.h"
|
|
#include "icons.h"
|
|
#include "platform_common.h"
|
|
#include "config.h"
|
|
#include <iostream>
|
|
#include"platform_util.h"
|
|
#include <wx/stdpaths.h>
|
|
#ifndef WIN32
|
|
#include <errno.h>
|
|
#endif
|
|
#include "common_scoped_ptr.h"
|
|
//#include <memory>
|
|
|
|
using namespace Shared::Util;
|
|
using namespace Shared::PlatformCommon;
|
|
using namespace Glest::Game;
|
|
using namespace std;
|
|
|
|
namespace Glest {
|
|
namespace Game {
|
|
string getGameReadWritePath(const string &lookupKey) {
|
|
string path = "";
|
|
if (path == "" && getenv("GLESTHOME") != NULL) {
|
|
path = getenv("GLESTHOME");
|
|
if (path != "" && EndsWith(path, "/") == false && EndsWith(path, "\\") == false) {
|
|
path += "/";
|
|
}
|
|
|
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path to be used for read/write files [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str());
|
|
}
|
|
|
|
return path;
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace MapEditor {
|
|
|
|
const string mapeditorVersionString = "v0.8.01";
|
|
const string MainWindow::winHeader = "ZetaGlest Map Editor " + mapeditorVersionString;
|
|
|
|
// ===============================================
|
|
// class Global functions
|
|
// ===============================================
|
|
|
|
wxString ToUnicode(const char* str) {
|
|
return wxString(str, wxConvUTF8);
|
|
}
|
|
|
|
wxString ToUnicode(const string& str) {
|
|
return wxString(str.c_str(), wxConvUTF8);
|
|
}
|
|
|
|
// ===============================================
|
|
// class MainWindow
|
|
// ===============================================
|
|
|
|
MainWindow::MainWindow(string appPath)
|
|
: wxFrame(NULL, -1, ToUnicode(winHeader), wxPoint(0, 0), wxSize(1024, 768))
|
|
, glCanvas(NULL)
|
|
, program(NULL)
|
|
, lastX(0)
|
|
, lastY(0)
|
|
, panel(NULL)
|
|
, menuBar(NULL)
|
|
, fileDialog(NULL)
|
|
|
|
, currentBrush(btHeight)
|
|
, height(0)
|
|
, surface(1)
|
|
, radius(1)
|
|
, object(0)
|
|
, resource(0)
|
|
, startLocation(1)
|
|
, enabledGroup(ctHeight)
|
|
, fileModified(false)
|
|
, boxsizer(NULL)
|
|
, startupSettingsInited(false) {
|
|
|
|
menuFile = NULL;
|
|
menuEdit = NULL;
|
|
menuEditMirror = NULL;
|
|
menuView = NULL;
|
|
menuBrush = NULL;
|
|
menuBrushHeight = NULL;
|
|
menuBrushGradient = NULL;
|
|
menuBrushSurface = NULL;
|
|
menuBrushObject = NULL;
|
|
menuBrushResource = NULL;
|
|
menuBrushStartLocation = NULL;
|
|
menuRadius = NULL;
|
|
fileDialog = NULL;
|
|
resourceUnderMouse = 0;
|
|
objectUnderMouse = 0;
|
|
|
|
// default values for random height calculation that turned out to be quite useful
|
|
randomWithReset = true;
|
|
randomMinimumHeight = -300;
|
|
randomMaximumHeight = 400;
|
|
randomChanceDivider = 30;
|
|
randomRecursions = 3;
|
|
|
|
this->appPath = appPath;
|
|
Properties::setApplicationPath(executable_path(appPath));
|
|
|
|
this->panel = new wxPanel(this, wxID_ANY);
|
|
}
|
|
|
|
void MainWindow::onToolPlayer(wxCommandEvent& event) {
|
|
PopupMenu(menuBrushStartLocation);
|
|
}
|
|
|
|
void MainToolBar::onMouseMove(wxMouseEvent &event) {
|
|
#ifdef WIN32
|
|
if (this->GetParent() != NULL && this->GetParent()->GetParent() != NULL) {
|
|
MainWindow *mainWindow = dynamic_cast<MainWindow *>(this->GetParent()->GetParent());
|
|
if (mainWindow != NULL) {
|
|
mainWindow->refreshMapRender();
|
|
}
|
|
}
|
|
#endif
|
|
event.Skip();
|
|
}
|
|
|
|
BEGIN_EVENT_TABLE(MainToolBar, wxToolBar)
|
|
|
|
EVT_MOTION(MainToolBar::onMouseMove)
|
|
|
|
END_EVENT_TABLE()
|
|
|
|
void MainWindow::init(string fname) {
|
|
|
|
//menus
|
|
menuBar = new wxMenuBar();
|
|
|
|
//file
|
|
menuFile = new wxMenu();
|
|
menuFile->Append(wxID_NEW);
|
|
menuFile->Append(wxID_OPEN);
|
|
menuFile->AppendSeparator();
|
|
menuFile->Append(wxID_SAVE);
|
|
menuFile->Append(wxID_SAVEAS);
|
|
menuFile->AppendSeparator();
|
|
menuFile->Append(wxID_EXIT);
|
|
menuBar->Append(menuFile, wxT("&File"));
|
|
|
|
//edit
|
|
menuEdit = new wxMenu();
|
|
menuEdit->Append(miEditUndo, wxT("&Undo\tCTRL+Z"));
|
|
menuEdit->Append(miEditRedo, wxT("&Redo\tCTRL+Y"));
|
|
menuEdit->AppendSeparator();
|
|
// menuEdit->Append(miEditReset, wxT("Rese&t..."));
|
|
menuEdit->Append(miEditResetPlayers, wxT("Reset &Players..."));
|
|
menuEdit->Append(miEditResize, wxT("Re&size..."));
|
|
menuEdit->Append(miEditFlipDiagonal, wxT("Flip &Diagonal"));
|
|
menuEdit->Append(miEditFlipX, wxT("Flip &X"));
|
|
menuEdit->Append(miEditFlipY, wxT("Flip &Y"));
|
|
|
|
// Mirror submenu-------------------------------------------
|
|
menuEditMirror = new wxMenu();
|
|
menuEditMirror->Append(miEditMirrorX, wxT("Copy &Left to Right"));
|
|
menuEditMirror->Append(miEditMirrorY, wxT("Copy &Top to Bottom"));
|
|
menuEditMirror->Append(miEditMirrorXY, wxT("Copy &BottomLeft to TopRight"));
|
|
menuEditMirror->AppendSeparator();
|
|
menuEditMirror->Append(miEditRotatecopyX, wxT("&Rotate Left to Right"));
|
|
menuEditMirror->Append(miEditRotatecopyY, wxT("Rotate T&op to Bottom"));
|
|
menuEditMirror->Append(miEditRotatecopyXY, wxT("Rotate Botto&mLeft to TopRight"));
|
|
menuEditMirror->Append(miEditRotatecopyCorner, wxT("Rotate TopLeft &corner to TopRight"));
|
|
menuEdit->Append(miEditMirror, wxT("&Mirror"), menuEditMirror);
|
|
// ---------------------------------------------------------
|
|
|
|
menuEdit->Append(miEditRandomizeHeights, wxT("Randomize &Heights"));
|
|
menuEdit->Append(miEditRandomize, wxT("Randomi&ze Players"));
|
|
menuEdit->Append(miEditSwitchSurfaces, wxT("Switch Sur&faces..."));
|
|
menuEdit->Append(miEditInfo, wxT("&Info..."));
|
|
menuEdit->Append(miEditAdvanced, wxT("&Advanced..."));
|
|
menuBar->Append(menuEdit, wxT("&Edit"));
|
|
|
|
//view
|
|
menuView = new wxMenu();
|
|
menuView->Append(miViewResetZoomAndPos, wxT("&Reset zoom and pos"));
|
|
menuView->AppendCheckItem(miViewGrid, wxT("&Grid"));
|
|
menuView->AppendCheckItem(miViewHeightMap, wxT("H&eightMap"));
|
|
menuView->AppendCheckItem(miHideWater, wxT("Hide&Water"));
|
|
menuView->AppendSeparator();
|
|
menuView->Append(miViewHelp, wxT("&Help..."));
|
|
menuView->Append(miViewAbout, wxT("&About..."));
|
|
menuBar->Append(menuView, wxT("&View"));
|
|
|
|
//brush
|
|
// menuBrush = new wxMenu();
|
|
|
|
//surface
|
|
menuBrushSurface = new wxMenu();
|
|
menuBrushSurface->AppendCheckItem(miBrushSurface + 1, wxT("&Grass"));
|
|
menuBrushSurface->AppendCheckItem(miBrushSurface + 2, wxT("S&econdary grass"));
|
|
menuBrushSurface->AppendCheckItem(miBrushSurface + 3, wxT("&Road"));
|
|
menuBrushSurface->AppendCheckItem(miBrushSurface + 4, wxT("&Stone"));
|
|
menuBrushSurface->AppendCheckItem(miBrushSurface + 5, wxT("Gr&ound"));
|
|
menuBar->Append(menuBrushSurface, wxT("&Surface"));
|
|
|
|
//resources
|
|
menuBrushResource = new wxMenu();
|
|
//menuBrushResource->AppendCheckItem(miBrushResource + 1, wxT("&0 - None"));
|
|
menuBrushResource->AppendCheckItem(miBrushResource + 2, wxT("&Gold (unwalkable)"));
|
|
menuBrushResource->AppendCheckItem(miBrushResource + 3, wxT("&Stone (unwalkable)"));
|
|
menuBrushResource->AppendCheckItem(miBrushResource + 4, wxT("&3 - custom"));
|
|
menuBrushResource->AppendCheckItem(miBrushResource + 5, wxT("&4 - custom"));
|
|
menuBrushResource->AppendCheckItem(miBrushResource + 6, wxT("&5 - custom"));
|
|
menuBar->Append(menuBrushResource, wxT("&Resource"));
|
|
|
|
//objects
|
|
menuBrushObject = new wxMenu();
|
|
menuBrushObject->AppendCheckItem(miBrushObject + 1, wxT("&None (erase)\tALT+0"));
|
|
menuBrushObject->AppendSeparator();
|
|
menuBrushObject->AppendCheckItem(miBrushObject + 2, wxT("&Tree (harvestable)"));
|
|
menuBrushObject->AppendCheckItem(miBrushObject + 3, wxT("&Dead tree/Cactuses/Thornbush"));
|
|
menuBrushObject->AppendCheckItem(miBrushObject + 4, wxT("&Stone"));
|
|
menuBrushObject->AppendCheckItem(miBrushObject + 5, wxT("&Bush/Grass/Fern (walkable)"));
|
|
menuBrushObject->AppendCheckItem(miBrushObject + 6, wxT("&Water object/Reed/Papyrus (walkable)"));
|
|
menuBrushObject->AppendCheckItem(miBrushObject + 7, wxT("Big tree/&Old palm"));
|
|
menuBrushObject->AppendCheckItem(miBrushObject + 8, wxT("&Hanged/Impaled "));
|
|
menuBrushObject->AppendCheckItem(miBrushObject + 9, wxT("St&atues"));
|
|
menuBrushObject->AppendCheckItem(miBrushObject + 10, wxT("&Mountain"));
|
|
menuBrushObject->AppendCheckItem(miBrushObject + 11, wxT("&Invisible blocking object"));
|
|
menuBar->Append(menuBrushObject, wxT("&Object"));
|
|
|
|
// ZombiePirate height brush
|
|
menuBrushGradient = new wxMenu();
|
|
for (int i = 0; i < heightCount; ++i) {
|
|
menuBrushGradient->AppendCheckItem(miBrushGradient + i + 1, ToUnicode((i > 4 ? "&" : "") + intToStr(i - heightCount / 2)));
|
|
}
|
|
menuBar->Append(menuBrushGradient, wxT("&Gradient"));
|
|
|
|
// Glest height brush
|
|
menuBrushHeight = new wxMenu();
|
|
for (int i = 0; i < heightCount; ++i) {
|
|
menuBrushHeight->AppendCheckItem(miBrushHeight + i + 1, ToUnicode((i > 4 ? "&" : "") + intToStr(i - heightCount / 2)));
|
|
}
|
|
menuBrushHeight->Check(miBrushHeight + (heightCount + 1) / 2, true);
|
|
menuBar->Append(menuBrushHeight, wxT("&Height"));
|
|
|
|
enabledGroup = ctHeight;
|
|
|
|
//radius
|
|
menuRadius = new wxMenu();
|
|
for (int i = 1; i <= radiusCount; ++i) {
|
|
menuRadius->AppendCheckItem(miRadius + i, ToUnicode("&" + intToStr(i) + " (diameter " + intToStr(i * 2 - 1) + ")" + "\tALT+" + intToStr(i)));
|
|
}
|
|
menuRadius->Check(miRadius + 1, true);
|
|
menuBar->Append(menuRadius, wxT("R&adius"));
|
|
|
|
//players
|
|
menuBrushStartLocation = new wxMenu();
|
|
wxMenuItem *pmi1 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 1, wxT("Player &1 Red"));
|
|
pmi1->SetBitmap(wxBitmap(brush_players_red));
|
|
menuBrushStartLocation->Append(pmi1);
|
|
wxMenuItem *pmi2 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 2, wxT("Player &2 Blue"));
|
|
pmi2->SetBitmap(wxBitmap(brush_players_blue));
|
|
menuBrushStartLocation->Append(pmi2);
|
|
wxMenuItem *pmi3 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 3, wxT("Player &3 Green"));
|
|
pmi3->SetBitmap(wxBitmap(brush_players_green));
|
|
menuBrushStartLocation->Append(pmi3);
|
|
wxMenuItem *pmi4 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 4, wxT("Player &4 Yellow"));
|
|
pmi4->SetBitmap(wxBitmap(brush_players_yellow));
|
|
menuBrushStartLocation->Append(pmi4);
|
|
wxMenuItem *pmi5 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 5, wxT("Player &5 White"));
|
|
pmi5->SetBitmap(wxBitmap(brush_players_white));
|
|
menuBrushStartLocation->Append(pmi5);
|
|
wxMenuItem *pmi6 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 6, wxT("Player &6 Cyan"));
|
|
pmi6->SetBitmap(wxBitmap(brush_players_cyan));
|
|
menuBrushStartLocation->Append(pmi6);
|
|
wxMenuItem *pmi7 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 7, wxT("Player &7 Orange"));
|
|
pmi7->SetBitmap(wxBitmap(brush_players_orange));
|
|
menuBrushStartLocation->Append(pmi7);
|
|
wxMenuItem *pmi8 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 8, wxT("Player &8 Pink")); // = Light Magenta :-)
|
|
pmi8->SetBitmap(wxBitmap(brush_players_pink));
|
|
menuBrushStartLocation->Append(pmi8);
|
|
menuBar->Append(menuBrushStartLocation, wxT("&Player"));
|
|
//menuBar->Append(menuBrush, wxT("&Brush"));
|
|
|
|
|
|
SetMenuBar(menuBar);
|
|
|
|
fileName = "New (unsaved) map";
|
|
int status_widths[siCOUNT] = {
|
|
10, // empty
|
|
-25, // File name
|
|
-6, // File type
|
|
-20, // Current Object
|
|
-14, // Brush Type
|
|
-20, // Brush 'Value'
|
|
-10, // Brush Radius
|
|
-25, // Position
|
|
};
|
|
CreateStatusBar(siCOUNT);
|
|
GetStatusBar()->SetStatusWidths(siCOUNT, status_widths);
|
|
|
|
SetStatusText(wxT("File: ") + ToUnicode(fileName), siFILE_NAME);
|
|
SetStatusText(wxT(".mgm"), siFILE_TYPE);
|
|
SetStatusText(wxT("Object: None (Erase)"), siCURR_OBJECT);
|
|
SetStatusText(wxT("Brush: Height"), siBRUSH_TYPE);
|
|
SetStatusText(wxT("Value: 0"), siBRUSH_VALUE);
|
|
SetStatusText(wxT("Radius: 1"), siBRUSH_RADIUS);
|
|
SetStatusText(wxT("Pos (Ingame): 0"), siPOS_VALUE);
|
|
|
|
wxToolBar *toolbar = new MainToolBar(this->panel, wxID_ANY);
|
|
toolbar->AddTool(miEditUndo, _("undo"), wxBitmap(edit_undo), _("Undo"));
|
|
toolbar->AddTool(miEditRedo, _("redo"), wxBitmap(edit_redo), _("Redo"));
|
|
toolbar->AddTool(miEditRandomizeHeights, _("randomizeHeights"), wxBitmap(edit_randomize_heights), _("Randomize Heights"));
|
|
// toolbar->AddTool(miEditRandomize, _("randomize"), wxBitmap(edit_randomize), _("Randomize"));
|
|
toolbar->AddTool(miEditSwitchSurfaces, _("switch"), wxBitmap(edit_switch_surfaces), _("Switch Surfaces"));
|
|
toolbar->AddSeparator();
|
|
toolbar->AddTool(miBrushSurface + 1, _("brush_grass1"), wxBitmap(brush_surface_grass1), _("Grass"));
|
|
toolbar->AddTool(miBrushSurface + 2, _("brush_grass2"), wxBitmap(brush_surface_grass2), _("Secondary grass"));
|
|
toolbar->AddTool(miBrushSurface + 3, _("brush_road"), wxBitmap(brush_surface_road), _("Road"));
|
|
toolbar->AddTool(miBrushSurface + 4, _("brush_stone"), wxBitmap(brush_surface_stone), _("Stone"));
|
|
toolbar->AddTool(miBrushSurface + 5, _("brush_custom"), wxBitmap(brush_surface_custom), _("Ground"));
|
|
toolbar->AddSeparator();
|
|
toolbar->AddTool(miBrushResource + 2, _("resource1"), wxBitmap(brush_resource_1_gold), _("gold (unwalkable)"));
|
|
toolbar->AddTool(miBrushResource + 3, _("resource2"), wxBitmap(brush_resource_2_stone), _("stone (unwalkable)"));
|
|
toolbar->AddTool(miBrushResource + 4, _("resource3"), wxBitmap(brush_resource_3), _("custom3"));
|
|
toolbar->AddTool(miBrushResource + 5, _("resource4"), wxBitmap(brush_resource_4), _("custom4"));
|
|
toolbar->AddTool(miBrushResource + 6, _("resource5"), wxBitmap(brush_resource_5), _("custom5"));
|
|
toolbar->AddSeparator();
|
|
toolbar->AddTool(miBrushObject + 1, _("brush_none"), wxBitmap(brush_none), _("None (erase)"));
|
|
toolbar->AddTool(miBrushObject + 2, _("brush_tree"), wxBitmap(brush_object_tree), _("Tree (unwalkable/harvestable)"));
|
|
toolbar->AddTool(miBrushObject + 3, _("brush_dead_tree"), wxBitmap(brush_object_dead_tree), _("Dead tree/Cactuses/Thornbush (unwalkable)"));
|
|
toolbar->AddTool(miBrushObject + 4, _("brush_stone"), wxBitmap(brush_object_stone), _("Stone (unwalkable/not harvestable)"));
|
|
toolbar->AddTool(miBrushObject + 5, _("brush_bush"), wxBitmap(brush_object_bush), _("Bush/Grass/Fern (walkable)"));
|
|
toolbar->AddTool(miBrushObject + 6, _("brush_water"), wxBitmap(brush_object_water_object), _("Water object/Reed/Papyrus (walkable)"));
|
|
toolbar->AddTool(miBrushObject + 7, _("brush_c1_bigtree"), wxBitmap(brush_object_c1_bigtree), _("Big tree/Old palm (unwalkable/not harvestable)"));
|
|
toolbar->AddTool(miBrushObject + 8, _("brush_c2_hanged"), wxBitmap(brush_object_c2_hanged), _("Hanged/Impaled (unwalkable)"));
|
|
toolbar->AddTool(miBrushObject + 9, _("brush_c3_statue"), wxBitmap(brush_object_c3_statue), _("Statues (unwalkable)"));
|
|
toolbar->AddTool(miBrushObject + 10, _("brush_c4_bigrock"), wxBitmap(brush_object_c4_bigrock), _("Mountain (unwalkable)"));
|
|
toolbar->AddTool(miBrushObject + 11, _("brush_c5_blocking"), wxBitmap(brush_object_c5_blocking), _("Invisible blocking object (unwalkable)"));
|
|
toolbar->AddSeparator();
|
|
toolbar->AddTool(toolPlayer, _("brush_player"), wxBitmap(brush_players_player), _("Player start position"));
|
|
toolbar->Realize();
|
|
|
|
wxToolBar *toolbar2 = new MainToolBar(this->panel, wxID_ANY);
|
|
toolbar2->AddTool(miBrushGradient + 1, _("brush_gradient_n5"), wxBitmap(brush_gradient_n5));
|
|
toolbar2->AddTool(miBrushGradient + 2, _("brush_gradient_n4"), wxBitmap(brush_gradient_n4));
|
|
toolbar2->AddTool(miBrushGradient + 3, _("brush_gradient_n3"), wxBitmap(brush_gradient_n3));
|
|
toolbar2->AddTool(miBrushGradient + 4, _("brush_gradient_n2"), wxBitmap(brush_gradient_n2));
|
|
toolbar2->AddTool(miBrushGradient + 5, _("brush_gradient_n1"), wxBitmap(brush_gradient_n1));
|
|
toolbar2->AddTool(miBrushGradient + 6, _("brush_gradient_0"), wxBitmap(brush_gradient_0));
|
|
toolbar2->AddTool(miBrushGradient + 7, _("brush_gradient_p1"), wxBitmap(brush_gradient_p1));
|
|
toolbar2->AddTool(miBrushGradient + 8, _("brush_gradient_p2"), wxBitmap(brush_gradient_p2));
|
|
toolbar2->AddTool(miBrushGradient + 9, _("brush_gradient_p3"), wxBitmap(brush_gradient_p3));
|
|
toolbar2->AddTool(miBrushGradient + 10, _("brush_gradient_p4"), wxBitmap(brush_gradient_p4));
|
|
toolbar2->AddTool(miBrushGradient + 11, _("brush_gradient_p5"), wxBitmap(brush_gradient_p5));
|
|
toolbar2->AddSeparator();
|
|
toolbar2->AddTool(miBrushHeight + 1, _("brush_height_n5"), wxBitmap(brush_height_n5));
|
|
toolbar2->AddTool(miBrushHeight + 2, _("brush_height_n4"), wxBitmap(brush_height_n4));
|
|
toolbar2->AddTool(miBrushHeight + 3, _("brush_height_n3"), wxBitmap(brush_height_n3));
|
|
toolbar2->AddTool(miBrushHeight + 4, _("brush_height_n2"), wxBitmap(brush_height_n2));
|
|
toolbar2->AddTool(miBrushHeight + 5, _("brush_height_n1"), wxBitmap(brush_height_n1));
|
|
toolbar2->AddTool(miBrushHeight + 6, _("brush_height_0"), wxBitmap(brush_height_0));
|
|
toolbar2->AddTool(miBrushHeight + 7, _("brush_height_p1"), wxBitmap(brush_height_p1));
|
|
toolbar2->AddTool(miBrushHeight + 8, _("brush_height_p2"), wxBitmap(brush_height_p2));
|
|
toolbar2->AddTool(miBrushHeight + 9, _("brush_height_p3"), wxBitmap(brush_height_p3));
|
|
toolbar2->AddTool(miBrushHeight + 10, _("brush_height_p4"), wxBitmap(brush_height_p4));
|
|
toolbar2->AddTool(miBrushHeight + 11, _("brush_height_p5"), wxBitmap(brush_height_p5));
|
|
toolbar2->AddSeparator();
|
|
toolbar2->AddTool(miRadius + 1, _("radius1"), wxBitmap(radius_1), _("1 (1x1)"));
|
|
toolbar2->AddTool(miRadius + 2, _("radius2"), wxBitmap(radius_2), _("2 (3x3)"));
|
|
toolbar2->AddTool(miRadius + 3, _("radius3"), wxBitmap(radius_3), _("3 (5x5)"));
|
|
toolbar2->AddTool(miRadius + 4, _("radius4"), wxBitmap(radius_4), _("4 (7x7)"));
|
|
toolbar2->AddTool(miRadius + 5, _("radius5"), wxBitmap(radius_5), _("5 (9x9)"));
|
|
toolbar2->AddTool(miRadius + 6, _("radius6"), wxBitmap(radius_6), _("6 (11x11)"));
|
|
toolbar2->AddTool(miRadius + 7, _("radius7"), wxBitmap(radius_7), _("7 (13x13)"));
|
|
toolbar2->AddTool(miRadius + 8, _("radius8"), wxBitmap(radius_8), _("8 (15x15)"));
|
|
toolbar2->AddTool(miRadius + 9, _("radius9"), wxBitmap(radius_9), _("9 (17x17)"));
|
|
toolbar2->Realize();
|
|
|
|
Config &config = Config::getInstance();
|
|
|
|
string userData = config.getString("UserData_Root", "");
|
|
if (userData != "") {
|
|
endPathWithSlash(userData);
|
|
}
|
|
|
|
//std::cout << "A" << std::endl;
|
|
wxInitAllImageHandlers();
|
|
#ifdef WIN32
|
|
//std::cout << "B" << std::endl;
|
|
// #if defined(__MINGW32__)
|
|
wxIcon icon(ToUnicode("IDI_ICON1"));
|
|
// #else
|
|
// wxIcon icon("IDI_ICON1");
|
|
// #endif
|
|
|
|
#else
|
|
//std::cout << "B" << std::endl;
|
|
wxIcon icon;
|
|
string iniFilePath = extractDirectoryPathFromFile(config.getFileName(false));
|
|
string icon_file = iniFilePath + "editor.ico";
|
|
std::ifstream testFile(icon_file.c_str());
|
|
if (testFile.good()) {
|
|
testFile.close();
|
|
icon.LoadFile(ToUnicode(icon_file.c_str()), wxBITMAP_TYPE_ICO);
|
|
}
|
|
#endif
|
|
//std::cout << "C" << std::endl;
|
|
SetIcon(icon);
|
|
fileDialog = new wxFileDialog(this);
|
|
string defaultPath = userData + "maps/";
|
|
fileDialog->SetDirectory(ToUnicode(defaultPath));
|
|
|
|
//printf("Default Path [%s]\n",defaultPath.c_str());
|
|
|
|
lastPaintEvent.start();
|
|
|
|
boxsizer = new wxBoxSizer(wxVERTICAL);
|
|
boxsizer->Add(toolbar, 0, wxEXPAND);
|
|
boxsizer->Add(toolbar2, 0, wxEXPAND);
|
|
//boxsizer->Add(glCanvas, 1, wxEXPAND);
|
|
|
|
this->panel->SetSizer(boxsizer);
|
|
//this->Layout();
|
|
|
|
//program = new Program(glCanvas->GetClientSize().x, glCanvas->GetClientSize().y);
|
|
|
|
fileName = "New (unsaved) Map";
|
|
|
|
//printf("Does file exist, fname [%s]\n",fname.c_str());
|
|
|
|
if (fname.empty() == false && fileExists(fname)) {
|
|
//printf("YES file exist, fname [%s]\n",fname.c_str());
|
|
|
|
//program->loadMap(fname);
|
|
currentFile = fname;
|
|
fileName = cutLastExt(extractFileFromDirectoryPath(fname.c_str()));
|
|
fileDialog->SetPath(ToUnicode(fname));
|
|
SetTitle(ToUnicode(winHeader + " - " + fname));
|
|
} else
|
|
SetTitle(ToUnicode(winHeader));
|
|
//setDirty(false);
|
|
//setExtension();
|
|
|
|
initGlCanvas();
|
|
#if wxCHECK_VERSION(2, 9, 3)
|
|
//glCanvas->setCurrentGLContext();
|
|
//printf("setcurrent #1\n");
|
|
#elif wxCHECK_VERSION(2, 9, 1)
|
|
|
|
#else
|
|
if (glCanvas) glCanvas->SetCurrent();
|
|
//printf("setcurrent #2\n");
|
|
#endif
|
|
|
|
if (startupSettingsInited == false) {
|
|
startupSettingsInited = true;
|
|
setupStartupSettings();
|
|
}
|
|
}
|
|
|
|
void MainWindow::onClose(wxCloseEvent &event) {
|
|
if (program != NULL && program->getMap()->getHasChanged() == true) {
|
|
if (wxMessageDialog(NULL, ToUnicode("Do you want to save the current map?"),
|
|
ToUnicode("Question"), wxYES_NO | wxYES_DEFAULT).ShowModal() == wxID_YES) {
|
|
wxCommandEvent ev;
|
|
MainWindow::onMenuFileSave(ev);
|
|
}
|
|
}
|
|
delete program;
|
|
program = NULL;
|
|
|
|
//delete glCanvas;
|
|
if (glCanvas) glCanvas->Destroy();
|
|
glCanvas = NULL;
|
|
|
|
this->Destroy();
|
|
}
|
|
|
|
void MainWindow::initGlCanvas() {
|
|
if (glCanvas == NULL) {
|
|
int args[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_MIN_ALPHA, 8 };
|
|
glCanvas = new GlCanvas(this, this->panel, args);
|
|
|
|
boxsizer->Add(glCanvas, 1, wxEXPAND);
|
|
}
|
|
}
|
|
|
|
void MainWindow::setupStartupSettings() {
|
|
|
|
//gl canvas
|
|
if (glCanvas == NULL) {
|
|
initGlCanvas();
|
|
|
|
boxsizer->Add(glCanvas, 1, wxEXPAND);
|
|
|
|
this->panel->SetSizer(boxsizer);
|
|
this->Layout();
|
|
}
|
|
glCanvas->setCurrentGLContext();
|
|
glCanvas->SetFocus();
|
|
|
|
string playerName = Config::getInstance().getString("NetPlayerName", "");
|
|
program = new Program(glCanvas->GetClientSize().x, glCanvas->GetClientSize().y, playerName);
|
|
fileName = "New (unsaved) Map";
|
|
|
|
//printf("#0 file load [%s]\n",currentFile.c_str());
|
|
|
|
if (!currentFile.empty() && fileExists(currentFile)) {
|
|
//printf("#0 exists file load [%s]\n",currentFile.c_str());
|
|
|
|
program->loadMap(currentFile);
|
|
//currentFile = fname;
|
|
fileName = cutLastExt(extractFileFromDirectoryPath(currentFile.c_str()));
|
|
fileDialog->SetPath(ToUnicode(currentFile));
|
|
SetTitle(ToUnicode(winHeader + " - " + currentFile));
|
|
} else
|
|
SetTitle(ToUnicode(winHeader));
|
|
|
|
setDirty(false);
|
|
setExtension();
|
|
}
|
|
|
|
MainWindow::~MainWindow() {
|
|
delete fileDialog;
|
|
fileDialog = NULL;
|
|
|
|
delete program;
|
|
program = NULL;
|
|
|
|
delete glCanvas;
|
|
glCanvas = NULL;
|
|
}
|
|
|
|
void MainWindow::setDirty(bool val) {
|
|
wxPaintEvent ev;
|
|
onPaint(ev);
|
|
if (fileModified && val) {
|
|
return;
|
|
}
|
|
fileModified = val;
|
|
if (fileModified) {
|
|
SetStatusText(wxT("File: ") + ToUnicode(fileName) + wxT("*"), siFILE_NAME);
|
|
} else {
|
|
SetStatusText(wxT("File: ") + ToUnicode(fileName), siFILE_NAME);
|
|
}
|
|
}
|
|
|
|
void MainWindow::setExtension() {
|
|
if (currentFile.empty() || program == NULL) {
|
|
return;
|
|
}
|
|
|
|
string extnsn = ext(currentFile);
|
|
|
|
//printf("#A currentFile [%s] extnsn [%s]\n",currentFile.c_str(),extnsn.c_str());
|
|
|
|
if (extnsn == "gbm" || extnsn == "mgm") {
|
|
currentFile = cutLastExt(currentFile);
|
|
}
|
|
SetStatusText(wxT(".mgm"), siFILE_TYPE);
|
|
currentFile += ".mgm";
|
|
}
|
|
|
|
void MainWindow::onMouseDown(wxMouseEvent &event, int x, int y) {
|
|
if (event.LeftIsDown() && program != NULL) {
|
|
program->setUndoPoint(enabledGroup);
|
|
program->setRefAlt(x, y);
|
|
change(x, y);
|
|
if (!isDirty()) {
|
|
setDirty(true);
|
|
}
|
|
wxPaintEvent ev;
|
|
onPaint(ev);
|
|
}
|
|
event.Skip();
|
|
}
|
|
|
|
// for the mousewheel
|
|
void MainWindow::onMouseWheelDown(wxMouseEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
wxPaintEvent ev;
|
|
program->incCellSize(1);
|
|
onPaint(ev);
|
|
}
|
|
|
|
void MainWindow::onMouseWheelUp(wxMouseEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
wxPaintEvent ev;
|
|
program->incCellSize(-1);
|
|
onPaint(ev);
|
|
}
|
|
|
|
void MainWindow::onMouseMove(wxMouseEvent &event, int x, int y) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
bool repaint = false;
|
|
if (event.LeftIsDown()) {
|
|
change(x, y);
|
|
repaint = true;
|
|
} else if (event.MiddleIsDown()) {
|
|
int dif = (y - lastY);
|
|
if (dif != 0) {
|
|
program->incCellSize(dif / abs(dif));
|
|
repaint = true;
|
|
}
|
|
} else if (event.RightIsDown()) {
|
|
program->setOfset(x - lastX, y - lastY);
|
|
repaint = true;
|
|
} else {
|
|
int currResource = program->getResource(x, y);
|
|
if (currResource > 0) {
|
|
SetStatusText(wxT("Resource: ") + ToUnicode(resource_descs[currResource]), siCURR_OBJECT);
|
|
resourceUnderMouse = currResource;
|
|
objectUnderMouse = 0;
|
|
} else {
|
|
int currObject = program->getObject(x, y);
|
|
SetStatusText(wxT("Object: ") + ToUnicode(object_descs[currObject]), siCURR_OBJECT);
|
|
resourceUnderMouse = 0;
|
|
objectUnderMouse = currObject;
|
|
}
|
|
|
|
SetStatusText(wxT("Pos (Ingame): ")
|
|
+ ToUnicode(intToStr(program->getCellX(x))
|
|
+ ","
|
|
+ intToStr(program->getCellY(y))
|
|
+ " ("
|
|
+ intToStr(2 * (program->getCellX(x)))
|
|
+ ","
|
|
+ intToStr(2 * (program->getCellY(y)))
|
|
+ ")"), siPOS_VALUE);
|
|
//#ifdef WIN32
|
|
//repaint = true;
|
|
//#endif
|
|
}
|
|
lastX = x;
|
|
lastY = y;
|
|
|
|
if (repaint) {
|
|
wxPaintEvent ev;
|
|
onPaint(ev);
|
|
}
|
|
event.Skip();
|
|
}
|
|
|
|
void MainWindow::onPaint(wxPaintEvent &event) {
|
|
//printf("onPaint map\n");
|
|
|
|
if (!IsShown()) {
|
|
//printf("onPaint skip map\n");
|
|
|
|
event.Skip();
|
|
return;
|
|
}
|
|
|
|
//#if wxCHECK_VERSION(2, 9, 3)
|
|
|
|
//#elif wxCHECK_VERSION(2, 9, 1)
|
|
// glCanvas->setCurrentGLContext();
|
|
//#endif
|
|
|
|
//static bool contextSet = false;
|
|
//if(contextSet == false) {
|
|
// contextSet = true;
|
|
glCanvas->setCurrentGLContext();
|
|
//}
|
|
|
|
//printf("lastPaintEvent.getMillis() map\n");
|
|
if (lastPaintEvent.getMillis() < 30) {
|
|
sleep(1);
|
|
event.Skip();
|
|
return;
|
|
}
|
|
|
|
//printf("wxPaintDC dc map\n");
|
|
wxPaintDC dc(this); // "In a paint event handler must always create a wxPaintDC object even if you do not use it. (?)
|
|
// Otherwise, under MS Windows, refreshing for this and other windows will go wrong"
|
|
// http://docs.wxwidgets.org/2.6/wx_wxpaintevent.html
|
|
|
|
lastPaintEvent.start();
|
|
|
|
if (panel) panel->Refresh(false);
|
|
if (menuBar) menuBar->Refresh(false);
|
|
|
|
refreshMapRender();
|
|
event.Skip();
|
|
}
|
|
|
|
void MainWindow::refreshMapRender() {
|
|
//printf("refreshMapRender map\n");
|
|
|
|
if (program && glCanvas) {
|
|
program->renderMap(glCanvas->GetClientSize().x, glCanvas->GetClientSize().y);
|
|
glCanvas->SwapBuffers();
|
|
}
|
|
}
|
|
|
|
void MainWindow::onMenuFileLoad(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
fileDialog->SetMessage(wxT("Select Glestmap to load"));
|
|
fileDialog->SetWildcard(wxT("Glest&Mega Map (*.gbm *.mgm)|*.gbm;*.mgm|Glest Map (*.gbm)|*.gbm|Mega Map (*.mgm)|*.mgm"));
|
|
if (fileDialog->ShowModal() == wxID_OK) {
|
|
#ifdef WIN32
|
|
const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(fileDialog->GetPath()));
|
|
currentFile = tmp_buf;
|
|
|
|
auto_ptr<wchar_t> wstr(Ansi2WideString(currentFile.c_str()));
|
|
currentFile = utf8_encode(wstr.get());
|
|
#elif wxCHECK_VERSION(2, 9, 1)
|
|
currentFile = fileDialog->GetPath().ToStdString();
|
|
#else
|
|
const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(fileDialog->GetPath());
|
|
currentFile = tmp_buf;
|
|
#endif
|
|
|
|
//printf("#1 file load [%s]\n",currentFile.c_str());
|
|
|
|
program->loadMap(currentFile);
|
|
fileName = cutLastExt(extractFileFromDirectoryPath(currentFile.c_str()));
|
|
setDirty(false);
|
|
setExtension();
|
|
SetTitle(ToUnicode(winHeader + " - " + currentFile));
|
|
}
|
|
} catch (const string &e) {
|
|
MsgDialog(this, ToUnicode(e), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal();
|
|
} catch (const exception &e) {
|
|
MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal();
|
|
}
|
|
|
|
}
|
|
|
|
void MainWindow::onMenuFileSave(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
if (currentFile.empty()) {
|
|
wxCommandEvent ev;
|
|
onMenuFileSaveAs(ev);
|
|
} else {
|
|
setExtension();
|
|
|
|
//printf("#1 save load [%s]\n",currentFile.c_str());
|
|
|
|
program->saveMap(currentFile);
|
|
setDirty(false);
|
|
}
|
|
}
|
|
|
|
void MainWindow::onMenuFileSaveAs(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
#if wxCHECK_VERSION(2, 9, 1)
|
|
wxFileDialog fd(this, wxT("Select file"), wxT(""), wxT(""), wxT("*.mgm|*.gbm"), wxFD_SAVE);
|
|
#else
|
|
wxFileDialog fd(this, wxT("Select file"), wxT(""), wxT(""), wxT("*.mgm|*.gbm"), wxSAVE);
|
|
#endif
|
|
|
|
if (fileDialog->GetPath() != ToUnicode("")) {
|
|
fd.SetPath(fileDialog->GetPath());
|
|
} else {
|
|
Config &config = Config::getInstance();
|
|
string userData = config.getString("UserData_Root", "");
|
|
if (userData != "") {
|
|
endPathWithSlash(userData);
|
|
}
|
|
string defaultPath = userData + "maps/";
|
|
fd.SetDirectory(ToUnicode(defaultPath));
|
|
}
|
|
|
|
fd.SetWildcard(wxT("ZetaGlest Map (*.mgm)|*.mgm|Glest Map (*.gbm)|*.gbm"));
|
|
if (fd.ShowModal() == wxID_OK) {
|
|
#ifdef WIN32
|
|
const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(fd.GetPath()));
|
|
currentFile = tmp_buf;
|
|
|
|
auto_ptr<wchar_t> wstr(Ansi2WideString(currentFile.c_str()));
|
|
currentFile = utf8_encode(wstr.get());
|
|
#elif wxCHECK_VERSION(2, 9, 1)
|
|
currentFile = fd.GetPath().ToStdString();
|
|
#else
|
|
const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(fd.GetPath());
|
|
currentFile = tmp_buf;
|
|
#endif
|
|
|
|
fileDialog->SetPath(fd.GetPath());
|
|
setExtension();
|
|
|
|
//printf("#2 file save [%s]\n",currentFile.c_str());
|
|
|
|
program->saveMap(currentFile);
|
|
fileName = cutLastExt(extractFileFromDirectoryPath(currentFile.c_str()));
|
|
setDirty(false);
|
|
}
|
|
SetTitle(ToUnicode(winHeader + " - " + currentFile));
|
|
}
|
|
|
|
void MainWindow::onMenuFileExit(wxCommandEvent &event) {
|
|
Close();
|
|
}
|
|
|
|
void MainWindow::onMenuEditUndo(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
// std::cout << "Undo Pressed" << std::endl;
|
|
if (program->undo()) {
|
|
wxPaintEvent e;
|
|
onPaint(e);
|
|
setDirty();
|
|
}
|
|
}
|
|
|
|
void MainWindow::onMenuEditRedo(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
if (program->redo()) {
|
|
wxPaintEvent e;
|
|
onPaint(e);
|
|
setDirty();
|
|
}
|
|
}
|
|
|
|
void MainWindow::onMenuEditReset(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
program->setUndoPoint(ctAll);
|
|
SimpleDialog simpleDialog;
|
|
simpleDialog.addValue("Width", "128", "(must be 16,32,64,128,256,512...)"); // must be an exponent of two
|
|
simpleDialog.addValue("Height", "128", "(must be 16,32,64,128,256,512...)");
|
|
simpleDialog.addValue("Surface", "1", "(Default surface material)");
|
|
simpleDialog.addValue("Altitude", "10", "(Default surface height)");
|
|
simpleDialog.addValue("Number of players", "8");
|
|
if (!simpleDialog.show()) return;
|
|
|
|
try {
|
|
program->reset(
|
|
strToInt(simpleDialog.getValue("Width")),
|
|
strToInt(simpleDialog.getValue("Height")),
|
|
strToInt(simpleDialog.getValue("Altitude")),
|
|
strToInt(simpleDialog.getValue("Surface")));
|
|
program->resetFactions(strToInt(simpleDialog.getValue("Number of players")));
|
|
} catch (const exception &e) {
|
|
MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal();
|
|
}
|
|
currentFile = "";
|
|
fileName = "New (unsaved) map";
|
|
|
|
wxPaintEvent ev;
|
|
onPaint(ev);
|
|
}
|
|
|
|
void MainWindow::onMenuEditResetPlayers(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
SimpleDialog simpleDialog;
|
|
simpleDialog.addValue("Number of players", intToStr(program->getMap()->getMaxFactions()));
|
|
if (!simpleDialog.show("Reset players")) return;
|
|
|
|
try {
|
|
program->resetFactions(strToInt(simpleDialog.getValue("Number of players")));
|
|
} catch (const exception &e) {
|
|
MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal();
|
|
}
|
|
setDirty();
|
|
setExtension();
|
|
}
|
|
|
|
|
|
void MainWindow::onMenuEditFlipDiagonal(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
program->setUndoPoint(ctAll);
|
|
program->flipDiagonal();
|
|
setDirty();
|
|
}
|
|
|
|
void MainWindow::onMenuEditResize(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
SimpleDialog simpleDialog;
|
|
simpleDialog.addValue("Width", intToStr(program->getMap()->getW()), "(must be 16,32,64,128,256,512...)");
|
|
simpleDialog.addValue("Height", intToStr(program->getMap()->getH()), "(must be 16,32,64,128,256,512...)");
|
|
simpleDialog.addValue("Surface", "1", "(surface material for new area around map)");
|
|
simpleDialog.addValue("Altitude", "10", "(surface height for new area around map)");
|
|
if (!simpleDialog.show("Resize - expand around, shrink to topleft")) return;
|
|
|
|
try {
|
|
program->resize(
|
|
strToInt(simpleDialog.getValue("Width")),
|
|
strToInt(simpleDialog.getValue("Height")),
|
|
strToInt(simpleDialog.getValue("Altitude")),
|
|
strToInt(simpleDialog.getValue("Surface")));
|
|
} catch (const exception &e) {
|
|
MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal();
|
|
}
|
|
setDirty();
|
|
}
|
|
|
|
void MainWindow::onMenuEditFlipX(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
program->setUndoPoint(ctAll);
|
|
program->flipX();
|
|
setDirty();
|
|
}
|
|
|
|
void MainWindow::onMenuEditFlipY(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
program->setUndoPoint(ctAll);
|
|
program->flipY();
|
|
setDirty();
|
|
}
|
|
|
|
void MainWindow::onMenuEditMirrorX(wxCommandEvent &event) { // copy left to right
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
program->setUndoPoint(ctAll);
|
|
program->mirrorX();
|
|
setDirty();
|
|
}
|
|
|
|
void MainWindow::onMenuEditMirrorY(wxCommandEvent &event) { // copy top to bottom
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
program->setUndoPoint(ctAll);
|
|
program->mirrorY();
|
|
setDirty();
|
|
}
|
|
|
|
void MainWindow::onMenuEditMirrorXY(wxCommandEvent &event) { // copy bottomleft tp topright
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
program->setUndoPoint(ctAll);
|
|
program->mirrorXY();
|
|
setDirty();
|
|
}
|
|
|
|
void MainWindow::onMenuEditRotatecopyX(wxCommandEvent &event) { // copy left to right, rotated
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
program->setUndoPoint(ctAll);
|
|
program->rotatecopyX();
|
|
setDirty();
|
|
}
|
|
|
|
void MainWindow::onMenuEditRotatecopyY(wxCommandEvent &event) { // copy top to bottom, rotated
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
program->setUndoPoint(ctAll);
|
|
program->rotatecopyY();
|
|
setDirty();
|
|
}
|
|
|
|
void MainWindow::onMenuEditRotatecopyXY(wxCommandEvent &event) { // copy bottomleft to topright, rotated
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
program->setUndoPoint(ctAll);
|
|
program->rotatecopyXY();
|
|
setDirty();
|
|
}
|
|
|
|
void MainWindow::onMenuEditRotatecopyCorner(wxCommandEvent &event) { // copy top left 1/4 to top right 1/4, rotated
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
program->setUndoPoint(ctAll);
|
|
program->rotatecopyCorner();
|
|
setDirty();
|
|
}
|
|
|
|
|
|
void MainWindow::onMenuEditRandomizeHeights(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
while (true) {
|
|
|
|
SimpleDialog simpleDialog;
|
|
simpleDialog.addValue("Initial Reset", boolToStr(randomWithReset), "(1 = true, 0 = false) If set to '0' no height reset is done before calculating");
|
|
simpleDialog.addValue("Min Height", intToStr(randomMinimumHeight), "Lowest random height. example: -300 or below if you want water , 0 if you don't want water.");
|
|
simpleDialog.addValue("Max Height", intToStr(randomMaximumHeight), "Max random height. A good value is 400");
|
|
simpleDialog.addValue("Chance Divider", intToStr(randomChanceDivider), "Defines how often you get a hill or hole default is 30. Bigger number, less hills/holes.");
|
|
simpleDialog.addValue("Smooth Recursions", intToStr(randomRecursions), "Number of recursions cycles to smooth the hills and holes. 0<x<50 default is 3.");
|
|
if (!simpleDialog.show("Randomize Height")) return;
|
|
|
|
try {
|
|
string checkValue = simpleDialog.getValue("Initial Reset");
|
|
if (checkValue != "" && strToInt(checkValue) > 1) {
|
|
randomWithReset = true;
|
|
} else {
|
|
randomWithReset = strToBool(simpleDialog.getValue("Initial Reset"));
|
|
}
|
|
randomMinimumHeight = strToInt(simpleDialog.getValue("Min Height"));
|
|
randomMaximumHeight = strToInt(simpleDialog.getValue("Max Height"));
|
|
randomChanceDivider = strToInt(simpleDialog.getValue("Chance Divider"));
|
|
randomRecursions = strToInt(simpleDialog.getValue("Smooth Recursions"));
|
|
|
|
// set insane inputs to something that does not crash
|
|
if (randomMinimumHeight >= randomMaximumHeight) randomMinimumHeight = randomMaximumHeight - 1;
|
|
if (randomChanceDivider < 1) randomChanceDivider = 1;
|
|
|
|
// set randomRecursions to something useful
|
|
if (randomRecursions < 0) randomRecursions = 0;
|
|
if (randomRecursions > 50) randomRecursions = 50;
|
|
|
|
program->setUndoPoint(ctAll);
|
|
program->randomizeMapHeights(randomWithReset, randomMinimumHeight, randomMaximumHeight,
|
|
randomChanceDivider, randomRecursions);
|
|
} catch (const exception &e) {
|
|
MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal();
|
|
}
|
|
setDirty();
|
|
}
|
|
}
|
|
|
|
void MainWindow::onMenuEditRandomize(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
program->setUndoPoint(ctAll);
|
|
program->randomizeFactions();
|
|
setDirty();
|
|
}
|
|
|
|
void MainWindow::onMenuEditSwitchSurfaces(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
SimpleDialog simpleDialog;
|
|
simpleDialog.addValue("Surface1", "1", "replace this surface with...");
|
|
simpleDialog.addValue("Surface2", "2", "...this and vice versa");
|
|
if (!simpleDialog.show("Switch surfaces")) return;
|
|
|
|
try {
|
|
program->setUndoPoint(ctSurface);
|
|
program->switchMapSurfaces(
|
|
strToInt(simpleDialog.getValue("Surface1")),
|
|
strToInt(simpleDialog.getValue("Surface2")));
|
|
} catch (const exception &e) {
|
|
MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal();
|
|
}
|
|
setDirty();
|
|
}
|
|
|
|
void MainWindow::onMenuEditInfo(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
SimpleDialog simpleDialog;
|
|
simpleDialog.addValue("Title", program->getMap()->getTitle());
|
|
simpleDialog.addValue("Description", program->getMap()->getDesc());
|
|
simpleDialog.addValue("Author", program->getMap()->getAuthor());
|
|
if (!simpleDialog.show("Info", true)) return;
|
|
|
|
bool ischanged = program->setMapTitle(simpleDialog.getValue("Title"));
|
|
ischanged = (program->setMapDesc(simpleDialog.getValue("Description")) || ischanged);
|
|
ischanged = (program->setMapAuthor(simpleDialog.getValue("Author")) || ischanged);
|
|
if (ischanged)
|
|
if (!isDirty()) {
|
|
setDirty(true);
|
|
}
|
|
|
|
}
|
|
|
|
void MainWindow::onMenuEditAdvanced(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
SimpleDialog simpleDialog;
|
|
simpleDialog.addValue("Height Factor", intToStr(program->getMap()->getHeightFactor()), "lower means more hill effect. Numbers above 100 are handled like this:\nx=x/100 ,so a 150 will mean 1.5 in the game.");
|
|
simpleDialog.addValue("Water Level", intToStr(program->getMap()->getWaterLevel()), "water is visible below this, and walkable until 1.5 less");
|
|
simpleDialog.addValue("Cliff Level", intToStr(program->getMap()->getCliffLevel()), "neighboring fields with at least this heights difference are cliffs");
|
|
simpleDialog.addValue("Camera Height", intToStr(program->getMap()->getCameraHeight()), "you can give a camera height here default is 0 ;ignored if <20");
|
|
if (!simpleDialog.show("Advanced")) return;
|
|
|
|
try {
|
|
program->setMapAdvanced(
|
|
strToInt(simpleDialog.getValue("Height Factor")),
|
|
strToInt(simpleDialog.getValue("Water Level")),
|
|
strToInt(simpleDialog.getValue("Cliff Level")),
|
|
strToInt(simpleDialog.getValue("Camera Height")));
|
|
} catch (const exception &e) {
|
|
MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal();
|
|
}
|
|
setDirty();
|
|
}
|
|
|
|
void MainWindow::onMenuViewResetZoomAndPos(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
program->resetOfset();
|
|
wxPaintEvent e;
|
|
onPaint(e);
|
|
}
|
|
|
|
void MainWindow::onMenuViewGrid(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
menuView->Check(miViewGrid, program->setGridOnOff()); // miViewGrid event.GetId()
|
|
wxPaintEvent e;
|
|
onPaint(e);
|
|
}
|
|
|
|
|
|
void MainWindow::onMenuViewHeightMap(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
menuView->Check(miViewHeightMap, program->setHeightMapOnOff()); // miViewGrid event.GetId()
|
|
wxPaintEvent e;
|
|
onPaint(e);
|
|
}
|
|
void MainWindow::onMenuHideWater(wxCommandEvent &event) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
menuView->Check(miHideWater, program->setHideWaterOnOff()); // miViewGrid event.GetId()
|
|
wxPaintEvent e;
|
|
onPaint(e);
|
|
}
|
|
void MainWindow::onMenuViewAbout(wxCommandEvent &event) {
|
|
MsgDialog(
|
|
this,
|
|
wxT("\n ZetaGlest Map Editor\n Copyright 2004-2010 The Glest Team\n Copyright 2010-2018 The MegaGlest Team \n"),
|
|
wxT("About")).ShowModal();
|
|
}
|
|
|
|
void MainWindow::onMenuViewHelp(wxCommandEvent &event) {
|
|
MsgDialog(this,
|
|
wxT("Draw with left mouse\nMove viewport with right mouse drag\nZoom with center mouse drag, or mousewheel\n\n\
|
|
You can change brush in the same category with key 1-9\n\
|
|
and change category with their first letter (keys S, R, O, G, H)\n\
|
|
Press Space to set brush to the resource or object under the mouse cursor\n\
|
|
To center things in the map shift it with Shift-Up/Down/Left/Right keys\n\
|
|
Height tool (blue) builds with integer height steps 0-20, \nwhile Gradient tool (red) uses any real number \n\
|
|
Units can go over water as long as it is less than 1.5 deep\n\n\
|
|
A good idea is to put some stone, gold and tree near starting position\n\
|
|
Starting position needs an open area for the tower and the starting units\n"),
|
|
wxT("Help")).ShowModal();
|
|
/* 5 away and 10x10 empty area? */
|
|
}
|
|
|
|
void MainWindow::onMenuBrushHeight(wxCommandEvent &e) {
|
|
uncheckBrush();
|
|
menuBrushHeight->Check(e.GetId(), true);
|
|
height = e.GetId() - miBrushHeight - heightCount / 2 - 1;
|
|
enabledGroup = ctHeight;
|
|
currentBrush = btHeight;
|
|
SetStatusText(wxT("Brush: Height"), siBRUSH_TYPE);
|
|
SetStatusText(wxT("Value: ") + ToUnicode(intToStr(height)), siBRUSH_VALUE);
|
|
}
|
|
|
|
void MainWindow::onMenuBrushGradient(wxCommandEvent &e) {
|
|
uncheckBrush();
|
|
menuBrushGradient->Check(e.GetId(), true);
|
|
height = e.GetId() - miBrushGradient - heightCount / 2 - 1;
|
|
enabledGroup = ctGradient;
|
|
currentBrush = btGradient;
|
|
SetStatusText(wxT("Brush: Gradient"), siBRUSH_TYPE);
|
|
SetStatusText(wxT("Value: ") + ToUnicode(intToStr(height)), siBRUSH_VALUE);
|
|
}
|
|
|
|
|
|
void MainWindow::onMenuBrushSurface(wxCommandEvent &e) {
|
|
uncheckBrush();
|
|
menuBrushSurface->Check(e.GetId(), true);
|
|
surface = e.GetId() - miBrushSurface;
|
|
enabledGroup = ctSurface;
|
|
currentBrush = btSurface;
|
|
SetStatusText(wxT("Brush: Surface"), siBRUSH_TYPE);
|
|
SetStatusText(
|
|
wxT("Value: ") + ToUnicode(intToStr(surface)) + wxT(" ")
|
|
+ ToUnicode(surface_descs[surface - 1]), siBRUSH_VALUE);
|
|
}
|
|
|
|
void MainWindow::onMenuBrushObject(wxCommandEvent &e) {
|
|
uncheckBrush();
|
|
menuBrushObject->Check(e.GetId(), true);
|
|
object = e.GetId() - miBrushObject - 1;
|
|
enabledGroup = ctObject;
|
|
currentBrush = btObject;
|
|
SetStatusText(wxT("Brush: Object"), siBRUSH_TYPE);
|
|
SetStatusText(
|
|
wxT("Value: ") + ToUnicode(intToStr(object)) + wxT(" ")
|
|
+ ToUnicode(object_descs[object]), siBRUSH_VALUE);
|
|
}
|
|
|
|
void MainWindow::onMenuBrushResource(wxCommandEvent &e) {
|
|
uncheckBrush();
|
|
menuBrushResource->Check(e.GetId(), true);
|
|
resource = e.GetId() - miBrushResource - 1;
|
|
enabledGroup = ctResource;
|
|
currentBrush = btResource;
|
|
SetStatusText(wxT("Brush: Resource"), siBRUSH_TYPE);
|
|
SetStatusText(
|
|
wxT("Value: ") + ToUnicode(intToStr(resource)) + wxT(" ")
|
|
+ ToUnicode(resource_descs[resource]), siBRUSH_VALUE);
|
|
}
|
|
|
|
void MainWindow::onMenuBrushStartLocation(wxCommandEvent &e) {
|
|
uncheckBrush();
|
|
menuBrushStartLocation->Check(e.GetId(), true);
|
|
startLocation = e.GetId() - miBrushStartLocation;
|
|
enabledGroup = ctLocation;
|
|
currentBrush = btStartLocation;
|
|
SetStatusText(wxT("Brush: Start Locations"), siBRUSH_TYPE);
|
|
SetStatusText(wxT("Value: ") + ToUnicode(intToStr(startLocation)), siBRUSH_VALUE);
|
|
}
|
|
|
|
void MainWindow::onMenuRadius(wxCommandEvent &e) {
|
|
uncheckRadius();
|
|
menuRadius->Check(e.GetId(), true);
|
|
radius = e.GetId() - miRadius;
|
|
SetStatusText(wxT("Radius: ") + ToUnicode(intToStr(radius)), siBRUSH_RADIUS);
|
|
}
|
|
|
|
void MainWindow::change(int x, int y) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
switch (enabledGroup) {
|
|
case ctHeight:
|
|
program->glestChangeMapHeight(x, y, height, radius);
|
|
break;
|
|
case ctSurface:
|
|
program->changeMapSurface(x, y, surface, radius);
|
|
break;
|
|
case ctObject:
|
|
program->changeMapObject(x, y, object, radius);
|
|
break;
|
|
case ctResource:
|
|
program->changeMapResource(x, y, resource, radius);
|
|
break;
|
|
case ctLocation:
|
|
program->changeStartLocation(x, y, startLocation - 1);
|
|
break;
|
|
case ctGradient:
|
|
program->pirateChangeMapHeight(x, y, height, radius);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void MainWindow::uncheckBrush() {
|
|
for (int i = 0; i < heightCount; ++i) {
|
|
menuBrushHeight->Check(miBrushHeight + i + 1, false);
|
|
}
|
|
for (int i = 0; i < heightCount; ++i) {
|
|
menuBrushGradient->Check(miBrushGradient + i + 1, false);
|
|
}
|
|
for (int i = 0; i < surfaceCount; ++i) {
|
|
menuBrushSurface->Check(miBrushSurface + i + 1, false);
|
|
}
|
|
for (int i = 0; i < objectCount; ++i) {
|
|
menuBrushObject->Check(miBrushObject + i + 1, false);
|
|
}
|
|
for (int i = 0; i < resourceCount; ++i) {
|
|
menuBrushResource->Check(miBrushResource + i + 1, false);
|
|
}
|
|
for (int i = 0; i < startLocationCount; ++i) {
|
|
menuBrushStartLocation->Check(miBrushStartLocation + i + 1, false);
|
|
}
|
|
}
|
|
|
|
void MainWindow::uncheckRadius() {
|
|
for (int i = 1; i <= radiusCount; ++i) {
|
|
menuRadius->Check(miRadius + i, false);
|
|
}
|
|
}
|
|
|
|
void MainWindow::onKeyDown(wxKeyEvent &e) {
|
|
if (program == NULL) {
|
|
return;
|
|
}
|
|
|
|
if (e.GetModifiers() == wxMOD_CONTROL || e.GetModifiers() == wxMOD_ALT) {
|
|
e.Skip();
|
|
}
|
|
// WARNING: don't add any Ctrl or ALt key shortcuts below those are reserved for internal menu use.
|
|
|
|
if (currentBrush == btSurface) { // surface texture
|
|
if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '5') {
|
|
surface = e.GetKeyCode() - 48; // '1'-'5' == 1-5
|
|
wxCommandEvent evt(wxEVT_NULL, miBrushSurface + surface);
|
|
onMenuBrushSurface(evt);
|
|
return;
|
|
}
|
|
}
|
|
if (currentBrush == btObject) {
|
|
bool valid = true;
|
|
if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '9') {
|
|
object = e.GetKeyCode() - 48; // '1'-'9' == 1-9
|
|
} else if (e.GetKeyCode() == '0') { // '0' == 10
|
|
object = 10;
|
|
} else if (e.GetKeyCode() == '-') { // '-' == 0
|
|
object = 0;
|
|
} else {
|
|
valid = false;
|
|
}
|
|
if (valid) {
|
|
wxCommandEvent evt(wxEVT_NULL, miBrushObject + object + 1);
|
|
onMenuBrushObject(evt);
|
|
return;
|
|
}
|
|
}
|
|
if (currentBrush == btResource) {
|
|
if (e.GetKeyCode() >= '0' && e.GetKeyCode() <= '5') {
|
|
resource = e.GetKeyCode() - 48; // '0'-'5' == 0-5
|
|
wxCommandEvent evt(wxEVT_NULL, miBrushResource + resource + 1);
|
|
onMenuBrushResource(evt);
|
|
return;
|
|
}
|
|
}
|
|
if (currentBrush == btStartLocation) {
|
|
if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '8') {
|
|
startLocation = e.GetKeyCode() - 48; // '1'-'8' == 0-7
|
|
wxCommandEvent evt(wxEVT_NULL, miBrushStartLocation + startLocation);
|
|
onMenuBrushStartLocation(evt);
|
|
return;
|
|
}
|
|
}
|
|
if (e.GetKeyCode() == 'H') {
|
|
wxCommandEvent evt(wxEVT_NULL, miBrushHeight + height + heightCount / 2 + 1);
|
|
onMenuBrushHeight(evt);
|
|
} else if (e.GetKeyCode() == ' ') {
|
|
if (resourceUnderMouse != 0) {
|
|
wxCommandEvent evt(wxEVT_NULL, miBrushResource + resourceUnderMouse + 1);
|
|
onMenuBrushResource(evt);
|
|
} else {
|
|
wxCommandEvent evt(wxEVT_NULL, miBrushObject + objectUnderMouse + 1);
|
|
onMenuBrushObject(evt);
|
|
}
|
|
} else if (e.GetKeyCode() == 'G') {
|
|
wxCommandEvent evt(wxEVT_NULL, miBrushGradient + height + heightCount / 2 + 1);
|
|
onMenuBrushGradient(evt);
|
|
} else if (e.GetKeyCode() == 'S') {
|
|
wxCommandEvent evt(wxEVT_NULL, miBrushSurface + surface);
|
|
onMenuBrushSurface(evt);
|
|
} else if (e.GetKeyCode() == 'O') {
|
|
wxCommandEvent evt(wxEVT_NULL, miBrushObject + object + 1);
|
|
onMenuBrushObject(evt);
|
|
} else if (e.GetKeyCode() == 'R') {
|
|
wxCommandEvent evt(wxEVT_NULL, miBrushResource + resource + 1);
|
|
onMenuBrushResource(evt);
|
|
} else if (e.GetKeyCode() == 'L') {
|
|
wxCommandEvent evt(wxEVT_NULL, miBrushStartLocation + startLocation + 1);
|
|
onMenuBrushStartLocation(evt);
|
|
} else if (e.GetKeyCode() == WXK_LEFT && e.GetModifiers() == wxMOD_SHIFT) { // shift-left/right/up/down to shift the map one square
|
|
program->setUndoPoint(ctAll);
|
|
program->shiftLeft();
|
|
setDirty();
|
|
} else if (e.GetKeyCode() == WXK_RIGHT && e.GetModifiers() == wxMOD_SHIFT) {
|
|
program->setUndoPoint(ctAll);
|
|
program->shiftRight();
|
|
setDirty();
|
|
} else if (e.GetKeyCode() == WXK_UP && e.GetModifiers() == wxMOD_SHIFT) {
|
|
program->setUndoPoint(ctAll);
|
|
program->shiftUp();
|
|
setDirty();
|
|
} else if (e.GetKeyCode() == WXK_DOWN && e.GetModifiers() == wxMOD_SHIFT) {
|
|
program->setUndoPoint(ctAll);
|
|
program->shiftDown();
|
|
setDirty();
|
|
} else {
|
|
e.Skip();
|
|
}
|
|
}
|
|
|
|
BEGIN_EVENT_TABLE(MainWindow, wxFrame)
|
|
|
|
EVT_CLOSE(MainWindow::onClose)
|
|
|
|
// these are 'handled' by GlCanvas and funneled to these handlers. See BEGIN_EVENT_TABLE(GlCanvas, wxGLCanvas) below.
|
|
//EVT_LEFT_DOWN(MainWindow::onMouseDown)
|
|
//EVT_MOTION(MainWindow::onMouseMove)
|
|
//EVT_KEY_DOWN(MainWindow::onKeyDown)
|
|
|
|
EVT_MENU(wxID_NEW, MainWindow::onMenuEditReset)
|
|
EVT_MENU(wxID_OPEN, MainWindow::onMenuFileLoad)
|
|
EVT_MENU(wxID_SAVE, MainWindow::onMenuFileSave)
|
|
EVT_MENU(wxID_SAVEAS, MainWindow::onMenuFileSaveAs)
|
|
EVT_MENU(wxID_EXIT, MainWindow::onMenuFileExit)
|
|
|
|
EVT_MENU(miEditUndo, MainWindow::onMenuEditUndo)
|
|
EVT_MENU(miEditRedo, MainWindow::onMenuEditRedo)
|
|
EVT_MENU(miEditResetPlayers, MainWindow::onMenuEditResetPlayers)
|
|
EVT_MENU(miEditResize, MainWindow::onMenuEditResize)
|
|
EVT_MENU(miEditFlipDiagonal, MainWindow::onMenuEditFlipDiagonal)
|
|
EVT_MENU(miEditFlipX, MainWindow::onMenuEditFlipX)
|
|
EVT_MENU(miEditFlipY, MainWindow::onMenuEditFlipY)
|
|
|
|
EVT_MENU(miEditMirrorX, MainWindow::onMenuEditMirrorX)
|
|
EVT_MENU(miEditMirrorY, MainWindow::onMenuEditMirrorY)
|
|
EVT_MENU(miEditMirrorXY, MainWindow::onMenuEditMirrorXY)
|
|
EVT_MENU(miEditRotatecopyX, MainWindow::onMenuEditRotatecopyX)
|
|
EVT_MENU(miEditRotatecopyY, MainWindow::onMenuEditRotatecopyY)
|
|
EVT_MENU(miEditRotatecopyXY, MainWindow::onMenuEditRotatecopyXY)
|
|
EVT_MENU(miEditRotatecopyCorner, MainWindow::onMenuEditRotatecopyCorner)
|
|
|
|
EVT_MENU(miEditRandomizeHeights, MainWindow::onMenuEditRandomizeHeights)
|
|
EVT_MENU(miEditRandomize, MainWindow::onMenuEditRandomize)
|
|
EVT_MENU(miEditSwitchSurfaces, MainWindow::onMenuEditSwitchSurfaces)
|
|
EVT_MENU(miEditInfo, MainWindow::onMenuEditInfo)
|
|
EVT_MENU(miEditAdvanced, MainWindow::onMenuEditAdvanced)
|
|
|
|
EVT_MENU(miViewResetZoomAndPos, MainWindow::onMenuViewResetZoomAndPos)
|
|
EVT_MENU(miViewGrid, MainWindow::onMenuViewGrid)
|
|
EVT_MENU(miViewHeightMap, MainWindow::onMenuViewHeightMap)
|
|
EVT_MENU(miHideWater, MainWindow::onMenuHideWater)
|
|
EVT_MENU(miViewAbout, MainWindow::onMenuViewAbout)
|
|
EVT_MENU(miViewHelp, MainWindow::onMenuViewHelp)
|
|
|
|
EVT_MENU_RANGE(miBrushHeight + 1, miBrushHeight + heightCount, MainWindow::onMenuBrushHeight)
|
|
EVT_MENU_RANGE(miBrushGradient + 1, miBrushGradient + heightCount, MainWindow::onMenuBrushGradient)
|
|
EVT_MENU_RANGE(miBrushSurface + 1, miBrushSurface + surfaceCount, MainWindow::onMenuBrushSurface)
|
|
EVT_MENU_RANGE(miBrushObject + 1, miBrushObject + objectCount, MainWindow::onMenuBrushObject)
|
|
EVT_MENU_RANGE(miBrushResource + 1, miBrushResource + resourceCount, MainWindow::onMenuBrushResource)
|
|
EVT_MENU_RANGE(miBrushStartLocation + 1, miBrushStartLocation + startLocationCount, MainWindow::onMenuBrushStartLocation)
|
|
EVT_MENU_RANGE(miRadius, miRadius + radiusCount, MainWindow::onMenuRadius)
|
|
|
|
EVT_PAINT(MainWindow::onPaint)
|
|
|
|
EVT_TOOL(toolPlayer, MainWindow::onToolPlayer)
|
|
END_EVENT_TABLE()
|
|
|
|
// =====================================================
|
|
// class GlCanvas
|
|
// =====================================================
|
|
|
|
GlCanvas::GlCanvas(MainWindow *mainWindow, wxWindow *parent, int *args)
|
|
#if wxCHECK_VERSION(2, 9, 1)
|
|
: wxGLCanvas(parent, -1, args, wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas")) {
|
|
this->context = new wxGLContext(this);
|
|
#else
|
|
: wxGLCanvas(parent, -1, wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas"), args) {
|
|
this->context = NULL;
|
|
#endif
|
|
|
|
this->mainWindow = mainWindow;
|
|
}
|
|
|
|
GlCanvas::~GlCanvas() {
|
|
delete this->context;
|
|
this->context = NULL;
|
|
}
|
|
|
|
void GlCanvas::setCurrentGLContext() {
|
|
#ifndef __APPLE__
|
|
|
|
#if wxCHECK_VERSION(2, 9, 1)
|
|
if (this->context == NULL) {
|
|
this->context = new wxGLContext(this);
|
|
}
|
|
#endif
|
|
|
|
if (this->context) {
|
|
this->SetCurrent(*this->context);
|
|
}
|
|
#else
|
|
this->SetCurrent();
|
|
#endif
|
|
}
|
|
|
|
void translateCoords(wxWindow *wnd, int &x, int &y) {
|
|
/*
|
|
#ifdef WIN32
|
|
int cx, cy;
|
|
wnd->GetPosition(&cx, &cy);
|
|
x += cx;
|
|
y += cy;
|
|
#endif
|
|
*/
|
|
}
|
|
|
|
// for the mousewheel
|
|
void GlCanvas::onMouseWheel(wxMouseEvent &event) {
|
|
if (event.GetWheelRotation() > 0) mainWindow->onMouseWheelDown(event);
|
|
else mainWindow->onMouseWheelUp(event);
|
|
}
|
|
|
|
void GlCanvas::onMouseDown(wxMouseEvent &event) {
|
|
int x, y;
|
|
event.GetPosition(&x, &y);
|
|
translateCoords(this, x, y);
|
|
mainWindow->onMouseDown(event, x, y);
|
|
}
|
|
|
|
void GlCanvas::onMouseMove(wxMouseEvent &event) {
|
|
int x, y;
|
|
event.GetPosition(&x, &y);
|
|
translateCoords(this, x, y);
|
|
mainWindow->onMouseMove(event, x, y);
|
|
}
|
|
|
|
void GlCanvas::onKeyDown(wxKeyEvent &event) {
|
|
int x, y;
|
|
event.GetPosition(&x, &y);
|
|
translateCoords(this, x, y);
|
|
mainWindow->onKeyDown(event);
|
|
}
|
|
|
|
void GlCanvas::onPaint(wxPaintEvent &event) {
|
|
// wxPaintDC dc(this); //N "In a paint event handler must always create a wxPaintDC object even if you do not use it. (?)
|
|
// mainWindow->program->renderMap(GetClientSize().x, GetClientSize().y);
|
|
// SwapBuffers();
|
|
// event.Skip();
|
|
//printf("gl onPaint skip map\n");
|
|
mainWindow->onPaint(event);
|
|
}
|
|
|
|
BEGIN_EVENT_TABLE(GlCanvas, wxGLCanvas)
|
|
EVT_KEY_DOWN(GlCanvas::onKeyDown)
|
|
EVT_MOUSEWHEEL(GlCanvas::onMouseWheel)
|
|
EVT_LEFT_DOWN(GlCanvas::onMouseDown)
|
|
EVT_MOTION(GlCanvas::onMouseMove)
|
|
EVT_PAINT(GlCanvas::onPaint) // Because the drawing area needs to be repainted too.
|
|
END_EVENT_TABLE()
|
|
|
|
// ===============================================
|
|
// class SimpleDialog
|
|
// ===============================================
|
|
|
|
void SimpleDialog::addValue(const string &key, const string &value, const string &help) {
|
|
values.push_back(pair<string, string>(key, value + "|" + help)); // I guess I need map<,> instead but I don't know how to do it
|
|
}
|
|
|
|
string SimpleDialog::getValue(const string &key) {
|
|
for (unsigned int i = 0; i < values.size(); ++i) {
|
|
if (values[i].first == key) {
|
|
return values[i].second;
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
bool SimpleDialog::show(const string &title, bool wide) {
|
|
Create(NULL, -1, ToUnicode(title));
|
|
wxSizer *sizer2 = new wxBoxSizer(wxVERTICAL);
|
|
wxSizer *sizer = new wxFlexGridSizer(3);
|
|
|
|
vector<wxTextCtrl*> texts;
|
|
for (Values::iterator it = values.begin(); it != values.end(); ++it) {
|
|
size_t helptextpos = it->second.find_first_of('|');
|
|
sizer->Add(new wxStaticText(this, -1, ToUnicode(it->first)), 0, wxALL, 5);
|
|
wxTextCtrl *text = new wxTextCtrl(this, -1, ToUnicode(it->second.substr(0, helptextpos)));
|
|
if (wide) text->SetMinSize(wxSize((text->GetSize().GetWidth()) * 4, text->GetSize().GetHeight())); // 4 time as wide as default
|
|
sizer->Add(text, 0, wxALL, 5);
|
|
texts.push_back(text);
|
|
sizer->Add(new wxStaticText(this, -1, ToUnicode(it->second.substr(helptextpos + 1))), 0, wxALL, 5);
|
|
}
|
|
sizer2->Add(sizer);
|
|
sizer2->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALIGN_RIGHT); // enable Cancel button
|
|
SetSizerAndFit(sizer2);
|
|
|
|
ShowModal();
|
|
if (m_returnCode == wxID_CANCEL) return false; // don't change values if canceled
|
|
|
|
for (unsigned int i = 0; i < texts.size(); ++i) {
|
|
#ifdef WIN32
|
|
const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(texts[i]->GetValue()));
|
|
values[i].second = tmp_buf;
|
|
#else
|
|
values[i].second = texts[i]->GetValue().ToAscii();
|
|
#endif
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
// ===============================================
|
|
// class App
|
|
// ===============================================
|
|
|
|
bool App::OnInit() {
|
|
SystemFlags::VERBOSE_MODE_ENABLED = false;
|
|
SystemFlags::ENABLE_THREADED_LOGGING = false;
|
|
|
|
string fileparam;
|
|
if (argc == 2) {
|
|
if (argv[1][0] == '-') { // any flag gives help and exits program.
|
|
std::cout << std::endl << "ZetaGlest map editor " << mapeditorVersionString << " [Using " << (const char *) wxConvCurrent->cWX2MB(wxVERSION_STRING) << "]" << std::endl << std::endl;
|
|
//std::cout << "\nglest_map_editor [MGM FILE]" << std::endl << std::endl;
|
|
std::cout << "Creates or edits zetaglest/glest maps. [.mgm/.gbm]" << std::endl << std::endl;
|
|
std::cout << "Draw with left mouse button." << std::endl;
|
|
std::cout << "Move map with right mouse button." << std::endl;
|
|
std::cout << "Zoom with middle mouse button or mousewheel." << std::endl;
|
|
|
|
// std::cout << " ~ more helps should be written here ~" << std::endl;
|
|
std::cout << std::endl;
|
|
exit(0);
|
|
}
|
|
//#if defined(__MINGW32__)
|
|
#if wxCHECK_VERSION(2, 9, 1)
|
|
fileparam = argv[1].ToStdString();
|
|
#else
|
|
const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(argv[1]);
|
|
fileparam = tmp_buf;
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
auto_ptr<wchar_t> wstr(Ansi2WideString(fileparam.c_str()));
|
|
fileparam = utf8_encode(wstr.get());
|
|
#endif
|
|
|
|
//#else
|
|
// fileparam = wxFNCONV(argv[1]);
|
|
//#endif
|
|
}
|
|
|
|
#if defined(wxMAJOR_VERSION) && defined(wxMINOR_VERSION) && defined(wxRELEASE_NUMBER) && defined(wxSUBRELEASE_NUMBER)
|
|
printf("Using wxWidgets version [%d.%d.%d.%d]\n", wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER, wxSUBRELEASE_NUMBER);
|
|
#endif
|
|
|
|
wxString exe_path = wxStandardPaths::Get().GetExecutablePath();
|
|
//wxString path_separator = wxFileName::GetPathSeparator();
|
|
//exe_path = exe_path.BeforeLast(path_separator[0]);
|
|
//exe_path += path_separator;
|
|
|
|
string appPath;
|
|
//#if defined(__MINGW32__)
|
|
|
|
#ifdef WIN32
|
|
const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(exe_path));
|
|
appPath = tmp_buf;
|
|
|
|
auto_ptr<wchar_t> wstr(Ansi2WideString(appPath.c_str()));
|
|
appPath = utf8_encode(wstr.get());
|
|
#elif wxCHECK_VERSION(2, 9, 1)
|
|
appPath = exe_path.ToStdString();
|
|
#else
|
|
appPath = wxFNCONV(exe_path);
|
|
#endif
|
|
|
|
//#else
|
|
// const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(exe_path));
|
|
// appPath = tmp_buf;
|
|
//#endif
|
|
|
|
mainWindow = new MainWindow(appPath);
|
|
mainWindow->Show();
|
|
mainWindow->init(fileparam);
|
|
mainWindow->Update();
|
|
|
|
#ifdef WIN32
|
|
wxPoint pos = mainWindow->GetScreenPosition();
|
|
wxSize size = mainWindow->GetSize();
|
|
|
|
mainWindow->SetSize(pos.x, pos.y, 1, 1, wxSIZE_FORCE);
|
|
//mainWindow->Update();
|
|
|
|
mainWindow->SetSize(pos.x, pos.y, size.x - 1, size.y, wxSIZE_FORCE);
|
|
mainWindow->Update();
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
int App::MainLoop() {
|
|
try {
|
|
//throw megaglest_runtime_error("test");
|
|
return wxApp::MainLoop();
|
|
} catch (const exception &e) {
|
|
MsgDialog(NULL, ToUnicode(e.what()), wxT("Exception")).ShowModal();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int App::OnExit() {
|
|
SystemFlags::Close();
|
|
SystemFlags::SHUTDOWN_PROGRAM_MODE = true;
|
|
|
|
return 0;
|
|
}
|
|
|
|
MsgDialog::MsgDialog(wxWindow *parent,
|
|
const wxString& message,
|
|
const wxString& caption,
|
|
long style,
|
|
const wxPoint& pos) {
|
|
|
|
m_sizerText = NULL;
|
|
if (!wxDialog::Create(parent, wxID_ANY, caption,
|
|
pos, wxDefaultSize,
|
|
style)) {
|
|
return;
|
|
}
|
|
m_sizerText = new wxBoxSizer(wxVERTICAL);
|
|
wxStaticText *label = new wxStaticText(this, wxID_ANY, message);
|
|
wxFont font(*wxNORMAL_FONT);
|
|
font.SetPointSize(font.GetPointSize());
|
|
font.SetWeight(wxFONTWEIGHT_NORMAL);
|
|
label->SetFont(font);
|
|
|
|
m_sizerText->Add(label, wxSizerFlags().Centre().Border());
|
|
|
|
wxSizer *sizerIconAndText = new wxBoxSizer(wxHORIZONTAL);
|
|
sizerIconAndText->Add(m_sizerText, wxSizerFlags(1).Expand());
|
|
|
|
wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
|
|
sizerTop->Add(sizerIconAndText, wxSizerFlags(1).Expand().Border());
|
|
|
|
wxSizer *sizerBtns = CreateButtonSizer(wxOK);
|
|
if (sizerBtns) {
|
|
sizerTop->Add(sizerBtns, wxSizerFlags().Expand().Border());
|
|
}
|
|
|
|
SetSizerAndFit(sizerTop);
|
|
CentreOnScreen();
|
|
}
|
|
MsgDialog::~MsgDialog() {
|
|
|
|
}
|
|
|
|
}// end namespace
|
|
|
|
IMPLEMENT_APP(MapEditor::App)
|