Editor: Brush preview and Shift-Key for filling brush

Editor needs to render more often for the preview function.
This commit is contained in:
titison 2021-03-19 16:06:38 +01:00
parent 880730e5e1
commit 0201af7ccf
9 changed files with 83 additions and 38 deletions

View File

@ -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)

View File

@ -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();

View File

@ -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) {

View File

@ -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();

View File

@ -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

View File

@ -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() {}
};

View File

@ -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);

View File

@ -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);

View File

@ -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;