DML editor sample

This commit is contained in:
Vadim Lopatin 2015-04-02 11:53:28 +03:00
parent f0a615ed82
commit 5b67dbde81
9 changed files with 141 additions and 18 deletions

View File

@ -1,6 +1,8 @@
module dmledit;
import dlangui;
import dlangui.dialogs.filedlg;
import dlangui.dialogs.dialog;
mixin APP_ENTRY_POINT;
@ -15,6 +17,8 @@ enum IDEActions : int {
FileClose,
FileExit,
EditPreferences,
DebugStart,
HelpAbout,
}
// actions
@ -33,6 +37,8 @@ const Action ACTION_EDIT_UNINDENT = (new Action(EditorActions.Unindent, "MENU_ED
const Action ACTION_EDIT_TOGGLE_LINE_COMMENT = (new Action(EditorActions.ToggleLineComment, "MENU_EDIT_TOGGLE_LINE_COMMENT"c, null, KeyCode.KEY_DIVIDE, KeyFlag.Control)).disableByDefault();
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();
const Action ACTION_EDIT_PREFERENCES = (new Action(IDEActions.EditPreferences, "MENU_EDIT_PREFERENCES"c, null)).disableByDefault();
const Action ACTION_DEBUG_START = new Action(IDEActions.DebugStart, "MENU_DEBUG_START_DEBUGGING"c, "debug-run"c, KeyCode.F5, 0);
const Action ACTION_HELP_ABOUT = new Action(IDEActions.HelpAbout, "MENU_HELP_ABOUT"c);
class EditFrame : AppFrame {
@ -44,19 +50,18 @@ class EditFrame : AppFrame {
}
/// create main menu
override protected MainMenu createMainMenu() {
return new MainMenu(new MenuItem());
mainMenuItems = new MenuItem();
MenuItem fileItem = new MenuItem(new Action(1, "MENU_FILE"));
fileItem.add(ACTION_FILE_NEW, ACTION_FILE_OPEN,
ACTION_FILE_EXIT);
mainMenuItems.add(fileItem);
MenuItem editItem = new MenuItem(new Action(2, "MENU_EDIT"));
editItem.add(ACTION_EDIT_COPY, ACTION_EDIT_PASTE,
ACTION_EDIT_CUT, ACTION_EDIT_UNDO, ACTION_EDIT_REDO,
ACTION_EDIT_INDENT, ACTION_EDIT_UNINDENT, ACTION_EDIT_TOGGLE_LINE_COMMENT, ACTION_EDIT_TOGGLE_BLOCK_COMMENT);
editItem.add(ACTION_EDIT_PREFERENCES);
mainMenuItems.add(editItem);
MainMenu mainMenu = new MainMenu(mainMenuItems);
return mainMenu;
}
@ -67,7 +72,7 @@ class EditFrame : AppFrame {
ToolBarHost res = new ToolBarHost();
ToolBar tb;
tb = res.getOrAddToolbar("Standard");
tb.addButtons(ACTION_FILE_NEW, ACTION_FILE_OPEN, ACTION_FILE_SAVE);
tb.addButtons(ACTION_FILE_NEW, ACTION_FILE_OPEN, ACTION_FILE_SAVE, ACTION_SEPARATOR, ACTION_DEBUG_START);
tb = res.getOrAddToolbar("Edit");
tb.addButtons(ACTION_EDIT_COPY, ACTION_EDIT_PASTE, ACTION_EDIT_CUT, ACTION_SEPARATOR,
@ -75,20 +80,117 @@ class EditFrame : AppFrame {
return res;
}
string _filename;
void openSourceFile(string filename) {
// TODO
_filename = filename;
}
bool onCanClose() {
// todo
return true;
}
FileDialog createFileDialog(UIString caption) {
FileDialog dlg = new FileDialog(caption, window, null);
dlg.filetypeIcons[".d"] = "text-dml";
return dlg;
}
/// override to handle specific actions
override bool handleAction(const Action a) {
if (a) {
switch (a.id) {
case IDEActions.FileExit:
if (onCanClose())
window.close();
return true;
case IDEActions.HelpAbout:
window.showMessageBox(UIString("About DlangUI ML Editor"d),
UIString("DLangIDE\n(C) Vadim Lopatin, 2015\nhttp://github.com/buggins/dlangui\nSimple editor for DML code"d));
return true;
case IDEActions.FileOpen:
UIString caption;
caption = "Open DML File"d;
FileDialog dlg = createFileDialog(caption);
dlg.addFilter(FileFilterEntry(UIString("DML files"d), "*.dml"));
dlg.addFilter(FileFilterEntry(UIString("All files"d), "*.*"));
dlg.onDialogResult = delegate(Dialog dlg, const Action result) {
if (result.id == ACTION_OPEN.id) {
string filename = result.stringParam;
openSourceFile(filename);
}
};
dlg.show();
return true;
case IDEActions.DebugStart:
updatePreview();
return true;
case IDEActions.EditPreferences:
//showPreferences();
return true;
default:
return super.handleAction(a);
}
}
return false;
}
void updatePreview() {
dstring dsource = _editor.text;
string source = toUTF8(dsource);
try {
Widget w = parseML(source);
statusLine.setStatusText("No errors"d);
_preview.contentWidget = w;
} catch (ParserException e) {
statusLine.setStatusText(toUTF32("ERROR: " ~ e.msg));
_editor.setCaretPos(e.line, e.pos);
}
}
protected SourceEdit _editor;
protected ScrollWidget _preview;
/// create app body widget
override protected Widget createBody() {
VerticalLayout bodyWidget = new VerticalLayout();
bodyWidget.layoutWidth = FILL_PARENT;
bodyWidget.layoutHeight = FILL_PARENT;
HorizontalLayout hlayout = new HorizontalLayout();
hlayout.layoutWidth = makePercentSize(50);
hlayout.layoutWidth = FILL_PARENT;
hlayout.layoutHeight = FILL_PARENT;
SourceEdit editor = new SourceEdit();
hlayout.addChild(editor);
ScrollWidget preview = new ScrollWidget();
preview.layoutWidth = FILL_PARENT;
preview.layoutHeight = FILL_PARENT;
hlayout.addChild(preview);
_editor = new SourceEdit();
hlayout.addChild(_editor);
_editor.text = q{
VerticalLayout {
id: vlayout
margins: Rect { left: 5; right: 3; top: 2; bottom: 4 }
padding: Rect { 5, 4, 3, 2 } // same as Rect { left: 5; top: 4; right: 3; bottom: 2 }
TextWidget {
/* this widget can be accessed via id myLabel1
e.g. w.childById!TextWidget("myLabel1")
*/
id: myLabel1
text: "Some text"; padding: 5
enabled: false
}
TextWidget {
id: myLabel2
text: "More text"; margins: 5
enabled: true
}
CheckBox{ id: cb1; text: "Some checkbox" }
HorizontalLayout {
RadioButton{ id: rb1; text: "Radio Button 1" }
RadioButton{ id: rb1; text: "Radio Button 2" }
}
}
};
_preview = new ScrollWidget();
_preview.layoutWidth = makePercentSize(50);
_preview.layoutHeight = FILL_PARENT;
_preview.backgroundImageId = "tx_fabric.tiled";
hlayout.addChild(_preview);
bodyWidget.addChild(hlayout);
return bodyWidget;
}

View File

@ -1,5 +1,6 @@
EXIT=Exit
MENU_FILE=&File
MENU_FILE_NEW=&New
MENU_FILE_OPEN=&Open
MENU_FILE_OPEN_RECENT=Open recent
MENU_FILE_SAVE=&Save
@ -12,6 +13,8 @@ MENU_EDIT_UNDO=&Undo
MENU_EDIT_REDO=&Redo
MENU_EDIT_INDENT=Indent block
MENU_EDIT_UNINDENT=Unindent block
MENU_EDIT_TOGGLE_LINE_COMMENT=Toggle line comment
MENU_EDIT_TOGGLE_BLOCK_COMMENT=Toggle block comment
MENU_EDIT_PREFERENCES=&Preferences
MENU_VIEW=&View
MENU_VIEW_LANGUAGE=Interface &Language

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -1,6 +1,7 @@
res/i18n/en.ini
res/i18n/ru.ini
res/mdpi/cr3_logo.png
res/mdpi/debug-run.png
res/mdpi/document-close.png
res/mdpi/document-new.png
res/mdpi/document-open-recent.png
@ -15,3 +16,5 @@ res/mdpi/edit-paste.png
res/mdpi/edit-redo.png
res/mdpi/edit-undo.png
res/mdpi/edit-unindent.png
res/mdpi/text-dml.png
res/mdpi/tx_fabric.jpg

View File

@ -584,19 +584,21 @@ class MLParser {
}
protected void setStringProperty(string propName, string value) {
if (propName.equal("id")) {
if (propName.equal("id") || propName.equal("styleId") || propName.equal("backgroundImageId")) {
if (!_currentWidget.setStringProperty(propName, value))
error("cannot set id property for widget");
error("cannot set " ~ propName ~ " property for widget");
return;
}
dstring v = toUTF32(value);
if (!_currentWidget.setDstringProperty(propName, v))
error("unknown string property " ~ propName);
if (!_currentWidget.setDstringProperty(propName, v)) {
if (!_currentWidget.setStringProperty(propName, value))
error("unknown string property " ~ propName);
}
}
protected void setIdentProperty(string propName, string value) {
if (propName.equal("id")) {
if (propName.equal("id") || propName.equal("styleId") || propName.equal("backgroundImageId")) {
if (!_currentWidget.setStringProperty(propName, value))
error("cannot set id property for widget");
return;

View File

@ -1475,7 +1475,20 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
return super.onMouseEvent(event);
}
/// returns caret position
@property TextPosition caretPos() {
return _caretPos;
}
/// change caret position and ensure it is visible
void setCaretPos(int line, int column, bool makeVisible = true)
{
_caretPos = TextPosition(line,column);
correctCaretPos();
invalidate();
if (makeVisible)
ensureCaretVisible();
}
}
interface EditorActionHandler {

View File

@ -1228,7 +1228,7 @@ class Widget {
else if (!isSpecialSize(lh))
dy = lh;
if (isPercentSize(lw) && parentWidth != SIZE_UNSPECIFIED)
dy = fromPercentSize(lw, parentWidth);
dx = fromPercentSize(lw, parentWidth);
else if (!isSpecialSize(lw))
dx = lw;
// apply min/max width and height constraints
@ -1479,7 +1479,7 @@ class Widget {
/// set string property value, for ML loaders
bool setStringProperty(string name, string value) {
mixin(generatePropertySetters("id"));
mixin(generatePropertySetters("id", "styleId", "backgroundImageId"));
if (name.equal("text")) {
text = UIString(value);
return true;