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 }