1 /* 2 * PixelPerfectEditor, converterdialog module 3 * 4 * Copyright 2017, under Boost License 5 * 6 * by Laszlo Szeremi 7 */ 8 module converterdialog; 9 10 import std.conv; 11 import std.stdio; 12 13 import PixelPerfectEngine.concrete.window; 14 import PixelPerfectEngine.concrete.elements; 15 16 import PixelPerfectEngine.map.mapload; 17 18 import PixelPerfectEngine.system.etc; 19 import PixelPerfectEngine.system.inputHandler; 20 21 import PixelPerfectEngine.graphics.bitmap; 22 import PixelPerfectEngine.graphics.layers; 23 24 import PixelPerfectEngine.extbmp.extbmp; 25 26 import converter; 27 import importDialog; 28 import multiImportDialog; 29 /** 30 *Creates a window for converting external bitmaps for the engine's native format 31 */ 32 public class ConverterDialog : Window{ 33 private ListBox imageList, fileList, animationList, frameList; 34 private string[] filenames; 35 private string importFileName,animationSelection; 36 private Label[string] labels; 37 private InputHandler inputHandler; 38 public ExtendibleBitmap[] files; 39 private ISpriteLayer viewer; 40 private Bitmap32Bit preview; 41 private PreviewWindow previewWindow; 42 private int imageSelection, frameSelection; 43 44 public bool previewModeOn; 45 ExtendibleBitmap selection; 46 public this(InputHandler inputhandler, ISpriteLayer viewer, ExtendibleMap mh = null, ExtendibleBitmap[] documentFiles = null){ 47 this(Coordinate(0,16,640,480), "XMP Converter Toolkit"); 48 this.inputHandler = inputhandler; 49 this.viewer = viewer; 50 files = documentFiles; 51 Button [] buttons; 52 if(mh !is null){ 53 //filenames = mh.getAllFilenames(); 54 //fileList = new ListBox("fileList",Coordinate(4,20,204,101), [ListBoxColumn("Filename",filenames)], [256], 15); 55 }else{ 56 labels["0x00"] = new Label("Path:", "", Coordinate(4,20,204,40)); 57 labels["path"] = new Label("n/a", "path", Coordinate(4,40,204,60)); 58 } 59 buttons ~= new Button("New File","newfile", Coordinate(210,20,294,39)); 60 buttons ~= new Button("Load File","loadfile", Coordinate(210,40,294,59)); 61 buttons ~= new Button("Save File","savefile", Coordinate(210,60,294,79)); 62 //buttons ~= new Button("Rem File","removefile", Coordinate(210,60,294,79)); //[ListBoxColumn("BitmapID",[""]),ListBoxColumn("Bitdepth",[""]),ListBoxColumn("Format",[""]),ListBoxColumn("PalMode",[""])] //[128,64,64,80] 63 imageList = new ListBox("imageList",Coordinate(4,104,204,304),null,new ListBoxHeader(["BitmapID","Bitdepth","Format","PalMode","sizeX","sizeY"], [128,64,64,80,42,42]), 15); 64 buttons ~= new Button("Import New","inportnew", Coordinate(210,110,294,129)); 65 buttons ~= new Button("Imp Multi","inportmultiple", Coordinate(210,130,294,149)); 66 buttons ~= new Button("Export As","exportas", Coordinate(210,150,294,169)); 67 buttons ~= new Button("Remove","remove", Coordinate(210,170,294,189)); 68 buttons ~= new Button("Preview","preview", Coordinate(210,190,294,209)); 69 buttons ~= new Button("Imp Pal","paletteImport", Coordinate(210,210,294,229)); 70 animationList = new ListBox("animationList", Coordinate(300,20,500,120), null, new ListBoxHeader(["AnimID","Frames"], [128,80]), 15); 71 buttons ~= new Button("New Anim","newAnim", Coordinate(506,20,590,39)); 72 buttons ~= new Button("Edit","animProp", Coordinate(506,40,590,59)); 73 //buttons ~= new Button("Save File","savefile", Coordinate(506,60,590,79)); 74 buttons ~= new Button("Rem Anim","removeAnim", Coordinate(506,60,590,79)); 75 frameList = new ListBox("frameList", Coordinate(300,122,500,304), null, new ListBoxHeader(["Num","ImageID","Dur"],[40,128,64]), 15); 76 buttons ~= new Button("Add Frame","addFrame", Coordinate(506,130,590,149)); 77 buttons ~= new Button("Edit","editFr", Coordinate(506,150,590,169)); 78 buttons ~= new Button("Remove","removeFr", Coordinate(506,170,590,189)); 79 80 foreach(Button e; buttons){ 81 addElement(e, EventProperties.MOUSE); 82 e.onMouseLClickRel = &actionEvent; 83 } 84 foreach(WindowElement e; labels){ 85 addElement(e, EventProperties.MOUSE); 86 } 87 addElement(imageList, EventProperties.MOUSE); 88 imageList.onItemSelect = &actionEvent; 89 addElement(animationList, EventProperties.MOUSE); 90 addElement(frameList, EventProperties.MOUSE); 91 } 92 93 public this(Coordinate size, dstring title){ 94 super(size, title); 95 } 96 97 public void singleImport(string bitmapID, string paletteID, bool importPal, string bitDepth){ 98 try{ 99 importDirectlyToXMP(importFileName,paletteID,selection,new ImportData([bitmapID],bitDepth,0,0,0)); 100 if(importPal){// 101 importPaletteDirectlyToXMP(importFileName,selection,paletteID); 102 } 103 }catch(Exception e){ 104 writeln(e); 105 } 106 } 107 108 public void multiImport(string foretag, string aftertag, int digits, string paletteID, bool importPal, string bitDepth, int numFrom, int sX, int sY, bool useHex){ 109 try{ 110 NamingConvention nc = new NamingConvention(foretag, aftertag, useHex ? NumberingStyle.HEXADECIMAL : NumberingStyle.DECIMAL, numFrom, digits); 111 importDirectlyToXMP(importFileName, paletteID, selection, new ImportData(nc, bitDepth, sX, sY, 0)); 112 if(importPal){// 113 importPaletteDirectlyToXMP(importFileName,selection,paletteID); 114 } 115 }catch(Exception e){ 116 parent.messageWindow(to!dstring(e.classinfo.toString()), to!dstring(e.msg)); 117 } 118 } 119 120 public void actionEvent(Event event){ 121 //writeln(event.subsource); 122 //writeln(event.source); 123 switch(event.subsource){ 124 case "filedialog": 125 switch(event.source){ 126 case "xmpfiledialog": 127 ExtendibleBitmap newFile = new ExtendibleBitmap(); 128 string fileName = event.path ; 129 fileName ~= '\\'; 130 fileName ~= event.filename; 131 newFile.saveFile(fileName); 132 if(files is null){ 133 selection = newFile; 134 labels["path"].setText(to!dstring(fileName)); 135 }else{ 136 files ~= newFile; 137 filenames ~= fileName; 138 selection = newFile; 139 } 140 141 break; 142 case "xmpload": 143 string fileName = event.path ; 144 //writeln(fileName); 145 fileName ~= '\\'; 146 //writeln(fileName); 147 fileName ~= event.filename; 148 //writeln(fileName); 149 ExtendibleBitmap newFile = new ExtendibleBitmap(fileName); 150 if(files is null){ 151 selection = newFile; 152 labels["path"].setText(to!dstring(fileName)); 153 }else{ 154 files ~= newFile; 155 filenames ~= fileName; 156 selection = newFile; 157 } 158 updateImageList(); 159 updateAnimationList(); 160 break; 161 case "importfile": 162 string fileName = event.path ; 163 fileName ~= '\\'; 164 fileName ~= event.filename; 165 importFileName = fileName; 166 //Bitmap32Bit bmp = importBitmapFromFile(fileName); 167 //ImportDialog id = new ImportDialog(this); 168 //id.al ~= this; 169 parent.addWindow(new ImportDialog(this)); 170 break; 171 case "importmulti": 172 string fileName = event.path; 173 fileName ~= '\\'; 174 fileName ~= event.filename; 175 importFileName = fileName; 176 BitmapInfo bi = getBitmapInfo(importFileName); 177 178 parent.addWindow(new MultiImportDialog(bi.width, bi.height, this)); 179 break; 180 case "palettefile": 181 string fileName = event.path; 182 fileName ~= '\\'; 183 fileName ~= event.filename; 184 importFileName = fileName; 185 TextInputDialog tid = new TextInputDialog(Coordinate(0,0,200,90),"palName","Import Palette","Palette ID:"); 186 187 parent.addWindow(tid); 188 break; 189 default: break; 190 } 191 break; 192 /+case "impDial": 193 194 try{ 195 /*Bitmap32Bit bmp = import32BitBitmapFromFile(importFileName); 196 selection.addBitmap(cast(void[])bmp.getRawdata(),bmp.getX,bmp.getY,"32bit",to!string(event.text),"ARGB"); 197 updateImageList(); 198 previewModeOn = true; 199 //set sprite for preview mode 200 //writeln(preview); 201 viewer.addSprite(bmp, 0, 0, 0);*/ 202 string bitdepth; 203 switch(event.value){ 204 case 0: bitdepth = "8bit"; break; 205 case 1: bitdepth = "16bit"; break; 206 case 2: bitdepth = "32bit"; break; 207 default: bitdepth = "1bit"; break; 208 } 209 importDirectlyToXMP(importFileName,selection,new ImportData([to!string(event.text)],bitdepth,0,0,0)); 210 211 }catch(Exception e){ 212 writeln(e); 213 } 214 break;+/ 215 case "TextInputDialog": 216 switch(event.source){ 217 case "palName": 218 importPaletteDirectlyToXMP(importFileName,selection,to!string(event.text)); 219 break; 220 default: break; 221 } 222 break; 223 default: 224 switch(event.source){ 225 case "newfile": 226 // create new filedialog to save the new file to the given location 227 FileDialog fileDialog = new FileDialog("Create new XMP file", "xmpfiledialog", &actionEvent, [FileDialog.FileAssociationDescriptor("Extendible bitmap file", ["*.xmp"])], ".\\", true); 228 parent.addWindow(fileDialog); 229 break; 230 case "loadfile": 231 FileDialog fileDialog = new FileDialog("Load XMP file", "xmpload", &actionEvent, [FileDialog.FileAssociationDescriptor("Extendible bitmap file", ["*.xmp"])], ".\\", false); 232 parent.addWindow(fileDialog); 233 break; 234 case "savefile": 235 selection.saveFile(); 236 break; 237 case "preview": 238 if(preview !is null){ 239 if(previewModeOn){ 240 previewModeOn = false; 241 previewWindow.close(); 242 }else{ 243 previewModeOn = true; 244 245 previewWindow = new PreviewWindow(preview, viewer, this); 246 parent.addWindow(previewWindow); 247 } 248 } 249 break; 250 case "inportnew": 251 FileDialog fileDialog = new FileDialog("Import PNG/TGA/BMP", "importfile", &actionEvent, [FileDialog.FileAssociationDescriptor("All supported files", ["*.png","*.tga","*.bmp"]), 252 FileDialog.FileAssociationDescriptor("Portable network graphics", ["*.png"]), FileDialog.FileAssociationDescriptor("Targa graphics file", ["*.tga"]), 253 FileDialog.FileAssociationDescriptor("Windows bitmap", ["*.bmp"])], ".\\"); 254 parent.addWindow(fileDialog); 255 break; 256 case "inportmultiple": 257 //parent.addWindow(new SpriteSheetDialog()); 258 FileDialog fileDialog = new FileDialog("Import PNG/TGA/BMP", "importmulti", &actionEvent, [FileDialog.FileAssociationDescriptor("All supported files", ["*.png","*.tga","*.bmp"]), 259 FileDialog.FileAssociationDescriptor("Portable network graphics", ["*.png"]), FileDialog.FileAssociationDescriptor("Targa graphics file", ["*.tga"]), 260 FileDialog.FileAssociationDescriptor("Windows bitmap", ["*.bmp"])], ".\\"); 261 parent.addWindow(fileDialog); 262 break; 263 case "imageList": 264 //if(!selection.isEmpty){ 265 imageSelection = event.value; 266 //update image information 267 //preview = new Bitmap32Bit(selection.getBitmap(imageSelection),selection.getXsize(imageSelection),selection.getYsize(imageSelection)); 268 //writeln(preview); 269 preview = getBitmapPreview(selection,selection.bitmapID[imageSelection]); 270 //writeln(preview); 271 //} 272 break; 273 case "paletteImport": 274 FileDialog fileDialog = new FileDialog("Import Palette", "palettefile", &actionEvent, [FileDialog.FileAssociationDescriptor("All supported files", ["*.png","*.tga","*.bmp"]), 275 FileDialog.FileAssociationDescriptor("Portable network graphics", ["*.png"]), FileDialog.FileAssociationDescriptor("Targa graphics file", ["*.tga"]), 276 FileDialog.FileAssociationDescriptor("Windows bitmap", ["*.bmp"])], ".\\"); 277 parent.addWindow(fileDialog); 278 break; 279 case "remove": 280 selection.removeBitmap(imageList.selection); 281 updateImageList(); 282 break; 283 default: break; 284 } 285 break; 286 } 287 } 288 private void updateFileList(){ 289 290 } 291 private void updateImageList(){ 292 293 ListBoxItem[] items; 294 for(int i; i < selection.bitmapID.length; i++){ 295 items ~= new ListBoxItem([to!dstring(selection.bitmapID[i]),to!dstring(selection.bitdepth[i]),to!dstring(selection.format[i]) 296 ,to!dstring(selection.paletteMode[i]), to!dstring(selection.getXsize(i)),to!dstring(selection.getYsize(i))]); 297 } 298 //imageList.updateColumns([ListBoxColumn("BitmapID",IDs),ListBoxColumn("Bitdepth",bt),ListBoxColumn("Format",form),ListBoxColumn("PalMode",pm)]); 299 imageList.updateColumns(items); 300 imageList.draw(); 301 } 302 private void updateAnimationList(){ 303 //wstring[] IDs, frames; 304 ListBoxItem[] items; 305 foreach(s; selection.animData.byKey){ 306 items ~= new ListBoxItem([to!dstring(s), to!dstring(selection.animData[s].ID.length)]); 307 } 308 animationList.updateColumns(items); 309 animationList.draw(); 310 } 311 private void updateFrameList(){ 312 //wstring[] num, IDs, dur; 313 ListBoxItem[] items; 314 for(int i ; i < selection.animData[animationSelection].ID.length ; i++){ 315 items ~= new ListBoxItem([to!dstring(i), to!dstring(selection.animData[animationSelection].ID[i]), to!dstring( 316 selection.animData[animationSelection].duration[i])]); 317 } 318 frameList.updateColumns(items); 319 frameList.draw(); 320 } 321 322 } 323 324 interface SheetDialogListener{ 325 public void SheetDialogEvent(string a, string b, int numFrom, int numOfDigits, int x, int y, int bitdepth, NumberingStyle ns); 326 } 327 328 public class PreviewWindow : Window{ 329 Bitmap32Bit previewImage; 330 ISpriteLayer spriteLayer; 331 ConverterDialog cd; 332 public this(Bitmap32Bit previewImage, ISpriteLayer spriteLayer, ConverterDialog cd){ 333 Coordinate size = Coordinate(0,0,previewImage.width > 78 ? previewImage.width + 2 : 80, previewImage.height + 18); 334 super(size, "Preview"); 335 spriteLayer.addSprite(previewImage, -1, 2, 18); 336 this.spriteLayer = spriteLayer; 337 this.cd = cd; 338 } 339 340 public deprecated void actionEvent(Event event) { 341 342 } 343 344 override public void move(int x,int y) { 345 spriteLayer.moveSprite(-1,x+2,y+18); 346 super.move(x,y); 347 } 348 override public void relMove(int x,int y) { 349 spriteLayer.relMoveSprite(-1,x,y); 350 super.relMove(x,y); 351 } 352 override public void close() { 353 spriteLayer.removeSprite(-1); 354 cd.previewModeOn = false; 355 super.close; 356 } 357 358 } 359