1 /* 2 * Copyright (C) 2016-2017, by Laszlo Szeremi under the Boost license. 3 * 4 * Pixel Perfect Editor, graphics.outputScreen module 5 */ 6 7 module editor; 8 9 import PixelPerfectEngine.graphics.outputScreen; 10 import PixelPerfectEngine.graphics.raster; 11 import PixelPerfectEngine.graphics.layers; 12 import PixelPerfectEngine.graphics.paletteMan; 13 import PixelPerfectEngine.extbmp.extbmp; 14 15 import PixelPerfectEngine.graphics.bitmap; 16 import PixelPerfectEngine.graphics.draw; 17 //import collision; 18 import PixelPerfectEngine.system.inputHandler; 19 import PixelPerfectEngine.system.file; 20 import PixelPerfectEngine.system.etc; 21 import PixelPerfectEngine.system.config; 22 import PixelPerfectEngine.system.systemUtility; 23 import std.stdio; 24 import std.conv; 25 import derelict.sdl2.sdl; 26 import PixelPerfectEngine.concrete.window; 27 import PixelPerfectEngine.concrete.eventChainSystem; 28 import PixelPerfectEngine.map.mapload; 29 30 import converterdialog; 31 import tileLayer; 32 import newLayerDialog; 33 import about; 34 import editorEvents; 35 36 public interface IEditor{ 37 public void onExit(); 38 public void newDocument(); 39 public void newLayer(); 40 public void xmpToolkit(); 41 public void passActionEvent(Event e); 42 public void createNewDocument(wstring name, int rX, int rY, int pal); 43 //public void createNewLayer(string name, int type, int tX, int tY, int mX, int mY, int priority); 44 } 45 46 public class NewDocumentDialog : Window{ 47 public IEditor ie; 48 private TextBox[] textBoxes; 49 public this(Coordinate size, wstring title){ 50 super(size, title); 51 } 52 public this(InputHandler inputhandler){ 53 this(Coordinate(10,10,220,150),"New Document"); 54 55 Button[] buttons; 56 Label[] labels; 57 buttons ~= new Button("Ok", "ok", Coordinate(150,110,200,130)); 58 59 labels ~= new Label("Name:","",Coordinate(5,20,80,39)); 60 labels ~= new Label("RasterX:","",Coordinate(5,40,80,59)); 61 labels ~= new Label("RasterY:","",Coordinate(5,60,80,79)); 62 labels ~= new Label("N. of colors:","",Coordinate(5,80,120,99)); 63 textBoxes ~= new TextBox("","name",Coordinate(81,20,200,39)); 64 textBoxes ~= new TextBox("","rX",Coordinate(121,40,200,59)); 65 textBoxes ~= new TextBox("","rY",Coordinate(121,60,200,79)); 66 textBoxes ~= new TextBox("","pal",Coordinate(121,80,200,99)); 67 addElement(buttons[0], EventProperties.MOUSE); 68 foreach(WindowElement we; labels){ 69 addElement(we, EventProperties.MOUSE); 70 } 71 foreach(TextBox we; textBoxes){ 72 //we.addTextInputHandler(inputhandler); 73 addElement(we, EventProperties.MOUSE); 74 } 75 buttons[0].onMouseLClickRel = &buttonOn_onMouseLClickRel; 76 } 77 78 public void buttonOn_onMouseLClickRel(Event event){ 79 ie.createNewDocument(textBoxes[0].getText(), to!int(textBoxes[1].getText()), to!int(textBoxes[2].getText()), to!int(textBoxes[3].getText())); 80 81 parent.closeWindow(this); 82 } 83 } 84 85 public class EditorWindowHandler : WindowHandler, ElementContainer{ 86 private WindowElement[] elements, mouseC, keyboardC, scrollC; 87 private ListBox layerList, prop; 88 //private ListBoxColumn[] propTL, propSL, propSLE; 89 //private ListBoxColumn[] layerListE; 90 public Label[] labels; 91 private int[] propTLW, propSLW, propSLEW; 92 public IEditor ie; 93 94 //public InputHandler ih; 95 96 private BitmapDrawer output; 97 public this(int sx, int sy, int rx, int ry,ISpriteLayer sl){ 98 super(sx,sy,rx,ry,sl); 99 output = new BitmapDrawer(rx, ry); 100 addBackground(output.output); 101 propTLW = [40, 320]; 102 propSLW = [160, 320, 48, 64]; 103 propSLEW = [160, 320, 40, 56]; 104 WindowElement.popUpHandler = this; 105 } 106 107 public void initGUI(){ 108 output.drawFilledRectangle(0, rasterX, 0, rasterY, 0x0005); 109 110 PopUpMenuElement[] menuElements; 111 menuElements ~= new PopUpMenuElement("file", "FILE"); 112 113 menuElements[0].setLength(7); 114 menuElements[0][0] = new PopUpMenuElement("new", "New PPE map", "Ctrl + N"); 115 menuElements[0][1] = new PopUpMenuElement("newTemp", "New PPE map from template", "Ctrl + Shift + N"); 116 menuElements[0][2] = new PopUpMenuElement("load", "Load PPE map", "Ctrl + L"); 117 menuElements[0][3] = new PopUpMenuElement("save", "Save PPE map", "Ctrl + S"); 118 menuElements[0][4] = new PopUpMenuElement("saveAs", "Save PPE map as", "Ctrl + Shift + S"); 119 menuElements[0][5] = new PopUpMenuElement("saveTemp", "Save PPE map as template", "Ctrl + Shift + T"); 120 menuElements[0][6] = new PopUpMenuElement("exit", "Exit application", "Alt + F4"); 121 122 menuElements ~= new PopUpMenuElement("edit", "EDIT"); 123 124 menuElements[1].setLength(7); 125 menuElements[1][0] = new PopUpMenuElement("undo", "Undo", "Ctrl + Z"); 126 menuElements[1][1] = new PopUpMenuElement("redo", "Redo", "Ctrl + Shift + Z"); 127 menuElements[1][2] = new PopUpMenuElement("copy", "Copy", "Ctrl + C"); 128 menuElements[1][3] = new PopUpMenuElement("cut", "Cut", "Ctrl + X"); 129 menuElements[1][4] = new PopUpMenuElement("paste", "Paste", "Ctrl + V"); 130 menuElements[1][5] = new PopUpMenuElement("editorSetup", "Editor Settings"); 131 menuElements[1][6] = new PopUpMenuElement("docSetup", "Document Settings"); 132 133 menuElements ~= new PopUpMenuElement("view", "VIEW"); 134 135 menuElements[2].setLength(2); 136 menuElements[2][0] = new PopUpMenuElement("layerList", "Layer list", "Alt + L"); 137 menuElements[2][1] = new PopUpMenuElement("layerTools", "Layer tools", "Alt + T"); 138 139 menuElements ~= new PopUpMenuElement("layers", "LAYERS"); 140 141 menuElements[3].setLength(4); 142 menuElements[3][0] = new PopUpMenuElement("newLayer", "New layer", "Alt + N"); 143 menuElements[3][1] = new PopUpMenuElement("delLayer", "Delete layer", "Alt + Del"); 144 menuElements[3][2] = new PopUpMenuElement("impLayer", "Import layer", "Alt + Shift + I"); 145 menuElements[3][3] = new PopUpMenuElement("layerSrc", "Layer resources", "Alt + R"); 146 147 menuElements ~= new PopUpMenuElement("tools", "TOOLS"); 148 149 menuElements[4].setLength(2); 150 menuElements[4][0] = new PopUpMenuElement("xmpTool", "XMP Toolkit", "Alt + X"); 151 menuElements[4][1] = new PopUpMenuElement("mapXMLEdit", "Edit map as XML", "Ctrl + Alt + X"); 152 //menuElements[4][0] = new PopUpMenuElement("", "", ""); 153 154 menuElements ~= new PopUpMenuElement("help", "HELP"); 155 156 menuElements[5].setLength(2); 157 menuElements[5][0] = new PopUpMenuElement("helpFile", "Content", "F1"); 158 menuElements[5][1] = new PopUpMenuElement("about", "About"); 159 160 //addElement(new Button("Exit","exit",Coordinate(550,80,630,100)), EventProperties.MOUSE); 161 /*labels ~= new Label("Layer info:","null",Coordinate(5,395,101,415)); 162 labels ~= new Label("ScrollX:","null",Coordinate(5,415,70,435)); 163 labels ~= new Label("0","sx",Coordinate(71,415,140,435)); 164 labels ~= new Label("ScrollY:","null",Coordinate(145,415,210,435)); 165 labels ~= new Label("0","sy",Coordinate(211,415,280,435)); 166 labels ~= new Label("ScrollRateX:","null",Coordinate(281,415,378,435)); 167 labels ~= new Label("0","srx",Coordinate(379,415,420,435)); 168 labels ~= new Label("ScrollRateY:","null",Coordinate(421,415,518,435)); 169 labels ~= new Label("0","sry",Coordinate(519,415,560,435)); 170 labels ~= new Label("MapX:","null",Coordinate(5,435,45,455)); 171 labels ~= new Label("0","mx",Coordinate(46,435,100,455)); 172 labels ~= new Label("MapY:","null",Coordinate(105,435,145,455)); 173 labels ~= new Label("0","my",Coordinate(146,435,200,455)); 174 labels ~= new Label("TileX:","null",Coordinate(205,435,255,455)); 175 labels ~= new Label("0","tx",Coordinate(256,435,310,455)); 176 labels ~= new Label("TileY:","null",Coordinate(315,435,365,455)); 177 labels ~= new Label("0","ty",Coordinate(366,435,420,455));*/ 178 MenuBar mb = new MenuBar("menubar",Coordinate(0,0,640,16),menuElements); 179 addElement(mb, EventProperties.MOUSE); 180 mb.onMouseLClickPre = &actionEvent; 181 foreach(WindowElement we; labels){ 182 addElement(we, 0); 183 } 184 foreach(WindowElement we; elements){ 185 we.draw(); 186 } 187 } 188 189 public override StyleSheet getStyleSheet(){ 190 return defaultStyle; 191 } 192 193 public void addElement(WindowElement we, int eventProperties){ 194 elements ~= we; 195 we.elementContainer = this; 196 //we.al ~= this; 197 if((eventProperties & EventProperties.KEYBOARD) == EventProperties.KEYBOARD){ 198 keyboardC ~= we; 199 } 200 if((eventProperties & EventProperties.MOUSE) == EventProperties.MOUSE){ 201 mouseC ~= we; 202 } 203 if((eventProperties & EventProperties.SCROLL) == EventProperties.SCROLL){ 204 scrollC ~= we; 205 } 206 } 207 208 209 public void actionEvent(Event event){ 210 writeln(event.source); 211 switch(event.source){ 212 case "exit": 213 ie.onExit; 214 break; 215 case "new": 216 ie.newDocument; 217 break; 218 case "newL": 219 ie.newLayer; 220 break; 221 case "xmpTool": 222 ie.xmpToolkit(); 223 break; 224 case "about": 225 Window w = new AboutWindow(); 226 addWindow(w); 227 w.relMove(30,30); 228 break; 229 default: 230 ie.passActionEvent(event); 231 break; 232 } 233 } 234 235 public override void drawUpdate(WindowElement sender){ 236 output.insertBitmap(sender.getPosition().left,sender.getPosition().top,sender.output.output); 237 } 238 239 override public void passMouseEvent(int x,int y,int state,ubyte button) { 240 foreach(WindowElement e; mouseC){ 241 if(e.getPosition().left < x && e.getPosition().right > x && e.getPosition().top < y && e.getPosition().bottom > y){ 242 e.onClick(x - e.getPosition().left, y - e.getPosition().top, state, button); 243 return; 244 } 245 } 246 } 247 public override void passScrollEvent(int wX, int wY, int x, int y){ 248 foreach(WindowElement e; scrollC){ 249 if(e.getPosition().left < wX && e.getPosition().right > wX && e.getPosition().top < wX && e.getPosition().bottom > wY){ 250 251 e.onScroll(y, x, wX, wY); 252 253 return; 254 } 255 } 256 } 257 public Coordinate getAbsolutePosition(WindowElement sender){ 258 return sender.position; 259 } 260 } 261 262 public enum PlacementMode : uint{ 263 NULL = 0, 264 NORMAL = 1, 265 VOIDFILL = 2, 266 OVERWRITE = 3, 267 268 } 269 270 public class Editor : InputListener, MouseListener, IEditor, SystemEventListener, NewLayerDialogListener{ 271 public OutputScreen[] ow; 272 public Raster[] rasters; 273 public InputHandler input; 274 public TileLayer[int] backgroundLayers; 275 //public TileLayer8Bit[int] backgroundLayers8; 276 //public TileLayer32Bit[int] backgroundLayers32; 277 public Layer[int] layers; 278 public wchar selectedTile; 279 public BitmapAttrib selectedTileAttrib; 280 public int selectedLayer; 281 public SpriteLayer windowing; 282 public SpriteLayer bitmapPreview; 283 public bool onexit, exitDialog, newLayerDialog, mouseState, rasterRefresh; 284 public WindowElement[] elements; 285 public Window test; 286 public EditorWindowHandler wh; 287 public ExtendibleMap document; 288 public EffectLayer selectionLayer; 289 //public ForceFeedbackHandler ffb; 290 private uint[5] framecounter; 291 public char[40] windowTitle; 292 public ConfigurationProfile configFile; 293 private int mouseX, mouseY; 294 private Coordinate selection, selectedTiles; 295 public PlacementMode pm; 296 public UndoableStack undoStack; 297 public PaletteManager palman; 298 299 public void mouseButtonEvent(Uint32 which, Uint32 timestamp, Uint32 windowID, Uint8 button, Uint8 state, Uint8 clicks, Sint32 x, Sint32 y){ 300 //writeln(windowID); 301 x /= 2; 302 y /= 2; 303 if(windowID == 2){ 304 if(button == MouseButton.LEFT){//placement 305 if(state == ButtonState.PRESSED && !mouseState){ 306 mouseX = x; 307 mouseY = y; 308 mouseState = true; 309 }else if(mouseState){ 310 mouseState = false; 311 if(mouseX == x && mouseY == y){//single placement 312 if(layers[selectedLayer].classinfo == typeid(TileLayer)){ 313 TileLayer tl = cast(TileLayer)(layers[selectedLayer]); 314 int targetX = (x + tl.getSX()) / tl.getTileWidth(); 315 int targetY = (y + tl.getSY()) / tl.getTileHeight(); 316 if(targetX >= 0 && targetY >= 0 && targetX < tl.getMX && targetY < tl.getMY){ 317 if(pm == PlacementMode.NORMAL || (pm == PlacementMode.VOIDFILL && tl.readMapping(targetX,targetY).tileID == 0xFFFF 318 || (pm == PlacementMode.OVERWRITE))){ 319 undoStack.addToTop(new WriteToMapSingle(cast(ITileLayer)(layers[selectedLayer]), x, y, MappingElement(selectedTile, selectedTileAttrib))); 320 } 321 } 322 }else{//sprite placement 323 324 } 325 }else{ //select or region fill 326 Coordinate c = Coordinate(); 327 if(mouseX>x){ 328 c.left = x; 329 c.right = mouseX; 330 }else{ 331 c.left = mouseX; 332 c.right = x; 333 } 334 if(mouseY>y){ 335 c.top = y; 336 c.bottom = mouseY; 337 }else{ 338 c.top = mouseY; 339 c.bottom = y; 340 } 341 if(layers[selectedLayer].classinfo == typeid(TileLayer)){ 342 TileLayer tl = cast(TileLayer)(layers[selectedLayer]); 343 c.left = (c.left + tl.getSX()) / tl.getTileWidth(); 344 c.right = (c.right + tl.getSX()) / tl.getTileWidth(); 345 c.top = (c.top + tl.getSY()) / tl.getTileHeight(); 346 c.bottom = (c.bottom + tl.getSY()) / tl.getTileHeight(); 347 //Fill 348 if(pm == PlacementMode.VOIDFILL){ 349 undoStack.addToTop(new WriteToMapVoidFill(cast(ITileLayer)(layers[selectedLayer]), c, MappingElement(selectedTile, selectedTileAttrib))); 350 }else{ 351 undoStack.addToTop(new WriteToMapOverwrite(cast(ITileLayer)(layers[selectedLayer]), c, MappingElement(selectedTile, selectedTileAttrib))); 352 } 353 } 354 } 355 } 356 }else if(button == MouseButton.MID){//deletion 357 358 } 359 } 360 setRasterRefresh; 361 } 362 public void mouseWheelEvent(uint type, uint timestamp, uint windowID, uint which, int x, int y, int wX, int wY){ 363 setRasterRefresh; 364 } 365 public void mouseMotionEvent(uint timestamp, uint windowID, uint which, uint state, int x, int y, int relX, int relY){ 366 setRasterRefresh; 367 } 368 public void keyPressed(string ID, Uint32 timestamp, Uint32 devicenumber, Uint32 devicetype){ 369 switch(ID){ 370 case "nextLayer": 371 break; 372 case "prevLayer": 373 break; 374 case "scrollUp": 375 break; 376 case "scrollDown": 377 break; 378 case "scrollLeft": 379 break; 380 case "scrollRight": 381 break; 382 case "quit": 383 break; 384 case "xmpTool": 385 break; 386 case "load": 387 break; 388 case "save": 389 break; 390 case "saveAs": 391 break; 392 default: 393 break; 394 } 395 } 396 public void keyReleased(string ID, Uint32 timestamp, Uint32 devicenumber, Uint32 devicetype){} 397 public void passActionEvent(Event e){ 398 switch(e.source){ 399 case "saveas": 400 FileDialog fd = new FileDialog("Save document as","docSave",&actionEvent,[FileDialog.FileAssociationDescriptor("PPE map file", ["*.xmf"])],".\\",true); 401 wh.addWindow(fd); 402 break; 403 case "load": 404 FileDialog fd = new FileDialog("Load document","docLoad",&actionEvent,[FileDialog.FileAssociationDescriptor("PPE map file", ["*.xmf"])],".\\",false); 405 wh.addWindow(fd); 406 break; 407 case "newLayer": 408 NewLayerDialog nld = new NewLayerDialog(this); 409 wh.addWindow(nld); 410 break; 411 case "layerTools": 412 TileLayerEditor tle = new TileLayerEditor(this); 413 wh.addWindow(tle); 414 break; 415 default: break; 416 } 417 } 418 /*public void actionEvent(string source, int type, int value, wstring message){ 419 writeln(source); 420 421 if(source == "file"){ 422 writeln(message); 423 } 424 } 425 public void actionEvent(string source, string subSource, int type, int value, wstring message){ 426 switch(subSource){ 427 case "exitdialog": 428 if(source == "Yes"){ 429 onexit = true; 430 } 431 break; 432 default: break; 433 } 434 }*/ 435 public void actionEvent(Event event){ 436 //writeln(event.subsource); 437 switch(event.subsource){ 438 case "exitdialog": 439 if(event.source == "ok"){ 440 onexit = true; 441 } 442 break; 443 case FileDialog.subsourceID: 444 switch(event.source){ 445 case "docSave": 446 break; 447 case "docLoad": 448 string path = event.path; 449 path ~= event.filename; 450 document = new ExtendibleMap(path); 451 break; 452 default: break; 453 } 454 break; 455 default: 456 break; 457 } 458 } 459 public void onQuit(){onExit();} 460 public void controllerRemoved(uint ID){} 461 public void controllerAdded(uint ID){} 462 public void xmpToolkit(){ 463 wh.addWindow(new ConverterDialog(input,bitmapPreview)); 464 } 465 /*public void placeObject(int x, int y){ 466 if(backgroundLayers.get(selectedLayer, null) !is null){ 467 int sX = backgroundLayers[selectedLayer].getSX(), sY = backgroundLayers[selectedLayer].getSY(); 468 sX += x; 469 sY += y; 470 sX /= backgroundLayers[selectedLayer].getTileWidth(); 471 sY /= backgroundLayers[selectedLayer].getTileHeight(); 472 if(sX >= 0 && sY >= 0){ 473 backgroundLayers[selectedLayer].writeMapping(sX, sY, selectedTile); 474 } 475 } 476 }*/ 477 public this(string[] args){ 478 pm = PlacementMode.OVERWRITE; 479 ConfigurationProfile.setVaultPath("ZILtoid1991","PixelPerfectEditor"); 480 configFile = new ConfigurationProfile(); 481 482 windowing = new SpriteLayer(LayerRenderingMode.COPY); 483 bitmapPreview = new SpriteLayer(); 484 485 wh = new EditorWindowHandler(1280,960,640,480,windowing); 486 wh.ie = this; 487 488 //Initialize the Concrete framework 489 INIT_CONCRETE(wh); 490 491 492 wh.initGUI(); 493 494 input = new InputHandler(); 495 input.ml ~= this; 496 input.ml ~= wh; 497 input.il ~= this; 498 input.sel ~= this; 499 input.kb ~= KeyBinding(0, SDL_SCANCODE_ESCAPE, 0, "sysesc", Devicetype.KEYBOARD); 500 WindowElement.inputHandler = input; 501 //wh.ih = input; 502 //ffb = new ForceFeedbackHandler(input); 503 504 //OutputWindow.setScalingQuality("2"); 505 //OutputWindow.setDriver("software"); 506 ow ~= new OutputScreen("Pixel Perfect Editor", 1280, 960); 507 508 rasters ~= new Raster(640, 480, ow[0]); 509 ow[0].setMainRaster(rasters[0]); 510 rasters[0].addLayer(windowing, 0); 511 rasters[0].addLayer(bitmapPreview, 1); 512 //rasters[0].setupPalette(512); 513 //loadPaletteFromFile("VDPeditUI0.pal", guiR); 514 //load24bitPaletteFromFile("VDPeditUI0.pal", rasters[0]); 515 //loadPaletteFromXMP(ssOrigin, "default", rasters[0]); 516 //foreach(c ; StyleSheet.defaultpaletteforGUI) 517 rasters[0].palette ~= [Color(0x00,0x00,0x00,0x00),Color(0xFF,0xFF,0xFF,0xFF),Color(0xFF,0x34,0x9e,0xff),Color(0xff,0xa2,0xd7,0xff), 518 Color(0xff,0x00,0x2c,0x59),Color(0xff,0x00,0x75,0xe7),Color(0xff,0xff,0x00,0x00),Color(0xFF,0x7F,0x00,0x00), 519 Color(0xFF,0x00,0xFF,0x00),Color(0xFF,0x00,0x7F,0x00),Color(0xFF,0x00,0x00,0xFF),Color(0xFF,0x00,0x00,0x7F), 520 Color(0xFF,0xFF,0xFF,0x00),Color(0xFF,0xFF,0x7F,0x00),Color(0xFF,0x7F,0x7F,0x7F),Color(0xFF,0x00,0x00,0x00)];// StyleSheet.defaultpaletteforGUI; 521 //writeln(rasters[0].palette); 522 //rasters[0].addRefreshListener(ow[0],0); 523 WindowElement.onDraw = &setRasterRefresh; 524 PopUpElement.onDraw = &setRasterRefresh; 525 Window.onDrawUpdate = &setRasterRefresh; 526 } 527 public void setRasterRefresh(){ 528 rasterRefresh = true; 529 } 530 public void whereTheMagicHappens(){ 531 rasters[0].refresh(); 532 while(!onexit){ 533 input.test(); 534 if(rasterRefresh){ 535 rasters[0].refresh(); 536 //rasterRefresh = false; 537 } 538 if(rasters.length == 2){ 539 rasters[1].refresh(); 540 } 541 //rudamentaryFrameCounter(); 542 //onexit = true; 543 } 544 configFile.store(); 545 } 546 public void onExit(){ 547 548 exitDialog=true; 549 DefaultDialog dd = new DefaultDialog(Coordinate(10,10,220,75), "exitdialog","Exit application", ["Are you sure?"],["Yes","No","Pls save"],["ok","close","save"]); 550 551 dd.output = &actionEvent; 552 wh.addWindow(dd); 553 554 } 555 public void newDocument(){ 556 NewDocumentDialog ndd = new NewDocumentDialog(input); 557 ndd.ie = this; 558 wh.addWindow(ndd); 559 } 560 public void createNewDocument(wstring name, int rX, int rY, int pal){ 561 ow ~= new OutputScreen("Edit window", to!ushort(rX*2),to!ushort(rY*2)); 562 rasters ~= new Raster(to!ushort(rX), to!ushort(rY), ow[1]); 563 rasters[1].setupPalette(pal); 564 ow[1].setMainRaster(rasters[1]); 565 selectionLayer = new EffectLayer(); 566 rasters[1].addLayer(selectionLayer, 65536); 567 document = new ExtendibleMap(); 568 document.metaData["name"] = to!string(name); 569 document.metaData["rX"] = to!string(rX); 570 document.metaData["rY"] = to!string(rY); 571 document.metaData["pal"] = to!string(pal); 572 } 573 574 public void newLayer(){ 575 if(document !is null){ 576 NewLayerDialog ndd = new NewLayerDialog(this); 577 wh.addWindow(ndd); 578 } 579 } 580 private void updateLayerList(){ 581 582 } 583 public void newTileLayerEvent(string name, string file, bool embed, bool preexisting, int tX, int tY, int mX, int mY){ 584 import std.path; 585 TileLayer tl = new TileLayer(tX, tY, LayerRenderingMode.ALPHA_BLENDING); 586 587 while(layers.get(selectedLayer, null)){ 588 selectedLayer++; 589 } 590 TileLayerData tld; 591 if(preexisting && !embed){ 592 //tld = new TileLayerData(tX, tY, mX, mY, 1.0, 1.0, selectedLayer, MapData.load(file), name); 593 }else if(!preexisting && embed){ 594 tld = new TileLayerData(tX, tY, mX, mY, 1.0, 1.0, selectedLayer, name); 595 }else if(!preexisting && !embed){ 596 tld = new TileLayerData(tX, tY, mX, mY, 1.0, 1.0, selectedLayer, name); 597 //tld.mapping.save(file); 598 }else if(extension(file) == ".xmf"){ 599 wh.messageWindow("Error"w, "Function of importing embedded mapping from *.xmf files not yet implemented"w, 320); 600 return; 601 } 602 tld.isEmbedded = embed; 603 //tl.loadMapping(mX,mY,tld.mapping.getCharMapping(),tld.mapping.getAttribMapping()); 604 layers[selectedLayer] = tl; 605 if(rasters.length > 1){ 606 rasters[1].addLayer(tl,selectedLayer); 607 } 608 } 609 public void newSpriteLayerEvent(string name){ 610 SpriteLayer sl = new SpriteLayer(); 611 612 while(layers.get(selectedLayer, null)){ 613 selectedLayer++; 614 } 615 SpriteLayerData sld = new SpriteLayerData(name, 1.0, 1.0, selectedLayer); 616 layers[selectedLayer] = sl; 617 if(rasters.length > 1){ 618 rasters[1].addLayer(sl,selectedLayer); 619 } 620 } 621 public void importTileLayerSymbolData(string file){ 622 623 } 624 public int getPreviousTileLayer(int pri){ 625 import std.algorithm.sorting; 626 int[] list = document.tld.keys; 627 list.sort(); 628 int n, i; 629 for( ; i < list.length ; i++){ 630 if(pri == list[i]){ 631 n = list[i]; 632 break; 633 } 634 } 635 selectedLayer--; 636 if(i == 0){ 637 return n; 638 }else{ 639 return list[i - 1]; 640 } 641 } 642 public int getNextTileLayer(int pri){ 643 import std.algorithm.sorting; 644 int[] list = document.tld.keys; 645 list.sort(); 646 int n, i; 647 for( ; i < list.length ; i++){ 648 if(pri == list[i]){ 649 n = list[i]; 650 break; 651 } 652 } 653 selectedLayer++; 654 if(i == list.length - 1){ 655 return n; 656 }else{ 657 return list[i + 1]; 658 } 659 } 660 public int moveLayerDown(int pri){ 661 selectedLayer--; 662 import std.algorithm.sorting; 663 int[] list = layers.keys; 664 list.sort(); 665 int n, i; 666 for( ; i < list.length ; i++){ 667 if(pri == list[i]){ 668 n = list[i]; 669 break; 670 } 671 } 672 if(i == 0){ 673 Layer l = layers[n]; 674 layers[n] = layers[n - 1]; 675 if(document.tld.get(n, null)){ 676 document.tld[n - 1] = document.tld[n]; 677 document.tld.remove(n); 678 document.tld[n - 1].priority -= 1; 679 }else{ 680 document.sld[n - 1] = document.sld[n]; 681 document.sld.remove(n); 682 document.sld[n - 1].priority -= 1; 683 } 684 n--; 685 return n; 686 } 687 if(list[i - 1] == n - 1){ //swap two layers 688 Layer l = layers[n]; 689 layers[n] = layers[n - 1]; 690 if(document.tld.get(n, null)){ 691 document.tld[n - 1] = document.tld[n]; 692 document.tld.remove(n); 693 document.tld[n - 1].priority -= 1; 694 }else{ 695 document.sld[n - 1] = document.sld[n]; 696 document.sld.remove(n); 697 document.sld[n - 1].priority -= 1; 698 } 699 n--; 700 layers[n] = l; 701 if(document.tld.get(n, null)){ 702 document.tld[n + 1] = document.tld[n]; 703 document.tld.remove(n); 704 document.tld[n + 1].priority += 1; 705 }else{ 706 document.sld[n + 1] = document.sld[n]; 707 document.sld.remove(n); 708 document.sld[n + 1].priority += 1; 709 } 710 }else{ //lower the priority of the current layer 711 Layer l = layers[n]; 712 layers.remove(n); 713 if(document.tld.get(n, null)){ 714 document.tld[n - 1] = document.tld[n]; 715 document.tld.remove(n); 716 document.tld[n - 1].priority -= 1; 717 }else{ 718 document.sld[n - 1] = document.sld[n]; 719 document.sld.remove(n); 720 document.sld[n - 1].priority -= 1; 721 } 722 n--; 723 layers[n] = l; 724 725 } 726 return n; 727 } 728 public int moveLayerUp(int pri){ 729 selectedLayer++; 730 import std.algorithm.sorting; 731 int[] list = layers.keys; 732 list.sort(); 733 int n, i; 734 for( ; i < list.length ; i++){ 735 if(pri == list[i]){ 736 n = list[i]; 737 break; 738 } 739 } 740 if(i == list.length - 1){ 741 Layer l = layers[n]; 742 layers[n] = layers[n - 1]; 743 if(document.tld.get(n, null)){ 744 document.tld[n - 1] = document.tld[n]; 745 document.tld.remove(n); 746 document.tld[n - 1].priority -= 1; 747 }else{ 748 document.sld[n - 1] = document.sld[n]; 749 document.sld.remove(n); 750 document.sld[n - 1].priority -= 1; 751 } 752 n--; 753 return n; 754 } 755 if(list[i + 1] == n + 1){ //swap two layers 756 Layer l = layers[n]; 757 layers[n] = layers[n + 1]; 758 if(document.tld.get(n, null)){ 759 document.tld[n + 1] = document.tld[n]; 760 document.tld.remove(n); 761 document.tld[n + 1].priority += 1; 762 }else{ 763 document.sld[n + 1] = document.sld[n]; 764 document.sld.remove(n); 765 document.sld[n + 1].priority += 1; 766 } 767 n++; 768 layers[n] = l; 769 if(document.tld.get(n, null)){ 770 document.tld[n - 1] = document.tld[n]; 771 document.tld.remove(n); 772 document.tld[n - 1].priority -= 1; 773 }else{ 774 document.sld[n - 1] = document.sld[n]; 775 document.sld.remove(n); 776 document.sld[n - 1].priority -= 1; 777 } 778 }else{ //higher the priority of the current layer 779 Layer l = layers[n]; 780 layers.remove(n); 781 if(document.tld.get(n, null)){ 782 document.tld[n + 1] = document.tld[n]; 783 document.tld.remove(n); 784 document.tld[n + 1].priority += 1; 785 }else{ 786 document.sld[n + 1] = document.sld[n]; 787 document.sld.remove(n); 788 document.sld[n + 1].priority += 1; 789 } 790 n++; 791 layers[n] = l; 792 793 } 794 return n; 795 } 796 }