Editor: Brush preview and Shift-Key for filling brush
Editor needs to render more often for the preview function.
This commit is contained in:
parent
880730e5e1
commit
0201af7ccf
|
@ -105,6 +105,8 @@ MainWindow::MainWindow(string appPath)
|
|||
resourceUnderMouse=0;
|
||||
objectUnderMouse=0;
|
||||
|
||||
shiftModifierKey = false;
|
||||
|
||||
// default values for random height calculation that turned out to be quite useful
|
||||
randomWithReset=true;
|
||||
randomMinimumHeight=-300;
|
||||
|
@ -157,8 +159,8 @@ void MainWindow::init(string fname) {
|
|||
menuBar->Append(menuFile, wxT("&File"));
|
||||
|
||||
//edit
|
||||
menuEdit = new wxMenu();
|
||||
menuEdit->Append(miEditUndo, wxT("&Undo\tCTRL+Z"));
|
||||
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..."));
|
||||
|
@ -313,6 +315,7 @@ void MainWindow::init(string fname) {
|
|||
SetStatusText(wxT(".mgm"), siFILE_TYPE);
|
||||
SetStatusText(wxT("Object: None (Erase)"), siCURR_OBJECT);
|
||||
SetStatusText(wxT("Brush: Height"), siBRUSH_TYPE);
|
||||
SetStatusText(wxT("Type: Overwrite"), siBRUSH_OVERWRITE);
|
||||
SetStatusText(wxT("Value: 0"), siBRUSH_VALUE);
|
||||
SetStatusText(wxT("Radius: 1"), siBRUSH_RADIUS);
|
||||
SetStatusText(wxT("Pos (Ingame): 0"), siPOS_VALUE);
|
||||
|
@ -606,20 +609,18 @@ void MainWindow::onMouseMove(wxMouseEvent &event, int x, int y) {
|
|||
if(program == NULL) {
|
||||
return;
|
||||
}
|
||||
bool repaint = false;
|
||||
mouse_pos.first = program->getCellX(x);
|
||||
mouse_pos.second = program->getCellY(y);
|
||||
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 {
|
||||
} else {
|
||||
int currResource = program->getResource(x, y);
|
||||
if (currResource > 0) {
|
||||
SetStatusText(wxT("Resource: ") + ToUnicode(resource_descs[currResource]), siCURR_OBJECT);
|
||||
|
@ -648,10 +649,9 @@ void MainWindow::onMouseMove(wxMouseEvent &event, int x, int y) {
|
|||
lastX = x;
|
||||
lastY = y;
|
||||
|
||||
if (repaint) {
|
||||
wxPaintEvent ev;
|
||||
onPaint(ev);
|
||||
}
|
||||
wxPaintEvent ev;
|
||||
onPaint(ev);
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
@ -701,8 +701,12 @@ void MainWindow::onPaint(wxPaintEvent &event) {
|
|||
void MainWindow::refreshMapRender() {
|
||||
//printf("refreshMapRender map\n");
|
||||
|
||||
if(program && glCanvas) {
|
||||
program->renderMap(glCanvas->GetClientSize().x, glCanvas->GetClientSize().y);
|
||||
if(program && glCanvas) {
|
||||
if(enabledGroup == ctLocation) {
|
||||
program->renderMap(glCanvas->GetClientSize().x, glCanvas->GetClientSize().y);
|
||||
} else {
|
||||
program->renderMap(glCanvas->GetClientSize().x, glCanvas->GetClientSize().y, &mouse_pos, &radius);
|
||||
}
|
||||
glCanvas->SwapBuffers();
|
||||
}
|
||||
}
|
||||
|
@ -1245,6 +1249,7 @@ void MainWindow::onMenuViewHelp(wxCommandEvent &event) {
|
|||
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\
|
||||
Hold Shift to fill only empty spaces with the current object or resource\ninstead of replacing everything under the brush.\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\
|
||||
|
@ -1341,10 +1346,10 @@ void MainWindow::change(int x, int y) {
|
|||
program->changeMapSurface(x, y, surface, radius);
|
||||
break;
|
||||
case ctObject:
|
||||
program->changeMapObject(x, y, object, radius);
|
||||
program->changeMapObject(x, y, object, radius, !shiftModifierKey);
|
||||
break;
|
||||
case ctResource:
|
||||
program->changeMapResource(x, y, resource, radius);
|
||||
program->changeMapResource(x, y, resource, radius, !shiftModifierKey);
|
||||
break;
|
||||
case ctLocation:
|
||||
program->changeStartLocation(x, y, startLocation - 1);
|
||||
|
@ -1382,7 +1387,7 @@ void MainWindow::uncheckRadius() {
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::onKeyDown(wxKeyEvent &e) {
|
||||
void MainWindow::onKeyDown(wxKeyEvent &e) {
|
||||
if(program == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -1475,11 +1480,29 @@ void MainWindow::uncheckRadius() {
|
|||
program->setUndoPoint(ctAll);
|
||||
program->shiftDown();
|
||||
setDirty();
|
||||
} else {
|
||||
} else if (e.GetModifiers() == wxMOD_SHIFT) {
|
||||
shiftModifierKey = true;
|
||||
SetStatusText(wxT("Type: Fill"), siBRUSH_OVERWRITE);
|
||||
} else {
|
||||
e.Skip();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onKeyUp(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 (e.GetModifiers() != wxMOD_SHIFT) {
|
||||
shiftModifierKey = false;
|
||||
SetStatusText(wxT("Type: Overwrite"), siBRUSH_OVERWRITE);
|
||||
}
|
||||
}
|
||||
|
||||
BEGIN_EVENT_TABLE(MainWindow, wxFrame)
|
||||
|
||||
EVT_CLOSE(MainWindow::onClose)
|
||||
|
@ -1614,6 +1637,11 @@ void GlCanvas::onKeyDown(wxKeyEvent &event) {
|
|||
mainWindow->onKeyDown(event);
|
||||
}
|
||||
|
||||
void GlCanvas::onKeyUp(wxKeyEvent &event) {
|
||||
mainWindow->onKeyUp(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);
|
||||
|
@ -1625,6 +1653,7 @@ void GlCanvas::onPaint(wxPaintEvent &event) {
|
|||
|
||||
BEGIN_EVENT_TABLE(GlCanvas, wxGLCanvas)
|
||||
EVT_KEY_DOWN(GlCanvas::onKeyDown)
|
||||
EVT_KEY_UP(GlCanvas::onKeyUp)
|
||||
EVT_MOUSEWHEEL(GlCanvas::onMouseWheel)
|
||||
EVT_LEFT_DOWN(GlCanvas::onMouseDown)
|
||||
EVT_MOTION(GlCanvas::onMouseMove)
|
||||
|
|
|
@ -51,6 +51,7 @@ enum StatusItems {
|
|||
siFILE_TYPE,
|
||||
siCURR_OBJECT,
|
||||
siBRUSH_TYPE,
|
||||
siBRUSH_OVERWRITE,
|
||||
siBRUSH_VALUE,
|
||||
siBRUSH_RADIUS,
|
||||
siPOS_VALUE,
|
||||
|
@ -197,6 +198,9 @@ private:
|
|||
int startLocation;
|
||||
int resourceUnderMouse;
|
||||
int objectUnderMouse;
|
||||
pair<int,int> mouse_pos;
|
||||
|
||||
bool shiftModifierKey;
|
||||
|
||||
bool randomWithReset;
|
||||
int randomMinimumHeight;
|
||||
|
@ -231,6 +235,7 @@ public:
|
|||
|
||||
void onPaint(wxPaintEvent &event);
|
||||
void onKeyDown(wxKeyEvent &e);
|
||||
void onKeyUp(wxKeyEvent &e);
|
||||
|
||||
void onMenuFileLoad(wxCommandEvent &event);
|
||||
void onMenuFileSave(wxCommandEvent &event);
|
||||
|
@ -308,6 +313,7 @@ public:
|
|||
void onMouseMove(wxMouseEvent &event);
|
||||
void onMouseWheel(wxMouseEvent &event);
|
||||
void onKeyDown(wxKeyEvent &event);
|
||||
void onKeyUp(wxKeyEvent &event);
|
||||
void onPaint(wxPaintEvent &event);
|
||||
|
||||
void setCurrentGLContext();
|
||||
|
|
|
@ -153,6 +153,7 @@ Program::Program(int w, int h, string playerName) {
|
|||
ofsetY = 0;
|
||||
|
||||
map = new MapPreview();
|
||||
|
||||
resetFactions(8);
|
||||
renderer.initMapSurface(w, h);
|
||||
map->setAuthor(playerName);
|
||||
|
@ -217,12 +218,12 @@ void Program::changeMapSurface(int x, int y, int surface, int radius) {
|
|||
if(map) map->changeSurface((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, static_cast<MapSurfaceType>(surface), radius);
|
||||
}
|
||||
|
||||
void Program::changeMapObject(int x, int y, int object, int radius) {
|
||||
if(map) map->changeObject((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, object, radius);
|
||||
void Program::changeMapObject(int x, int y, int object, int radius, bool overwrite) {
|
||||
if(map) map->changeObject((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, object, radius, overwrite);
|
||||
}
|
||||
|
||||
void Program::changeMapResource(int x, int y, int resource, int radius) {
|
||||
if(map) map->changeResource((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, resource, radius);
|
||||
void Program::changeMapResource(int x, int y, int resource, int radius, bool overwrite) {
|
||||
if(map) map->changeResource((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, resource, radius, overwrite);
|
||||
}
|
||||
|
||||
void Program::changeStartLocation(int x, int y, int player) {
|
||||
|
@ -264,9 +265,9 @@ bool Program::redo() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void Program::renderMap(int w, int h) {
|
||||
void Program::renderMap(int w, int h, pair<int,int>* mouse_pos, int* radius) {
|
||||
//printf("Rendering map\n");
|
||||
if(map) renderer.renderMap(map, ofsetX, ofsetY, w, h, cellSize, grid,heightmap,hideWater);
|
||||
if(map) renderer.renderMap(map, ofsetX, ofsetY, w, h, cellSize, grid,heightmap,hideWater,mouse_pos,radius);
|
||||
}
|
||||
|
||||
void Program::setRefAlt(int x, int y) {
|
||||
|
|
|
@ -102,6 +102,7 @@ private:
|
|||
bool hideWater;
|
||||
//static Map *map;
|
||||
static MapPreview *map;
|
||||
|
||||
friend class UndoPoint;
|
||||
ChangeStack undoStack, redoStack;
|
||||
|
||||
|
@ -123,8 +124,8 @@ public:
|
|||
void glestChangeMapHeight(int x, int y, int Height, int radius);
|
||||
void pirateChangeMapHeight(int x, int y, int Height, int radius);
|
||||
void changeMapSurface(int x, int y, int surface, int radius);
|
||||
void changeMapObject(int x, int y, int object, int radius);
|
||||
void changeMapResource(int x, int y, int resource, int radius);
|
||||
void changeMapObject(int x, int y, int object, int radius, bool overwrite);
|
||||
void changeMapResource(int x, int y, int resource, int radius, bool overwrite);
|
||||
void changeStartLocation(int x, int y, int player);
|
||||
|
||||
void setUndoPoint(ChangeType change);
|
||||
|
@ -165,7 +166,7 @@ public:
|
|||
void setMapAdvanced(int altFactor, int waterLevel, int minimumCliffHeight, int cameraHeight);
|
||||
|
||||
//misc
|
||||
void renderMap(int w, int h);
|
||||
void renderMap(int w, int h, pair<int,int>* mouse_pos=NULL, int* radius=NULL);
|
||||
void setOfset(int x, int y);
|
||||
void incCellSize(int i);
|
||||
void resetOfset();
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
virtual ~BaseRenderer() { }
|
||||
|
||||
virtual void initMapSurface(int clientW, int clientH);
|
||||
virtual void renderMap(MapPreview *map, int x, int y, int clientW, int clientH, int cellSize, bool grid=false, bool heightMap=false, bool hideWater=false);
|
||||
virtual void renderMap(MapPreview *map, int x, int y, int clientW, int clientH, int cellSize, bool grid=false, bool heightMap=false, bool hideWater=false, pair<int, int>* mouse_pos=NULL, int* radius=NULL);
|
||||
};
|
||||
|
||||
}} // end namespace
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
class RendererMapInterface {
|
||||
public:
|
||||
virtual void initMapSurface(int clientW, int clientH) = 0;
|
||||
virtual void renderMap(MapPreview *map, int x, int y, int clientW, int clientH, int cellSize, bool grid, bool heightMap, bool hideWater) = 0;
|
||||
virtual void renderMap(MapPreview *map, int x, int y, int clientW, int clientH, int cellSize, bool grid, bool heightMap, bool hideWater, pair<int, int>* mouse_pos=NULL, int* radius=NULL) = 0;
|
||||
|
||||
virtual ~RendererMapInterface() {}
|
||||
};
|
||||
|
|
|
@ -174,6 +174,7 @@ public:
|
|||
int getCameraHeight() const{return cameraHeight;}
|
||||
|
||||
bool inside(int x, int y);
|
||||
static int get_dist(int delta_x, int delta_y);
|
||||
|
||||
void setRefAlt(int x, int y);
|
||||
void setAdvanced(int heightFactor, int waterLevel, int cliffLevel, int cameraHeight);
|
||||
|
@ -191,8 +192,8 @@ public:
|
|||
void glestChangeHeight(int x, int y, int height, int radius);
|
||||
void pirateChangeHeight(int x, int y, int height, int radius);
|
||||
void changeSurface(int x, int y, MapSurfaceType surface, int radius);
|
||||
void changeObject(int x, int y, int object, int radius);
|
||||
void changeResource(int x, int y, int resource, int radius);
|
||||
void changeObject(int x, int y, int object, int radius, bool overwrite);
|
||||
void changeResource(int x, int y, int resource, int radius, bool overwrite);
|
||||
void changeStartLocation(int x, int y, int player);
|
||||
|
||||
void setHeight(int x, int y, float height);
|
||||
|
|
|
@ -36,7 +36,7 @@ void BaseRenderer::initMapSurface(int clientW, int clientH) {
|
|||
}
|
||||
|
||||
void BaseRenderer::renderMap(MapPreview *map, int x, int y,
|
||||
int clientW, int clientH, int cellSize, bool grid, bool heightMap, bool hideWater) {
|
||||
int clientW, int clientH, int cellSize, bool grid, bool heightMap, bool hideWater, pair<int,int>* mouse_pos, int* radius) {
|
||||
float alt=0;
|
||||
float showWater=0;
|
||||
|
||||
|
@ -78,7 +78,7 @@ void BaseRenderer::renderMap(MapPreview *map, int x, int y,
|
|||
case st_Ground: surfColor = Vec3f(0.7f * alt, 0.5f * alt, 0.3f * alt + showWater); break;
|
||||
}
|
||||
if(heightMap){
|
||||
surfColor = Vec3f(1.f * alt, 1.f * alt, 1.f * alt + showWater);
|
||||
surfColor = Vec3f(1.f * alt, 1.f * alt, 1.f * alt + showWater);
|
||||
}
|
||||
if(map->getCliffLevel()>0)
|
||||
{// we maybe need to render cliff surfColor
|
||||
|
@ -87,6 +87,13 @@ void BaseRenderer::renderMap(MapPreview *map, int x, int y,
|
|||
isCliff=true;
|
||||
}
|
||||
}
|
||||
//highlight under cusor
|
||||
if(mouse_pos != NULL && radius != NULL) {
|
||||
int dist = map->get_dist(i - mouse_pos->first, j - mouse_pos->second);
|
||||
if (*radius > dist) {
|
||||
surfColor += Vec3f(0.15f,0.15f,0.15f);
|
||||
}
|
||||
}
|
||||
glColor3fv(surfColor.ptr());
|
||||
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
|
|
|
@ -112,8 +112,8 @@ int MapPreview::getStartLocationY(int index) const {
|
|||
return startLocations[index].y;
|
||||
}
|
||||
|
||||
static int get_dist(int delta_x, int delta_y) {
|
||||
float dx = (float)delta_x;
|
||||
int MapPreview::get_dist(int delta_x, int delta_y) {
|
||||
float dx = (float)delta_x;
|
||||
float dy = (float)delta_y;
|
||||
#ifdef USE_STREFLOP
|
||||
return static_cast<int>(streflop::sqrtf(static_cast<streflop::Simple>(dx * dx + dy * dy))+0.5); // round correctly
|
||||
|
@ -462,7 +462,7 @@ void MapPreview::setSurface(int x, int y, MapSurfaceType surface) {
|
|||
hasChanged = true;
|
||||
}
|
||||
|
||||
void MapPreview::changeObject(int x, int y, int object, int radius) {
|
||||
void MapPreview::changeObject(int x, int y, int object, int radius, bool overwrite) {
|
||||
int i = 0, j = 0;
|
||||
int dist = 0;
|
||||
|
||||
|
@ -470,7 +470,7 @@ void MapPreview::changeObject(int x, int y, int object, int radius) {
|
|||
for (j = y - radius + 1; j < y + radius; j++) {
|
||||
if (inside(i, j)) {
|
||||
dist = get_dist(i - x, j - y);
|
||||
if (radius > dist) { // was >=
|
||||
if (radius > dist && (overwrite || (cells[i][j].resource==0 && cells[i][j].object == 0 && !isCliff(i,j) && cells[i][j].height >= waterLevel-1.5f))) { // was >=
|
||||
cells[i][j].object = object;
|
||||
cells[i][j].resource = 0;
|
||||
hasChanged = true;
|
||||
|
@ -488,7 +488,7 @@ void MapPreview::setObject(int x, int y, int object) {
|
|||
hasChanged = true;
|
||||
}
|
||||
|
||||
void MapPreview::changeResource(int x, int y, int resource, int radius) {
|
||||
void MapPreview::changeResource(int x, int y, int resource, int radius, bool overwrite) {
|
||||
int i = 0, j = 0;
|
||||
int dist = 0;
|
||||
|
||||
|
@ -496,7 +496,7 @@ void MapPreview::changeResource(int x, int y, int resource, int radius) {
|
|||
for (j = y - radius + 1; j < y + radius; j++) {
|
||||
if (inside(i, j)) {
|
||||
dist = get_dist(i - x, j - y);
|
||||
if (radius > dist) { // was >=
|
||||
if (radius > dist && (overwrite || (cells[i][j].resource==0 && cells[i][j].object == 0 && !isCliff(i,j) && cells[i][j].height >= waterLevel-1.5f))) { // was >=
|
||||
cells[i][j].resource = resource;
|
||||
cells[i][j].object = 0;
|
||||
hasChanged = true;
|
||||
|
|
Loading…
Reference in New Issue