mirror of
https://github.com/glest/glest-source.git
synced 2025-02-24 19:52:25 +01:00
1445 lines
48 KiB
C++
Executable File
1445 lines
48 KiB
C++
Executable File
// ==============================================================
|
||
// This file is part of Glest (www.glest.org)
|
||
//
|
||
// Copyright (C) 2001-2008 Marti<74>o Figueroa
|
||
//
|
||
// You can redistribute this code and/or modify it under
|
||
// the terms of the GNU General Public License as published
|
||
// by the Free Software Foundation; either version 2 of the
|
||
// License, or (at your option) any later version
|
||
// ==============================================================
|
||
|
||
#include "main.h"
|
||
#include <ctime>
|
||
#include "conversion.h"
|
||
#include "icons.h"
|
||
#include "platform_common.h"
|
||
#include <iostream>
|
||
|
||
using namespace Shared::Util;
|
||
using namespace Shared::PlatformCommon;
|
||
using namespace std;
|
||
|
||
namespace MapEditor {
|
||
|
||
|
||
|
||
const string mapeditorVersionString = "v1.5.1";
|
||
const string MainWindow::winHeader = "MegaGlest 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()
|
||
: wxFrame(NULL, -1, ToUnicode(winHeader), wxPoint(0,0), wxSize(1024, 768))
|
||
, lastX(0), lastY(0)
|
||
, currentBrush(btHeight)
|
||
, height(0)
|
||
, surface(1)
|
||
, radius(1)
|
||
, object(0)
|
||
, resource(0)
|
||
, startLocation(1)
|
||
, enabledGroup(ctHeight)
|
||
, fileModified(false)
|
||
, menuBar(NULL)
|
||
, panel(NULL)
|
||
, glCanvas(NULL)
|
||
, program(NULL), boxsizer(NULL), startupSettingsInited(false) {
|
||
|
||
this->panel = new wxPanel(this, wxID_ANY);
|
||
|
||
//gl canvas
|
||
int args[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_MIN_ALPHA, 8 };
|
||
glCanvas = new GlCanvas(this, this->panel, args);
|
||
glCanvas->SetFocus();
|
||
}
|
||
|
||
void MainWindow::onToolPlayer(wxCommandEvent& event){
|
||
PopupMenu(menuBrushStartLocation);
|
||
}
|
||
|
||
void MainWindow::init(string fname) {
|
||
#if wxCHECK_VERSION(2, 9, 1)
|
||
|
||
#else
|
||
glCanvas->SetCurrent();
|
||
#endif
|
||
|
||
//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(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 Heights/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->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
|
||
-2, // File name
|
||
-1, // File type
|
||
-2, // Current Object
|
||
-2, // Brush Type
|
||
-2, // Brush 'Value'
|
||
-1, // Brush Radius
|
||
};
|
||
CreateStatusBar(siCOUNT);
|
||
GetStatusBar()->SetStatusWidths(siCOUNT, status_widths);
|
||
|
||
SetStatusText(wxT("File: ") + ToUnicode(fileName), siFILE_NAME);
|
||
SetStatusText(wxT(".gbm"), 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);
|
||
|
||
wxToolBar *toolbar = new wxToolBar(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 wxToolBar(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();
|
||
|
||
//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;
|
||
std::ifstream testFile("editor.ico");
|
||
if(testFile.good()) {
|
||
testFile.close();
|
||
icon.LoadFile(wxT("editor.ico"),wxBITMAP_TYPE_ICO);
|
||
}
|
||
#endif
|
||
//std::cout << "C" << std::endl;
|
||
SetIcon(icon);
|
||
fileDialog = new wxFileDialog(this);
|
||
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";
|
||
if (!fname.empty() && fileExists(fname)) {
|
||
//program->loadMap(fname);
|
||
currentFile = fname;
|
||
fileName = cutLastExt(extractFileFromDirectoryPath(fname.c_str()));
|
||
fileDialog->SetPath(ToUnicode(fname));
|
||
}
|
||
SetTitle(ToUnicode(currentFile + " - " + winHeader));
|
||
//setDirty(false);
|
||
//setExtension();
|
||
}
|
||
|
||
void MainWindow::onClose(wxCloseEvent &event) {
|
||
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 this;
|
||
}
|
||
|
||
void MainWindow::setupStartupSettings() {
|
||
program = new Program(glCanvas->GetClientSize().x, glCanvas->GetClientSize().y);
|
||
|
||
fileName = "New (unsaved) Map";
|
||
if (!currentFile.empty() && fileExists(currentFile)) {
|
||
program->loadMap(currentFile);
|
||
//currentFile = fname;
|
||
fileName = cutLastExt(extractFileFromDirectoryPath(currentFile.c_str()));
|
||
fileDialog->SetPath(ToUnicode(currentFile));
|
||
}
|
||
SetTitle(ToUnicode(currentFile + " - " + winHeader));
|
||
setDirty(false);
|
||
setExtension();
|
||
}
|
||
|
||
MainWindow::~MainWindow() {
|
||
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);
|
||
if (extnsn == "gbm" || extnsn == "mgm") {
|
||
currentFile = cutLastExt(currentFile);
|
||
}
|
||
if (Program::getMap()->getMaxFactions() <= 4) {
|
||
SetStatusText(wxT(".gbm"), siFILE_TYPE);
|
||
currentFile += ".gbm";
|
||
} else {
|
||
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;
|
||
int dif;
|
||
if (event.LeftIsDown()) {
|
||
change(x, y);
|
||
repaint = true;
|
||
} else if (event.MiddleIsDown()) {
|
||
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;
|
||
}
|
||
}
|
||
lastX = x;
|
||
lastY = y;
|
||
|
||
if (repaint) {
|
||
wxPaintEvent ev;
|
||
onPaint(ev);
|
||
}
|
||
event.Skip();
|
||
}
|
||
|
||
void MainWindow::onPaint(wxPaintEvent &event) {
|
||
if(!IsShown()) {
|
||
event.Skip();
|
||
return;
|
||
}
|
||
|
||
#if wxCHECK_VERSION(2, 9, 1)
|
||
glCanvas->setCurrentGLContext();
|
||
#endif
|
||
|
||
if(startupSettingsInited == false) {
|
||
startupSettingsInited = true;
|
||
setupStartupSettings();
|
||
}
|
||
|
||
if(lastPaintEvent.getMillis() < 30) {
|
||
sleep(1);
|
||
return;
|
||
}
|
||
|
||
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->Update();
|
||
if(menuBar) menuBar->Update();
|
||
|
||
if(program && glCanvas) {
|
||
program->renderMap(glCanvas->GetClientSize().x, glCanvas->GetClientSize().y);
|
||
glCanvas->SwapBuffers();
|
||
}
|
||
event.Skip();
|
||
}
|
||
|
||
void MainWindow::onMenuFileLoad(wxCommandEvent &event) {
|
||
if(program == NULL) {
|
||
return;
|
||
}
|
||
|
||
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) {
|
||
currentFile = fileDialog->GetPath().ToAscii();
|
||
program->loadMap(currentFile);
|
||
fileName = cutLastExt(extractFileFromDirectoryPath(currentFile.c_str()));
|
||
setDirty(false);
|
||
setExtension();
|
||
SetTitle(ToUnicode(winHeader + "; " + currentFile));
|
||
}
|
||
}
|
||
|
||
void MainWindow::onMenuFileSave(wxCommandEvent &event) {
|
||
if(program == NULL) {
|
||
return;
|
||
}
|
||
|
||
if (currentFile.empty()) {
|
||
wxCommandEvent ev;
|
||
onMenuFileSaveAs(ev);
|
||
} else {
|
||
setExtension();
|
||
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("*.gbm|*.mgm"), wxFD_SAVE);
|
||
#else
|
||
wxFileDialog fd(this, wxT("Select file"), wxT(""), wxT(""), wxT("*.gbm|*.mgm"), wxSAVE);
|
||
#endif
|
||
|
||
fd.SetPath(fileDialog->GetPath());
|
||
fd.SetWildcard(wxT("Glest Map (*.gbm)|*.gbm|MegaGlest Map (*.mgm)|*.mgm"));
|
||
if (fd.ShowModal() == wxID_OK) {
|
||
currentFile = fd.GetPath().ToAscii();
|
||
fileDialog->SetPath(fd.GetPath());
|
||
setExtension();
|
||
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";
|
||
}
|
||
|
||
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::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;
|
||
}
|
||
|
||
program->setUndoPoint(ctAll);
|
||
program->randomizeMapHeights();
|
||
setDirty();
|
||
}
|
||
|
||
void MainWindow::onMenuEditRandomize(wxCommandEvent &event) {
|
||
if(program == NULL) {
|
||
return;
|
||
}
|
||
|
||
program->setUndoPoint(ctAll);
|
||
program->randomizeMap();
|
||
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 = false;
|
||
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 map is more more zoomed in)");
|
||
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 heigth 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::onMenuViewAbout(wxCommandEvent &event) {
|
||
MsgDialog(
|
||
this,
|
||
wxT("Glest Map Editor - Copyright 2004 The Glest Team\n(with improvements by others, 2010)."),
|
||
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 (currentBrush == btHeight || currentBrush == btGradient) { // 'height' brush
|
||
if (e.GetKeyCode() >= '0' && e.GetKeyCode() <= '5') {
|
||
height = e.GetKeyCode() - 48; // '0'-'5' == 0-5
|
||
if (e.GetModifiers() == wxMOD_CONTROL) { // Ctrl means negative
|
||
height = -height ;
|
||
}
|
||
int id_offset = heightCount / 2 + height + 1;
|
||
if (currentBrush == btHeight) {
|
||
wxCommandEvent evt(wxEVT_NULL, miBrushHeight + id_offset);
|
||
onMenuBrushHeight(evt);
|
||
} else {
|
||
wxCommandEvent evt(wxEVT_NULL, miBrushGradient + id_offset);
|
||
onMenuBrushGradient(evt);
|
||
}
|
||
return;
|
||
}
|
||
}
|
||
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 if (e.GetKeyCode() == WXK_BACK && e.GetModifiers() == wxMOD_ALT) { // undo
|
||
wxCommandEvent evt(wxEVT_NULL, 0);
|
||
onMenuEditUndo(evt);
|
||
} 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(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(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() {
|
||
if(this->context) {
|
||
this->SetCurrent(*this->context);
|
||
}
|
||
}
|
||
|
||
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();
|
||
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) {
|
||
int 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) {
|
||
values[i].second = texts[i]->GetValue().ToAscii();
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
// ===============================================
|
||
// class App
|
||
// ===============================================
|
||
|
||
bool App::OnInit() {
|
||
string fileparam;
|
||
if(argc==2){
|
||
if(argv[1][0]=='-') { // any flag gives help and exits program.
|
||
std::cout << "MegaGlest map editor " << mapeditorVersionString << " [Using " << (const char *)wxConvCurrent->cWX2MB(wxVERSION_STRING) << "]" << std::endl << std::endl;
|
||
std::cout << "glest_map_editor [GBM OR MGM FILE]" << std::endl << std::endl;
|
||
std::cout << "Creates or edits glest/megaglest maps." << std::endl;
|
||
std::cout << "Draw with left mouse button (select what and how large area in menu or toolbar)" << std::endl;
|
||
std::cout << "Pan trough the 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__)
|
||
const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(argv[1]));
|
||
fileparam = tmp_buf;
|
||
#else
|
||
fileparam = wxFNCONV(argv[1]);
|
||
#endif
|
||
}
|
||
|
||
mainWindow = new MainWindow();
|
||
mainWindow->Show();
|
||
mainWindow->init(fileparam);
|
||
mainWindow->Update();
|
||
|
||
#ifdef WIN32
|
||
wxPoint pos = mainWindow->GetScreenPosition();
|
||
wxSize size = mainWindow->GetSize();
|
||
mainWindow->SetSize(pos.x, pos.y, size.x-1, size.y, wxSIZE_FORCE);
|
||
mainWindow->Update();
|
||
#endif
|
||
|
||
return true;
|
||
}
|
||
|
||
int App::MainLoop() {
|
||
try {
|
||
//throw runtime_error("test");
|
||
return wxApp::MainLoop();
|
||
}
|
||
catch (const exception &e) {
|
||
MsgDialog(NULL, ToUnicode(e.what()), wxT("Exception")).ShowModal();
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int App::OnExit() {
|
||
return 0;
|
||
}
|
||
|
||
MsgDialog::MsgDialog(wxWindow *parent,
|
||
const wxString& message,
|
||
const wxString& caption,
|
||
long style,
|
||
const wxPoint& pos) {
|
||
|
||
m_sizerText = NULL;
|
||
// TODO: should we use main frame as parent by default here?
|
||
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)
|