1 module spreadsheet; 2 3 import dlangui; 4 import dlangui.dialogs.filedlg; 5 import dlangui.dialogs.dialog; 6 import dlangui.widgets.spreadsheet; 7 import std.array : replaceFirst; 8 9 mixin APP_ENTRY_POINT; 10 11 // action codes 12 enum IDEActions : int { 13 //ProjectOpen = 1010000, 14 FileNew = 1010000, 15 FileOpen, 16 FileSave, 17 FileSaveAs, 18 FileSaveAll, 19 FileClose, 20 FileExit, 21 EditPreferences, 22 DebugStart, 23 HelpAbout, 24 } 25 26 // actions 27 const Action ACTION_FILE_NEW = new Action(IDEActions.FileNew, "MENU_FILE_NEW"c, "document-new", KeyCode.KEY_N, KeyFlag.Control); 28 const Action ACTION_FILE_SAVE = (new Action(IDEActions.FileSave, "MENU_FILE_SAVE"c, "document-save", KeyCode.KEY_S, KeyFlag.Control)).disableByDefault(); 29 const Action ACTION_FILE_SAVE_AS = (new Action(IDEActions.FileSaveAs, "MENU_FILE_SAVE_AS"c)).disableByDefault(); 30 const Action ACTION_FILE_OPEN = new Action(IDEActions.FileOpen, "MENU_FILE_OPEN"c, "document-open", KeyCode.KEY_O, KeyFlag.Control); 31 const Action ACTION_FILE_EXIT = new Action(IDEActions.FileExit, "MENU_FILE_EXIT"c, "document-close"c, KeyCode.KEY_X, KeyFlag.Alt); 32 const Action ACTION_EDIT_COPY = (new Action(EditorActions.Copy, "MENU_EDIT_COPY"c, "edit-copy"c, KeyCode.KEY_C, KeyFlag.Control)).addAccelerator(KeyCode.INS, KeyFlag.Control).disableByDefault(); 33 const Action ACTION_EDIT_PASTE = (new Action(EditorActions.Paste, "MENU_EDIT_PASTE"c, "edit-paste"c, KeyCode.KEY_V, KeyFlag.Control)).addAccelerator(KeyCode.INS, KeyFlag.Shift).disableByDefault(); 34 const Action ACTION_EDIT_CUT = (new Action(EditorActions.Cut, "MENU_EDIT_CUT"c, "edit-cut"c, KeyCode.KEY_X, KeyFlag.Control)).addAccelerator(KeyCode.DEL, KeyFlag.Shift).disableByDefault(); 35 const Action ACTION_EDIT_UNDO = (new Action(EditorActions.Undo, "MENU_EDIT_UNDO"c, "edit-undo"c, KeyCode.KEY_Z, KeyFlag.Control)).disableByDefault(); 36 const Action ACTION_EDIT_REDO = (new Action(EditorActions.Redo, "MENU_EDIT_REDO"c, "edit-redo"c, KeyCode.KEY_Y, KeyFlag.Control)).addAccelerator(KeyCode.KEY_Z, KeyFlag.Control|KeyFlag.Shift).disableByDefault(); 37 const Action ACTION_EDIT_INDENT = (new Action(EditorActions.Indent, "MENU_EDIT_INDENT"c, "edit-indent"c, KeyCode.TAB, 0)).addAccelerator(KeyCode.KEY_BRACKETCLOSE, KeyFlag.Control).disableByDefault(); 38 const Action ACTION_EDIT_UNINDENT = (new Action(EditorActions.Unindent, "MENU_EDIT_UNINDENT"c, "edit-unindent", KeyCode.TAB, KeyFlag.Shift)).addAccelerator(KeyCode.KEY_BRACKETOPEN, KeyFlag.Control).disableByDefault(); 39 const Action ACTION_EDIT_TOGGLE_LINE_COMMENT = (new Action(EditorActions.ToggleLineComment, "MENU_EDIT_TOGGLE_LINE_COMMENT"c, null, KeyCode.KEY_DIVIDE, KeyFlag.Control)).disableByDefault(); 40 const Action ACTION_EDIT_TOGGLE_BLOCK_COMMENT = (new Action(EditorActions.ToggleBlockComment, "MENU_EDIT_TOGGLE_BLOCK_COMMENT"c, null, KeyCode.KEY_DIVIDE, KeyFlag.Control|KeyFlag.Shift)).disableByDefault(); 41 const Action ACTION_EDIT_PREFERENCES = (new Action(IDEActions.EditPreferences, "MENU_EDIT_PREFERENCES"c, null)).disableByDefault(); 42 const Action ACTION_DEBUG_START = new Action(IDEActions.DebugStart, "MENU_DEBUG_UPDATE_PREVIEW"c, "debug-run"c, KeyCode.F5, 0); 43 const Action ACTION_HELP_ABOUT = new Action(IDEActions.HelpAbout, "MENU_HELP_ABOUT"c); 44 45 class EditFrame : AppFrame { 46 47 MenuItem mainMenuItems; 48 49 override protected void initialize() { 50 _appName = "DlangUISpreadSheet"; 51 super.initialize(); 52 } 53 54 /// create main menu 55 override protected MainMenu createMainMenu() { 56 mainMenuItems = new MenuItem(); 57 MenuItem fileItem = new MenuItem(new Action(1, "MENU_FILE")); 58 fileItem.add(ACTION_FILE_NEW, ACTION_FILE_OPEN, 59 ACTION_FILE_EXIT); 60 mainMenuItems.add(fileItem); 61 MenuItem editItem = new MenuItem(new Action(2, "MENU_EDIT")); 62 editItem.add(ACTION_EDIT_COPY, ACTION_EDIT_PASTE, 63 ACTION_EDIT_CUT, ACTION_EDIT_UNDO, ACTION_EDIT_REDO, 64 ACTION_EDIT_INDENT, ACTION_EDIT_UNINDENT, ACTION_EDIT_TOGGLE_LINE_COMMENT, ACTION_EDIT_TOGGLE_BLOCK_COMMENT, ACTION_DEBUG_START); 65 66 editItem.add(ACTION_EDIT_PREFERENCES); 67 mainMenuItems.add(editItem); 68 MainMenu mainMenu = new MainMenu(mainMenuItems); 69 return mainMenu; 70 } 71 72 73 /// create app toolbars 74 override protected ToolBarHost createToolbars() { 75 ToolBarHost res = new ToolBarHost(); 76 ToolBar tb; 77 tb = res.getOrAddToolbar("Standard"); 78 tb.addButtons(ACTION_FILE_NEW, ACTION_FILE_OPEN, ACTION_FILE_SAVE, ACTION_SEPARATOR, ACTION_DEBUG_START); 79 80 tb = res.getOrAddToolbar("Edit"); 81 tb.addButtons(ACTION_EDIT_COPY, ACTION_EDIT_PASTE, ACTION_EDIT_CUT, ACTION_SEPARATOR, 82 ACTION_EDIT_UNDO, ACTION_EDIT_REDO, ACTION_EDIT_INDENT, ACTION_EDIT_UNINDENT); 83 return res; 84 } 85 86 string _filename; 87 void openSourceFile(string filename) { 88 import std.file; 89 // TODO 90 if (exists(filename)) { 91 _filename = filename; 92 window.windowCaption = toUTF32(filename); 93 //_editor.load(filename); 94 //updatePreview(); 95 } 96 } 97 98 void saveSourceFile(string filename) { 99 if (filename.length == 0) 100 filename = _filename; 101 //import std.file; 102 //_filename = filename; 103 //window.windowCaption = toUTF32(filename); 104 //_editor.save(filename); 105 } 106 107 bool onCanClose() { 108 // todo 109 return true; 110 } 111 112 FileDialog createFileDialog(UIString caption, bool fileMustExist = true) { 113 uint flags = DialogFlag.Modal | DialogFlag.Resizable; 114 if (fileMustExist) 115 flags |= FileDialogFlag.FileMustExist; 116 FileDialog dlg = new FileDialog(caption, window, null, flags); 117 dlg.filetypeIcons[".d"] = "text-dml"; 118 return dlg; 119 } 120 121 void saveAs() { 122 } 123 124 /// override to handle specific actions 125 override bool handleAction(const Action a) { 126 if (a) { 127 switch (a.id) { 128 case IDEActions.FileExit: 129 if (onCanClose()) 130 window.close(); 131 return true; 132 case IDEActions.HelpAbout: 133 window.showMessageBox(UIString.fromRaw("About DlangUI ML Editor"d), 134 UIString.fromRaw("DLangIDE\n(C) Vadim Lopatin, 2015\nhttp://github.com/buggins/dlangui\nSimple editor for DML code"d)); 135 return true; 136 case IDEActions.FileNew: 137 UIString caption; 138 caption = "Create new DML file"d; 139 FileDialog dlg = createFileDialog(caption, false); 140 dlg.addFilter(FileFilterEntry(UIString.fromRaw("DML files"d), "*.dml")); 141 dlg.addFilter(FileFilterEntry(UIString.fromRaw("All files"d), "*.*")); 142 dlg.dialogResult = delegate(Dialog dlg, const Action result) { 143 if (result.id == ACTION_OPEN.id) { 144 string filename = result.stringParam; 145 //_editor.text=""d; 146 saveSourceFile(filename); 147 } 148 }; 149 dlg.show(); 150 return true; 151 case IDEActions.FileSave: 152 if (_filename.length) { 153 saveSourceFile(_filename); 154 return true; 155 } 156 UIString caption; 157 caption = "Save DML File as"d; 158 FileDialog dlg = createFileDialog(caption, false); 159 dlg.addFilter(FileFilterEntry(UIString.fromRaw("DML files"d), "*.dml")); 160 dlg.addFilter(FileFilterEntry(UIString.fromRaw("All files"d), "*.*")); 161 dlg.dialogResult = delegate(Dialog dlg, const Action result) { 162 if (result.id == ACTION_OPEN.id) { 163 string filename = result.stringParam; 164 saveSourceFile(filename); 165 } 166 }; 167 dlg.show(); 168 return true; 169 case IDEActions.FileOpen: 170 UIString caption; 171 caption = "Open DML File"d; 172 FileDialog dlg = createFileDialog(caption); 173 dlg.addFilter(FileFilterEntry(UIString.fromRaw("DML files"d), "*.dml")); 174 dlg.addFilter(FileFilterEntry(UIString.fromRaw("All files"d), "*.*")); 175 dlg.dialogResult = delegate(Dialog dlg, const Action result) { 176 if (result.id == ACTION_OPEN.id) { 177 string filename = result.stringParam; 178 openSourceFile(filename); 179 } 180 }; 181 dlg.show(); 182 return true; 183 case IDEActions.DebugStart: 184 return true; 185 case IDEActions.EditPreferences: 186 //showPreferences(); 187 return true; 188 default: 189 return super.handleAction(a); 190 } 191 } 192 return false; 193 } 194 195 /// override to handle specific actions state (e.g. change enabled state for supported actions) 196 override bool handleActionStateRequest(const Action a) { 197 switch (a.id) { 198 case IDEActions.HelpAbout: 199 case IDEActions.FileNew: 200 case IDEActions.FileSave: 201 case IDEActions.FileOpen: 202 case IDEActions.DebugStart: 203 case IDEActions.EditPreferences: 204 a.state = ACTION_STATE_ENABLED; 205 return true; 206 default: 207 return super.handleActionStateRequest(a); 208 } 209 } 210 211 SpreadSheetWidget _spreadsheet; 212 213 /// create app body widget 214 override protected Widget createBody() { 215 VerticalLayout bodyWidget = new VerticalLayout(); 216 bodyWidget.layoutWidth = FILL_PARENT; 217 bodyWidget.layoutHeight = FILL_PARENT; 218 _spreadsheet = new SpreadSheetWidget(); 219 bodyWidget.addChild(_spreadsheet); 220 return bodyWidget; 221 } 222 223 } 224 225 /// entry point for dlangui based application 226 extern (C) int UIAppMain(string[] args) { 227 228 // embed non-standard resources listed in views/resources.list into executable 229 embeddedResourceList.addResources(embedResourcesFromList!("resources.list")()); 230 231 /// set font gamma (1.0 is neutral, < 1.0 makes glyphs lighter, >1.0 makes glyphs bolder) 232 FontManager.fontGamma = 0.8; 233 FontManager.hintingMode = HintingMode.Normal; 234 235 // select translation file - for english language 236 Platform.instance.uiLanguage = "en"; 237 // load theme from file "theme_custom.xml" 238 Platform.instance.uiTheme = "theme_custom"; 239 240 // create window 241 Window window = Platform.instance.createWindow("DlangUI SpreadSheet example"d, null, WindowFlag.Resizable, 700, 470); 242 243 // create some widget to show in window 244 window.windowIcon = drawableCache.getImage("dlangui-logo1"); 245 246 FontRef font = FontManager.instance.getFont(24, 300, false, FontFamily.SansSerif, "Arial"); 247 Log.d("font found: ", font.face); 248 font = FontManager.instance.getFont(24, 300, false, FontFamily.Serif, "Times New Roman"); 249 Log.d("font found: ", font.face); 250 251 // create some widget to show in window 252 window.mainWidget = new EditFrame(); 253 254 // show window 255 window.show(); 256 257 // run message loop 258 return Platform.instance.enterMessageLoop(); 259 }