mirror of https://github.com/buggins/dlangui.git
349 lines
9.5 KiB
D
349 lines
9.5 KiB
D
module dlearn;
|
||
|
||
import dlangui;
|
||
import dlangui.core.logger;
|
||
import dlangui.dialogs.filedlg;
|
||
import dlangui.dialogs.dialog;
|
||
import dlangui.dml.dmlhighlight;
|
||
import dlangui.widgets.metadata;
|
||
import std.array : replaceFirst;
|
||
import std.algorithm;
|
||
import std.process;
|
||
import std.stdio;
|
||
import std.array;
|
||
import std.file;
|
||
import std.path;
|
||
|
||
import dlangui.dialogs.settingsdialog;
|
||
import settings;
|
||
import appSettings;
|
||
|
||
mixin APP_ENTRY_POINT;
|
||
|
||
enum IDEActions : int {
|
||
About = 1010000,
|
||
Lang
|
||
}
|
||
|
||
dstring SAMPLE_SOURCE_CODE = q{import std.stdio;
|
||
import std.path;
|
||
import std.file;
|
||
import std.string;
|
||
import std.algorithm;
|
||
import std.array;
|
||
import std.conv;
|
||
import std.typecons;
|
||
|
||
int main() {
|
||
|
||
|
||
writeln("Ok!");
|
||
return 0;
|
||
}
|
||
};
|
||
|
||
const Action ACTION_ABOUT = new Action(IDEActions.About, "MENU_ABOUT"c, "document-about", KeyCode.KEY_A, KeyFlag.Control);
|
||
const Action ACTION_LANG = new Action(IDEActions.Lang, "MENU_LANG"c, "document-lang", KeyCode.KEY_L, KeyFlag.Control);
|
||
|
||
string BUTTONS_CODE = q{
|
||
HorizontalLayout {
|
||
layoutWidth: FILL_PARENT
|
||
layoutHeight: 20
|
||
alignment: HCenter
|
||
|
||
Button { id: btnRun; text: "compile/run";
|
||
margins: Rect { left: 60; right: 0; top: 20; bottom: 20}
|
||
layoutWidth: 180; layoutHeight: 20 }
|
||
Button { id: btnReset; text: "reset"; padding: 0;
|
||
margins: Rect { left: 80; right: 0; top: 20; bottom: 20 }
|
||
layoutWidth: 200; layoutHeight: 20 }
|
||
|
||
Button { id: btnSave; text: "save"; padding: 0;
|
||
margins: Rect { left: 80; right: 0; top: 20; bottom: 20 }
|
||
layoutWidth: 200; layoutHeight: 20 }
|
||
}
|
||
};
|
||
|
||
immutable string RESULT_WIDGET = `
|
||
MultilineTextWidget {
|
||
/* this widget can be accessed via id myLabel1
|
||
e.g. w.childById!TextWidget("myLabel1")
|
||
*/
|
||
id: logTxtWidget
|
||
text: ""
|
||
padding: 5
|
||
layoutWidth: FILL_PARENT
|
||
layoutHeight: 100
|
||
//readonly: true
|
||
}
|
||
`;
|
||
|
||
string cacheFile;
|
||
|
||
class DMLSourceEdit : SourceEdit {
|
||
this(string ID) {
|
||
super(ID);
|
||
|
||
content.syntaxSupport = new DMLSyntaxSupport("");
|
||
setTokenHightlightColor(TokenCategory.Comment, 0x008000); // green
|
||
setTokenHightlightColor(TokenCategory.Keyword, 0x0000FF); // blue
|
||
setTokenHightlightColor(TokenCategory.String, 0xa31515); // brown
|
||
setTokenHightlightColor(TokenCategory.Integer, 0xa315C0); //
|
||
setTokenHightlightColor(TokenCategory.Float, 0xa315C0); //
|
||
setTokenHightlightColor(TokenCategory.Error, 0xFF0000); // red
|
||
setTokenHightlightColor(TokenCategory.Op, 0x503000);
|
||
setTokenHightlightColor(TokenCategory.Identifier_Class, 0x000080); // blue
|
||
|
||
}
|
||
this() {
|
||
this("Dlearn");
|
||
}
|
||
}
|
||
|
||
|
||
class MainFrame : AppFrame {
|
||
|
||
MenuItem mainMenuItems;
|
||
AppSettings _settings;
|
||
|
||
override protected void initialize() {
|
||
_appName = "DLearn";
|
||
super.initialize();
|
||
}
|
||
|
||
this(Window window) {
|
||
_settings = new AppSettings(buildNormalizedPath(settingsDir, "dlearnrc.json"));
|
||
cacheFile = buildNormalizedPath(settingsDir, "dlearn_ini.d");
|
||
applySettings(_settings);
|
||
|
||
super();
|
||
}
|
||
|
||
~this() {
|
||
// if (_dcdInterface) {
|
||
// destroy(_dcdInterface);
|
||
// _dcdInterface = null;
|
||
// }
|
||
}
|
||
|
||
/// create main menu
|
||
override protected MainMenu createMainMenu() {
|
||
mainMenuItems = new MenuItem();
|
||
|
||
MenuItem aboutMenu = new MenuItem(new Action(1, "MENU_ABOUT"));
|
||
aboutMenu.add(ACTION_ABOUT);
|
||
mainMenuItems.add(aboutMenu);
|
||
|
||
MenuItem langMenu = new MenuItem(new Action(2, "MENU_LANG"));
|
||
langMenu.add(ACTION_LANG);
|
||
mainMenuItems.add(langMenu);
|
||
|
||
MainMenu mainMenu = new MainMenu(mainMenuItems);
|
||
|
||
return mainMenu;
|
||
}
|
||
|
||
void applySettings(AppSettings settings) {
|
||
Platform.instance.uiLanguage = settings.uiLanguage;
|
||
//Log.d("settings.uiLanguage=");
|
||
//Log.d(settings.uiLanguage);
|
||
//Platform.instance.uiLanguage = "cn";
|
||
requestLayout();
|
||
}
|
||
|
||
override bool handleAction(const Action a) {
|
||
if (!a) {
|
||
return false;
|
||
}
|
||
switch (a.id) {
|
||
case IDEActions.About:
|
||
window.showMessageBox(UIString.fromId("ABOUT"), UIString.fromId("ABOUT_TEXT"));
|
||
return true;
|
||
case IDEActions.Lang:
|
||
showPreferences();
|
||
return true;
|
||
default:
|
||
return super.handleAction(a);
|
||
}
|
||
//return false;
|
||
}
|
||
|
||
override protected ToolBarHost createToolbars() {
|
||
ToolBarHost res = new ToolBarHost();
|
||
ToolBar tb;
|
||
tb = res.getOrAddToolbar("About");
|
||
tb.addButtons(ACTION_ABOUT);
|
||
|
||
tb = res.getOrAddToolbar("Lang");
|
||
tb.addButtons(ACTION_LANG);
|
||
|
||
return res;
|
||
}
|
||
|
||
string _filename;
|
||
void openSourceFile(string filename) {
|
||
import std.file;
|
||
// TODO
|
||
if (exists(filename)) {
|
||
_filename = filename;
|
||
window.windowCaption = toUTF32(filename);
|
||
_editor.load(filename);
|
||
}
|
||
}
|
||
|
||
void saveSourceFile(string filename) {
|
||
if (filename.length == 0)
|
||
filename = _filename;
|
||
import std.file;
|
||
_filename = filename;
|
||
window.windowCaption = toUTF32(filename);
|
||
_editor.save(filename);
|
||
}
|
||
|
||
bool onCanClose() {
|
||
// todo
|
||
return true;
|
||
}
|
||
|
||
void showPreferences() {
|
||
Setting s = _settings.copySettings();
|
||
SettingsDialog dlg = new SettingsDialog(UIString.fromId("HEADER_SETTINGS"), window, s, createSettingsPages());
|
||
dlg.dialogResult = delegate(Dialog dlg, const Action result) {
|
||
if (result.id == ACTION_APPLY.id) {
|
||
_settings.applySettings(s);
|
||
applySettings(_settings);
|
||
_settings.save();
|
||
}
|
||
};
|
||
dlg.show();
|
||
}
|
||
|
||
protected DMLSourceEdit _editor;
|
||
// protected ScrollWidget _preview;
|
||
|
||
void setText(Widget w, string text) {
|
||
w.text(toUTF32(text.replace("\r\n", "\n")));
|
||
}
|
||
|
||
override protected Widget createBody() {
|
||
auto dockHost = new DockHost();
|
||
dockHost.layoutWidth = FILL_PARENT;
|
||
dockHost.layoutHeight = FILL_PARENT;
|
||
dockHost.alignment = Align.Top;
|
||
|
||
auto ml = parseML(RESULT_WIDGET);
|
||
auto topFrame = parseML(BUTTONS_CODE);
|
||
|
||
_editor = new DMLSourceEdit();
|
||
_editor.text = getCacheText();
|
||
_editor.layoutHeight = 200;
|
||
|
||
auto resultDockWin = new DockWindow("result"); // false: don't show close button
|
||
resultDockWin.bodyWidget = ml;
|
||
resultDockWin.dockAlignment = DockAlignment.Bottom;
|
||
resultDockWin.layoutHeight = makePercentSize(40);
|
||
resultDockWin.layoutWidth = FILL_PARENT;
|
||
resultDockWin.caption.text = UIString.fromId("RESULT") ~ ":";
|
||
|
||
auto topDockWin = new DockWindow("top");
|
||
topDockWin.bodyWidget = topFrame;
|
||
topDockWin.dockAlignment = DockAlignment.Top;
|
||
topDockWin.layoutHeight = makePercentSize(10);
|
||
topDockWin.layoutWidth = FILL_PARENT;
|
||
topDockWin.caption.text = UIString.fromId("BUTTONS") ~ ":";
|
||
|
||
dockHost.addDockedWindow(topDockWin);
|
||
dockHost.bodyWidget = _editor;
|
||
dockHost.addDockedWindow(resultDockWin);
|
||
|
||
auto logTxtWidget = ml.childById!TextWidget("logTxtWidget");
|
||
|
||
auto btnSave = topFrame.childById!Button("btnSave");
|
||
btnSave.text = UIString.fromId("SAVE");
|
||
btnSave.click = delegate(Widget srcWidget) {
|
||
auto fp = new File(cacheFile, "w");
|
||
fp.write(_editor.text);
|
||
setText(logTxtWidget, "Saved: " ~ cacheFile);
|
||
return true;
|
||
};
|
||
|
||
auto btnRun = topFrame.childById!Button("btnRun");
|
||
btnRun.text = UIString.fromId("COMPILE_AND_RUN");
|
||
|
||
btnRun.click = delegate(Widget srcWidget) {
|
||
auto tmpDir = std.file.tempDir();
|
||
auto tmp_filename = buildPath(tmpDir, "aa.d");
|
||
|
||
this.saveSourceFile(tmp_filename);
|
||
|
||
auto tmp_exeFile = tmp_filename ~ ".exe";
|
||
|
||
logTxtWidget.text = " ";
|
||
|
||
try {
|
||
auto result0 = execute(["dmd", tmp_filename, "-of=" ~ tmp_exeFile],
|
||
null, Config.suppressConsole);
|
||
|
||
setText(logTxtWidget, result0.output);
|
||
|
||
Log.i("dmd result: ", result0.output);
|
||
if (result0.status != 0) {
|
||
return false;
|
||
}
|
||
} catch (Exception e) {
|
||
setText(logTxtWidget, "编译出错:" ~ e.toString());
|
||
return false;
|
||
}
|
||
|
||
|
||
if (exists(tmp_exeFile)) {
|
||
try {
|
||
auto result1 = execute([tmp_exeFile], null, Config.suppressConsole);
|
||
setText(logTxtWidget, "\n\n" ~ result1.output);
|
||
if (result1.status != 0) {
|
||
return false;
|
||
}
|
||
} catch (Exception e) {
|
||
setText(logTxtWidget, UIString.fromId("ERROR").to!string ~ ":" ~ e.toString());
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
auto btnReset = topFrame.childById!Button("btnReset");
|
||
btnReset.text = UIString.fromId("RESET");
|
||
|
||
btnReset.click = delegate(Widget srcWidget) {
|
||
_editor.text = getCacheText();
|
||
return true;
|
||
};
|
||
|
||
return dockHost;
|
||
}
|
||
}
|
||
|
||
dstring getCacheText() {
|
||
if (exists(cacheFile)) {
|
||
return readText(cacheFile).to!dstring;
|
||
} else {
|
||
return SAMPLE_SOURCE_CODE;
|
||
}
|
||
}
|
||
|
||
extern (C) int UIAppMain(string[] args) {
|
||
embeddedResourceList.addResources(embedResourcesFromList!("resources.list")());
|
||
FontManager.fontGamma = 0.8;
|
||
FontManager.hintingMode = HintingMode.Normal;
|
||
|
||
Window window = Platform.instance.createWindow("Dlang Learn"d, null,
|
||
WindowFlag.Resizable, 500, 500);
|
||
|
||
window.windowIcon = drawableCache.getImage("dlangui-logo1");
|
||
window.mainWidget = new MainFrame(window);
|
||
|
||
window.show();
|
||
return Platform.instance.enterMessageLoop();
|
||
}
|