Posts: 316
Threads: 39
Joined: Nov 2023
Reputation:
3
This release contains a first version of the enginea library, meant for sector based first person shooter games. This is far from the final version of the library; support for meshes is very basic and has not been tested much.
https://naalaa.com/n7/N7_240629.zip
2024-06-29- Added the enginea library and editor (enginea_editor.exe), for sector based first person shooter games, plus a tutorial (EngineA_Tutorial.pdf) and examples in examples/enginea_library
Posts: 300
Threads: 30
Joined: Nov 2023
Reputation:
3
Cool... Great job... One small - cosmetic - issue... When selecting "Help/About" the version displayed it 24.02.16... Not a "deal breaker"... just me being a little "picky"... Moo Ha Ha Ha...
Logic is the beginning of wisdom.
Posts: 190
Threads: 20
Joined: Nov 2023
Reputation:
0
(06-29-2024, 07:57 PM)johnno56 Wrote: Cool... Great job... One small - cosmetic - issue... When selecting "Help/About" the version displayed it 24.02.16... Not a "deal breaker"... just me being a little "picky"... Moo Ha Ha Ha...
Save this code below as ned.n7, compile it and you will get newer version 24.06.29
Code: ' NED - NaaLaa Editor
' -------------------
' By Marcus 2022 - 2023.
#win32
include "ngui.n7"
include "file.n7"
include "qsort.n7"
' Version.
constant vVersion = "24.06.29"
' Path and files.
visible vPath
visible vDataPath
visible vCompiler = "n7.exe"
visible vDLLs = ["libwinpthread-1.dll", "libportaudio.dll"]
' Themes.
visible vThemes
' Widgets.
visible vEditorTabs, vEditor, vEditorInfoLabel, vOutput, vOutputLabel
visible vFindBar, vReplaceBar, vGotoBar
visible vFindTextEntry
visible vReplaceTextEntry, vReplaceWithTextEntry
visible vGotoTextEntry
visible vEdBoxCloseRequest
' Settings.
'visible vDarkMode = false
visible vTheme = "Default light"
visible vFindCaseSensitive = false
visible vReplaceCaseSensitive = false
visible vEditorFontName = "Courier New"
visible vEdFontSize = 16
visible vHiddenOutput = false
visible vHiddenFunctionList = false
' Command help.
visible vCommandSyntax = unset, vCommandFile = unset
' Only allow one running instance of NED.
if window("NED")
' Tell existing window to open the file or just bring the window to front.
if sizeof(args) > 1 SendWindowMessage("NED", args[1])
else SendWindowMessage("NED", "show")
' Terminate this instance.
end
endif
' Save path of executable. If you associate n7 files with ned, the current
' working directory may be wrong when ned is launched.
vPath = GetPath(args[0])
vDataPath = GetPathCombined(GetAppDataDirectory(), "naalaa7")
CreateDirectory(vDataPath)
' Create themes list.
vThemes = []
AddToList(vThemes, [name: "Default light", filename: unset])
AddToList(vThemes, [name: "Default dark", filename: unset])
files = GetFiles(GetPathCombined(GetPathCombined(vPath, "assets"), "themes"))
if files for i = 0 to sizeof(files) - 1
AddToList(vThemes, [name: GetFilename(files[i], false), filename: files[i]])
next
' Load command help.
LoadCommandHelp(GetPathCombined(GetPathCombined(vPath, "assets"), "command_help.txt"))
' Create a resizable window.
w = screenw()*2/3
h = screenh()*2/3
set window "NED", w, h, false, 0, min(w, 640), min(h, 480)
set redraw off
' Load settings.
settings = LoadSettings()
documents = settings.docs
for i = 0 to sizeof(vThemes) - 1 if vThemes[i].name = vTheme
vTheme = vThemes[i]
break
endif
if i >= sizeof(vThemes) vTheme = vThemes[0]
if vTheme.filename LoadTheme(vTheme.filename)
else if vTheme.name = "Default light" SetDarkMode(false)
else SetDarkMode(true)
SetTextEditorFont(vEditorFontName, vEdFontSize)
' Create gui.
root = CreateGui()
' Add commands (CTRL+<key>) that we want to process.
AddCommand(KEY_N, NewDocument)
AddCommand(KEY_O, LoadDocument)
AddCommand(KEY_S, SaveOrSaveAll)
AddCommand(KEY_F, ShowFindBar)
AddCommand(KEY_H, ShowReplaceBar)
AddCommand(KEY_G, ShowGotoBar)
AddCommand(KEY_F5, CompileAndRunTarget)
AddCommand(KEY_F7, CompileTarget)
AddCommand(KEY_F6, RunTarget)
' Add other keys that we want to process.
AddFunction(KEY_F1, CommandHelp)
AddFunction(KEY_F3, FindNextOrPrev)
AddFunction(KEY_F5, CompileAndRun)
AddFunction(KEY_F7, Compile)
AddFunction(KEY_F6, Run)
' Add an action for handling window messages from other n7 programs.
SetWindowMessageAction(function(msg)
if exists(msg)
existing = unset
if vEditorTabs.Count() > 0
for i = 0 to vEditorTabs.Count() - 1
if vEditorTabs.GetItem(i).editor.GetFilename() = msg
existing = vEditorTabs.GetItem(i)
break
endif
next
endif
if existing
vEditorTabs.SelectItem(existing)
else
AddNewEditor()
vEditor.LoadDocument(msg)
FunctionScan(vEditor)
SaveSettings()
endif
endif
ShowWindow()
return true
endfunc)
' Add some welcome lines to the output window.
vOutput.AddLine("Welcome to the second most primitive IDE thinkable!")
vOutput.AddLine("Compiled with n7 version " + VERSION)
' Any documents from settings?
if sizeof(documents)
' Try to load them, last one is the last active file.
for i = 0 to sizeof(documents) - 2
if exists(documents[i])
AddNewEditor()
vEditor.LoadDocument(documents[i])
if settings.target = documents[i]
ToggleTarget()
settings.target = unset
endif
FunctionScan(vEditor)
endif
next
' Select first tab or last if it exists.
if vEditorTabs.Count() > 0
vEditorTabs.SelectIndex(0)
last = Last(documents)
if last
for i = 0 to vEditorTabs.Count() - 1
if vEditorTabs.GetItem(i).editor.GetFilename() = last
vEditorTabs.SelectIndex(i)
break
endif
next
endif
endif
endif
' Any document as parameter?
if sizeof(args) > 1 and exists(args[1])
' Check if it exists among the ones already loaded.
existing = unset
if vEditorTabs.Count() > 0
for i = 0 to vEditorTabs.Count() - 1
if vEditorTabs.GetItem(i).editor.GetFilename() = args[1]
existing = vEditorTabs.GetItem(i)
break
endif
next
endif
' Set focus to its tab.
if existing
vEditorTabs.SelectItem(existing)
' Put it in a new tab.
else
AddNewEditor()
vEditor.LoadDocument(args[1])
FunctionScan(vEditor)
SaveSettings()
endif
endif
' No loads?
if vEditorTabs.Count() = 0
AddNewEditor()
endif
' Enter main loop.
EnterMainLoop(root)
' LoadSettings
' ------------
function LoadSettings()
f = openfile(GetPathCombined(vDataPath, "ned_config.txt"))
if not typeof(f) f = openfile(GetPathCombined(vPath, "ned_config.txt"))
documents = []
lastActive = unset
target = unset
if typeof(f)
setting = frln(f)
while setting
pair = split(setting, "=")
if sizeof(pair) = 2
select pair[0]
case "last_doc" documents[sizeof(documents)] = pair[1]
case "last_act" lastActive = pair[1]
case "target_doc" target = pair[1]
case "dark_mode"
' vDarkMode = int(pair[1])
if int(pair[1]) vTheme = "Default dark"
else vTheme = "Default light"
case "theme"
vTheme = pair[1]
case "find_case" vFindCaseSensitive = int(pair[1])
case "replace_case" vReplaceCaseSensitive = int(pair[1])
case "ed_font_size" vEdFontSize = int(pair[1])
case "hidden_op" vHiddenOutput = int(pair[1])
case "hidden_fl" vHiddenFunctionList = int(pair[1])
endsel
endif
setting = frln(f)
wend
if sizeof(documents) > 0 documents[sizeof(documents)] = lastActive
free file f
endif
return [docs: documents, target: target]
endfunc
' SaveSettings
' ------------
function SaveSettings()
f = createfile(GetPathCombined(vDataPath, "ned_config.txt"))
if typeof(f)
' wln file f, "dark_mode=" + vDarkMode
wln file f, "theme=" + vTheme.name
wln file f, "find_case=" + vFindCaseSensitive
wln file f, "replace_case=" + vReplaceCaseSensitive
wln file f, "ed_font_size=" + vEdFontSize
wln file f, "hidden_op=" + vHiddenOutput
wln file f, "hidden_fl=" + vHiddenFunctionList
if vEditorTabs.Count() > 0
target = unset
for i = 0 to vEditorTabs.Count() - 1
item = vEditorTabs.GetItem(i)
filename = item.editor.GetFilename()
if filename wln file f, "last_doc=" + filename
tabItem = vEditorTabs.GetTabItem(item)
if typeof(tabItem.icon) target = filename
next
if vEditor and vEditor.GetFilename() wln file f, "last_act=" + vEditor.GetFilename()
if typeof(target) wln file f, "target_doc=" + target
endif
free file f
endif
endfunc
' CreateGui
' ---------
function CreateGui()
' The root of the gui.
root = VBox(SIZE_EXPAND, SIZE_EXPAND)
root.background = GetColor(COLOR_BACKGROUND)
root.SetPadding(0)
' Creat a menu bar and add menus to it.
menuBar = MenuBar()
' File menu.
menu = Menu(FileMenuAction)
menu.Add("New", "Ctrl+N")
menu.Add("Load", "Ctrl+O")
menu.Add("Save", "Ctrl+S")
menu.Add("Save as", unset)
menu.Add("Toggle target", unset)
menu.Add("Save all", "Ctrl+Shift+S")
menu.Add("Close", unset)
menu.Add("Close all", unset)
menu.Add(HDivider(1, 4), unset)
menu.Add("Exit", unset)
menuBar.Add("File", menu)
' Edit menu.
menu = Menu(EditMenuAction)
menu.Add("Undo", "Ctrl+Z")
menu.Add("Redo", "Ctrl+Y")
menu.Add(HDivider(1, 4), unset)
menu.Add("Cut", "Ctrl+X")
menu.Add("Copy", "Ctrl+C")
menu.Add("Paste", "Ctrl+V")
menu.Add("Delete", "Del")
menu.Add("Select all", "Ctrl+A")
menu.Add(HDivider(1, 4), unset)
menu.Add("Find", "Ctrl+F")
menu.Add("Find next", "F3")
menu.Add("Find previous", "Shift+F3")
menu.Add("Replace", "Ctrl+H")
menu.Add("Goto line", "Ctrl+G")
menuBar.Add("Edit", menu)
' Program menu.
menu = Menu(ProgramMenuAction)
menu.Add("Compile and run", "F5")
menu.Add("Compile", "F7")
menu.Add("Run", "F6")
menu.Add(HDivider(1, 4), unset)
menu.Add("Compile and run target", "Ctrl+F5")
menu.Add("Compile target", "Ctrl+F7")
menu.Add("Run target", "Ctrl+F6")
menuBar.Add("Program", menu)
' Help menu.
menu = Menu(HelpMenuAction)
menu.Add("Syntax help/example", "F1")
menu.Add(HDivider(1, 4), unset)
menu.Add("Increase font size", unset)
menu.Add("Decrease font size", unset)
menu.Add(HDivider(1, 4), unset)
menu.Add("About", unset)
menuBar.Add("Help", menu)
' Add menu
root.Add(menuBar)
' Create box for everything but the menu.
content = VBox(SIZE_EXPAND, SIZE_EXPAND)
content.SetPadding(0)
content.SetSpacing(0)
' Create a box for the toolbar and settings bar.
hb = HBox(SIZE_EXPAND, SIZE_AUTO)
hb.SetValign(ALIGN_CENTER)
hb.SetPadding(0)
' Create toolbar.
toolbar = HBox(SIZE_EXPAND, SIZE_AUTO)
toolbar.SetValign(ALIGN_CENTER)
toolbar.SetPadding(4)
toolbar.SetSpacing(4)
' Add document buttons.
toolbar.Add(ImageButton(loadimage(GetPathCombined(vPath, "assets/new.png")), function(wdg)
NewDocument()
endfunc))
Last(toolbar.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(toolbar.GetChildren()).SetTooltip("Create a new document")
toolbar.Add(ImageButton(loadimage(GetPathCombined(vPath, "assets/open.png")), function(wdg)
LoadDocument()
endfunc))
Last(toolbar.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(toolbar.GetChildren()).SetTooltip("Open a document")
toolbar.Add(ImageButton(loadimage(GetPathCombined(vPath, "assets/save.png")), function(wdg)
SaveDocument()
endfunc))
Last(toolbar.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(toolbar.GetChildren()).SetTooltip("Save document")
toolbar.Add(ImageButton(loadimage(GetPathCombined(vPath, "assets/close.png")), function(wdg)
CloseDocument()
endfunc))
Last(toolbar.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(toolbar.GetChildren()).SetTooltip("Close document")
toolbar.Add(VDivider(1, 4))
' Add program buttons.
toolbar.Add(ImageButton(loadimage(GetPathCombined(vPath, "assets/compile_target.png")), function(wdg)
CompileTarget()
endfunc))
Last(toolbar.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(toolbar.GetChildren()).SetTooltip("Compile target file")
toolbar.Add(ImageButton(loadimage(GetPathCombined(vPath, "assets/run_target.png")), function(wdg)
CompileAndRunTarget()
endfunc))
Last(toolbar.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(toolbar.GetChildren()).SetTooltip("Compile and run target file")
toolbar.Add(ImageButton(loadimage(GetPathCombined(vPath, "assets/compile.png")), function(wdg)
Compile()
endfunc))
Last(toolbar.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(toolbar.GetChildren()).SetTooltip("Compile file")
toolbar.Add(ImageButton(loadimage(GetPathCombined(vPath, "assets/run.png")), function(wdg)
CompileAndRun()
endfunc))
Last(toolbar.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(toolbar.GetChildren()).SetTooltip("Compile and run file")
toolbar.Add(VDivider(1, 4))
' Add undo and redo buttons.
toolbar.Add(ImageButton(loadimage(GetPathCombined(vPath, "assets/undo.png")), function(wdg)
Undo()
endfunc))
Last(toolbar.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(toolbar.GetChildren()).SetTooltip("Undo")
toolbar.Add(ImageButton(loadimage(GetPathCombined(vPath, "assets/redo.png")), function(wdg)
Redo()
endfunc))
Last(toolbar.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(toolbar.GetChildren()).SetTooltip("Redo")
toolbar.Add(VDivider(1, 4))
' Add zoom in and out buttons.
toolbar.Add(ImageButton(loadimage(GetPathCombined(vPath, "assets/zoom_in.png")), function(wdg)
IncreaseFontSize()
endfunc))
Last(toolbar.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(toolbar.GetChildren()).SetTooltip("Increase the editor font size")
toolbar.Add(ImageButton(loadimage(GetPathCombined(vPath, "assets/zoom_out.png")), function(wdg)
DecreaseFontSize()
endfunc))
Last(toolbar.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(toolbar.GetChildren()).SetTooltip("Decrease the editor font size")
' Add toolbar to box
hb.Add(toolbar)
' Create settings bar.
settings = HBox(SIZE_EXPAND, SIZE_AUTO)
settings.SetHalign(ALIGN_RIGHT)
settings.SetValign(ALIGN_CENTER)
settings.SetPadding(4)
settings.SetSpacing(4)
settings.Add(ImageButton(loadimage(GetPathCombined(vPath, "assets/functions.png")), function(wdg)
vHiddenFunctionList = not vHiddenFunctionList
vEditor.box.flist.SetHidden(vHiddenFunctionList)
vEditor.box.fvbox.SetHidden(vHiddenFunctionList)
SaveSettings()
endfunc))
Last(settings.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(settings.GetChildren()).SetTooltip("Show/Hide function list")
' Add dark mode checkbox.
'settings.Add(LabledCheckBox("Night mode", vDarkMode, function(wdg, checked)
' vDarkMode = checked
' SetDarkMode(vDarkMode)
' SaveSettings()
' endfunc))
' Use a function as tooltip for this one.
'Last(settings.GetChildren()).GetCheckBox().SetTooltip(function(wdg)
' if wdg.IsChecked() return "Disable night mode"
' else return "Enable night mode"
' endfunc)
settings.Add(Label("Theme", SIZE_AUTO, SIZE_AUTO))
settings.Add(ComboBox(108, vThemes, function(cb, index)
item = cb.GetSelectedItem()
if item
if item.filename LoadTheme(item.filename)
else if item.name = "Default light" SetDarkMode(false)
else if item.name = "Default dark" SetDarkMode(true)
vTheme = item
SaveSettings()
endif
endfunc))
Last(settings.GetChildren()).SetDisplayField("name")
Last(settings.GetChildren()).SelectItem(vTheme)
' Add settings to box.
hb.Add(settings)
' Add toolbar and settings bar and a divider.
content.Add(hb)
content.Add(HDivider(1, 0))
' Hidden find bar.
vFindBar = VBox(SIZE_EXPAND, SIZE_AUTO)
vFindBar.SetPadding(0)
vFindBar.SetHalign(ALIGN_RIGHT)
hb = HBox(SIZE_AUTO, SIZE_AUTO)
hb.SetValign(ALIGN_CENTER)
hb.SetPadding(4)
hb.SetSpacing(8)
hb.Add(Label("Find", SIZE_AUTO, SIZE_AUTO))
vFindTextEntry = TextEntry(100, false)
vFindTextEntry.SetReturnAction(function(wdg)
FindNext()
endfunc)
vFindTextEntry.SetEscapeAction(function(wdg)
vFindBar.SetHidden(true)
SetFocus(vEditor)
endfunc)
hb.Add(vFindTextEntry)
hb.Add(LabledCheckBox("Match case", vFindCaseSensitive, function(wdg, checked)
vFindCaseSensitive = checked
SaveSettings()
endfunc))
Last(hb.GetChildren()).GetCheckBox().SetTooltip("Match case when searching")
hb.Add(TextButton("Next", SIZE_AUTO, SIZE_AUTO, function(wdg)
FindNext()
endfunc))
Last(hb.GetChildren()).SetTooltip("Find next")
hb.Add(TextButton("Prev", SIZE_AUTO, SIZE_AUTO, function(wdg)
FindPrev()
endfunc))
Last(hb.GetChildren()).SetTooltip("Find previous")
hb.Add(ImageButton(GetImage(IMAGE_CLOSE), function(wdg)
vFindBar.SetHidden(true)
SetFocus(vEditor)
endfunc))
Last(hb.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(hb.GetChildren()).SetPadding(4)
vFindBar.Add(hb)
vFindBar.Add(HDivider(1, 0))
vFindBar.SetHidden(true)
content.Add(vFindBar)
' Hidden find and replace bar.
vReplaceBar = VBox(SIZE_EXPAND, SIZE_AUTO)
vReplaceBar.SetPadding(0)
vReplaceBar.SetHalign(ALIGN_RIGHT)
hb = HBox(SIZE_AUTO, SIZE_AUTO)
hb.SetValign(ALIGN_CENTER)
hb.SetPadding(4)
hb.SetSpacing(8)
hb.Add(Label("Replace", SIZE_AUTO, SIZE_AUTO))
vReplaceTextEntry = TextEntry(100, false)
vReplaceTextEntry.SetReturnAction(function(wdg)
ReplaceNext()
endfunc)
vReplaceTextEntry.SetTabAction(function(wdg)
vReplaceWithTextEntry.SelectAll()
SetFocus(vReplaceWithTextEntry)
endfunc)
vReplaceTextEntry.SetEscapeAction(function(wdg)
vReplaceBar.SetHidden(true)
SetFocus(vEditor)
endfunc)
hb.Add(vReplaceTextEntry)
hb.Add(Label("With", SIZE_AUTO, SIZE_AUTO))
vReplaceWithTextEntry = TextEntry(100, false)
vReplaceWithTextEntry.SetReturnAction(function(wdg)
Replace()
endfunc)
vReplaceWithTextEntry.SetTabAction(function(wdg)
vReplaceTextEntry.SelectAll()
SetFocus(vReplaceTextEntry)
endfunc)
vReplaceWithTextEntry.SetEscapeAction(function(wdg)
vReplaceBar.SetHidden(true)
SetFocus(vEditor)
endfunc)
hb.Add(vReplaceWithTextEntry)
hb.Add(LabledCheckBox("Match case", vReplaceCaseSensitive, function(wdg, checked)
vReplaceCaseSensitive = checked
SaveSettings()
endfunc))
Last(hb.GetChildren()).GetCheckBox().SetTooltip("Match case when searching")
hb.Add(TextButton("Find", SIZE_AUTO, SIZE_AUTO, function(wdg)
ReplaceNext()
endfunc))
Last(hb.GetChildren()).SetTooltip("Find next")
hb.Add(TextButton("Replace", SIZE_AUTO, SIZE_AUTO, function(wdg)
Replace()
endfunc))
Last(hb.GetChildren()).SetTooltip("Replace current occurrence and find next")
hb.Add(TextButton("Replace all", SIZE_AUTO, SIZE_AUTO, function(wdg)
ReplaceAll()
endfunc))
Last(hb.GetChildren()).SetTooltip("Replace all occurences")
hb.Add(ImageButton(GetImage(IMAGE_CLOSE), function(wdg)
vReplaceBar.SetHidden(true)
SetFocus(vEditor)
endfunc))
Last(hb.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(hb.GetChildren()).SetPadding(4)
vReplaceBar.Add(hb)
vReplaceBar.Add(HDivider(1, 0))
vReplaceBar.SetHidden(true)
content.Add(vReplaceBar)
' Hidden goto bar.
vGotoBar = VBox(SIZE_EXPAND, SIZE_AUTO)
vGotoBar.SetPadding(0)
vGotoBar.SetHalign(ALIGN_RIGHT)
hb = HBox(SIZE_AUTO, SIZE_AUTO)
hb.SetValign(ALIGN_CENTER)
hb.SetPadding(4)
hb.SetSpacing(8)
hb.Add(Label("Line", SIZE_AUTO, SIZE_AUTO))
vGotoTextEntry = TextEntry(100, true)
vGotoTextEntry.SetReturnAction(function(wdg)
Goto()
endfunc)
vGotoTextEntry.SetEscapeAction(function(wdg)
vGotoBar.SetHidden(true)
endfunc)
hb.Add(vGotoTextEntry)
hb.Add(TextButton("Goto", SIZE_AUTO, SIZE_AUTO, function(wdg)
Goto()
endfunc))
Last(hb.GetChildren()).SetTooltip("Goto line")
hb.Add(ImageButton(GetImage(IMAGE_CLOSE), function(wdg)
vGotoBar.SetHidden(true)
SetFocus(vEditor)
endfunc))
Last(hb.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
Last(hb.GetChildren()).SetPadding(4)
vGotoBar.Add(hb)
vGotoBar.Add(HDivider(1, 0))
vGotoBar.SetHidden(true)
content.Add(vGotoBar)
vEditorTabs = TabBox(SIZE_EXPAND, SIZE_EXPAND)
vEditorTabs.SetAction(EditorTabChanged)
vEditorTabs.SetCloseRequestAction(EditorTabCloseRequest)
vEditorTabs.SetCloseAction(EditorTabClosed)
content.Add(vEditorTabs)
' Create a box with a header label for the output text area to the left and
' a label with document info to the right.
hb = HBox(SIZE_EXPAND, SIZE_AUTO)
hb.SetPadding(2)
hb.SetValign(ALIGN_CENTER)
' 2k23
' Create a box for the output text area and its scrollbar.
outputBox = HBox(SIZE_EXPAND, 128)
outputBox.SetHidden(vHiddenOutput)
if vHiddenOutput img = GetImage(IMAGE_ARROW_UP)
else img = GetImage(IMAGE_ARROW_DOWN)
hb.Add(ImageButton(img, function(wdg)
vHiddenOutput = not this.ob.IsHidden()
this.ob.SetHidden(vHiddenOutput)
if this.ob.IsHidden()
this.img = GetImage(IMAGE_ARROW_UP)
lines = vOutput.GetLines()
if lines and sizeof(lines)
vOutputLabel.SetText("Output: " + lines[sizeof(lines) - 1])
else
vOutputLabel.SetText("Output:")
endif
else
this.img = GetImage(IMAGE_ARROW_DOWN)
vOutputLabel.SetText("Output")
endif
this.MarkDirty()
SaveSettings()
endfunc))
Last(hb.GetChildren()).ob = outputBox
Last(hb.GetChildren()).SetForeground(GetColor(COLOR_PRIMARY_BACKGROUND))
vOutputLabel = Label("Output", SIZE_EXPAND, SIZE_AUTO)
hb.Add(vOutputLabel)
vEditorInfoLabel = Label("", SIZE_EXPAND, SIZE_AUTO)
vEditorInfoLabel.SetHalign(ALIGN_RIGHT)
hb.Add(vEditorInfoLabel)
' Connect the empty label to the editor.
'vEditor.SetInfoLabel(Last(hb.GetChildren()))
' Add the box.
content.Add(hb)
outputBox.SetPadding(2)
outputBox.SetBorder(1)
outputBox.SetBorderInside(true)
' Create the output text area (a read-only text editor).
vOutput = TextEditor(SIZE_EXPAND, SIZE_EXPAND)
vOutput.background = GetColor(COLOR_ED_BACKGROUND)
vOutput.readOnly = true
vOutput.maxLines = 64
vOutput.AddLine_ = vOutput.AddLine
vOutput.AddLine = function(txt)
this.AddLine_(txt)
if vHiddenOutput
lines = vOutput.GetLines()
if lines and sizeof(lines) vOutputLabel.SetText("Output: " + lines[sizeof(lines) - 1])
endif
endfunc
outputBox.Add(vOutput)
vsb = VerticalScrollbar(vOutput, SIZE_AUTO, SIZE_EXPAND)
outputBox.Add(vsb)
content.Add(outputBox)
' Add content box to the root.
root.Add(content)
return root
endfunc
' AddNewEditor
' ------------
function AddNewEditor()
' Create a box for the line number bar, editor and a scrollbar.
edBox = HBox(SIZE_EXPAND, SIZE_EXPAND)
edBox.SetPadding(2)
edBox.SetBorder(1)
edBox.SetBorderInside(true)
' Create and add a line number bar.
lnBar = LineNumberBar(SIZE_AUTO, SIZE_EXPAND)
edBox.Add(lnBar)
' Create and add the editor.
vEditor = TextEditor(SIZE_EXPAND, SIZE_EXPAND)
LoadKeywords(vEditor, GetPathCombined(GetPathCombined(vPath, "assets"), "keywords.txt"))
vEditor.SetLineNumberBar(lnBar)
vEditor.SetMaxColumnMarker(100)
vEditor.SetInfoLabel(vEditorInfoLabel)
edBox.Add(vEditor)
edBox.editor = vEditor
vEditor.box = edBox
vsb = VerticalScrollbar(vEditor, SIZE_AUTO, SIZE_EXPAND)
edBox.Add(vsb)
vEditor.helpSyntax = unset
' Create and add a function listbox.
edBox.flist = ListBox([], SIZE_AUTO, SIZE_EXPAND, FunctionSelectAction)
edBox.flist.ed = vEditor
edBox.flist.SetInnerPadding(4)
edBox.flist.SetMinWidth(128)
edBox.flist.SetBackground(GetColor(COLOR_ED_BACKGROUND))
vsb = VerticalScrollbar(edBox.flist, SIZE_AUTO, SIZE_EXPAND)
edBox.fvbox = vsb
edBox.flist.SetDisplayField("name")
edBox.flist.SetVolatileTooltip(function(wdg, x, y)
index = wdg.overIndex ' hack ...
if index >= 0 and index < sizeof(wdg.GetItems())
return wdg.GetItems()[index].full
else
return unset
endif
endfunc)
edBox.flist.SetHidden(vHiddenFunctionList)
edBox.fvbox.SetHidden(vHiddenFunctionList)
edBox.Add(edBox.flist)
edBox.Add(vsb)
vEditor.NewDocument()
vEditorTabs.Add(vEditor.GetDocumentName(), edBox, true)
vEditor.SetHeaderLabel(vEditorTabs.GetLabel(edBox))
vEditorTabs.SelectItem(edBox)
endfunc
' EditotTabChanged
' ----------------
function EditorTabChanged(edBox)
vEditor = edBox.editor
vEditor.box.flist.SetHidden(vHiddenFunctionList)
vEditor.box.fvbox.SetHidden(vHiddenFunctionList)
SetFocus(vEditor)
endfunc
' EditorTabCloseRequest
' ---------------------
function EditorTabCloseRequest(edBox)
if edBox.editor.Touched()
' Warn about changes. Should add a button "Save and close", could look at vEdBoxCloseRequest
' after saving, close and unset.
msg = chr(34) + edBox.editor.GetDocumentName() + chr(34) + " has unsaved changes." + chr(10)
msg = msg + "Do you still want to close the tab?"
vEdBoxCloseRequest = edBox
ShowMessageBox("Warning", msg, ["Yes", "No"], function(popup, buttonIndex)
if buttonIndex = 0
if vEditorTabs.Count() = 1 AddNewEditor()
vEditorTabs.Close(vEdBoxCloseRequest)
endif
vEdBoxCloseRequest = unset
endfunc)
return false
else
' Add a new empty document if this is the last tab.
if vEditorTabs.Count() = 1 AddNewEditor()
return true
endif
endfunc
' EditorTabClosed
' ---------------
function EditorTabClosed(edBox)
SaveSettings()
endfunc
' FileMenuAction
' --------------
function FileMenuAction(menu, selectedIndex)
select selectedIndex
case 0 NewDocument()
case 1 LoadDocument()
case 2 SaveDocument()
case 3 SaveDocumentAs()
case 4 ToggleTarget()
case 5 SaveAllDocuments()
case 6 CloseDocument()
case 7 CloseAllDocuments()
case 8 Exit()
endsel
endfunc
' EditMenuAction
' --------------
function EditMenuAction(menu, selectedIndex)
select selectedIndex
case 0 Undo()
case 1 Redo()
case 2 Cut()
case 3 Copy()
case 4 Paste()
case 5 Delete()
case 6 SelectAll()
case 7 ShowFindBar()
case 8 FindNext()
case 9 FindPrev()
case 10 ShowReplaceBar()
case 11 ShowGotoBar()
endsel
endfunc
' ProgramMenuAction
' -----------------
function ProgramMenuAction(menu, selectedIndex)
select selectedIndex
case 0 CompileAndRun()
case 1 Compile()
case 2 Run()
case 3 CompileAndRunTarget()
case 4 CompileTarget()
case 5 RunTarget()
endsel
endfunc
' HelpMenuAction
' --------------
function HelpMenuAction(menu, selectedIndex)
select selectedIndex
case 0 CommandHelp()
case 1 IncreaseFontSize()
case 2 DecreaseFontSize()
case 3 About()
endsel
endfunc
' NewDocument
' -----------
function NewDocument()
AddNewEditor()
endfunc
' LoadDocument
' ------------
function LoadDocument()
filename = openfiledialog("n7")
if filename and exists(filename)
' Loaded document goes into a new editor unless the active editor is an empty new document.
if vEditor.Touched() or vEditor.GetFilename() AddNewEditor()
vEditor.LoadDocument(filename)
SaveSettings()
FunctionScan(vEditor)
endif
endfunc
' SaveDocument
' --------------
function SaveDocument()
if vEditor.GetFilename()
if vEditor.SaveDocument()
vOutput.AddLine("Saved " + chr(34) + vEditor.GetFilename() + chr(34))
SaveSettings()
FunctionScan(vEditor)
return true
else
vOutput.AddLine("Could not save " + chr(34) + vEditor.GetFilename() + chr(34))
return false
endif
else
return SaveDocumentAs()
endif
endfunc
' SaveDocumentAs
' --------------
function SaveDocumentAs()
filename = savefiledialog("n7")
if filename
extFound = false
for i = len(filename) - 1 to 0
c = mid(filename, i)
if c = "\" or c = "/" break
if c = "."
extFound = true
break
endif
next
if not extFound filename = filename + ".n7"
vEditor.SetFilename(filename)
return SaveDocument()
else
return false
endif
endfunc
' ToggleTarget
' ------------
function ToggleTarget()
edBox = vEditorTabs.GetCurrentItem()
current = vEditorTabs.GetTabItem(edBox)
if current.icon
current.SetIcon(unset, unset)
SaveSettings()
else
if len(edBox.editor.GetFilename())
foreach item in vEditorTabs.items.children item.SetIcon(unset, unset)
current.SetIcon(GetImage(IMAGE_ARROW_RIGHT), GetColor(COLOR_PRIMARY_BACKGROUND))
SaveSettings()
else
txt = "You can't target a document" + chr(10)
txt = txt + "that has never been saved."
ShowMessageBox("Sorry", txt, "Close", unset)
endif
endif
endfunc
' SaveAllDocuments
' ----------------
' Well, doesn't save documents that hasn't previously been saved.
function SaveAllDocuments()
if vEditorTabs.Count() > 0
for i = 0 to vEditorTabs.Count() - 1
ed = vEditorTabs.GetItem(i).editor
if ed.GetFilename() ed.SaveDocument()
next
endif
endfunc
' SaveOrSaveAll
' -------------
' Comand key callback, have to check KEY_SHIFT ourselves to distinguish between ctrl+s and
' ctrl+shift+s. Probably should extend AddCommand to handle the shift key.
function SaveOrSaveAll()
if keydown(KEY_SHIFT) SaveAllDocuments()
else SaveDocument()
endfunc
' CloseDocument
' -------------
' Close current document.
function CloseDocument()
if vEditor.Touched()
msg = chr(34) + vEditor.GetDocumentName() + chr(34) + " has unsaved changes." + chr(10)
msg = msg + "Do you still want to close the tab?"
ShowMessageBox("Warning", msg, ["Yes", "No"], function(popup, buttonIndex)
if buttonIndex = 0
vEditorTabs.Close(vEditor.box)
if vEditorTabs.Count() = 0 AddNewEditor()
endif
endfunc)
else
vEditorTabs.Close(vEditor.box)
if vEditorTabs.Count() = 0 AddNewEditor()
endif
endfunc
' UnsavedDocuments
' ----------------
function UnsavedDocuments()
unsaved = []
for i = 0 to vEditorTabs.Count() - 1
if vEditorTabs.GetItem(i).editor.Touched()
unsaved[sizeof(unsaved)] = vEditorTabs.GetItem(i).editor.GetDocumentName()
endif
next
return unsaved
endfunc
' CloseAllDocuments
' -----------------
' Close all dodumcnets
function CloseAllDocuments()
unsaved = UnsavedDocuments()
if sizeof(unsaved)
txt = "The following documents have unsaved changes:" + chr(10)
for i = 0 to sizeof(unsaved) - 1 txt = txt + unsaved[i] + chr(10)
txt = txt + "Do you still want to close all documents?"
ShowMessageBox("Warning", txt, ["Yes", "No"], function(popup, buttonIndex)
if buttonIndex = 0
vEditorTabs.CloseAll(false)
AddNewEditor()
SaveSettings()
endif
endfunc)
return
else
vEditorTabs.CloseAll(false)
AddNewEditor()
SaveSettings()
endif
endfunc
' Exit
' ----
' Sadly only called when using the menu to exit. Not quite sure how to lett n7 programs handle the
' window's close button yet ...
function Exit()
if vEditorTabs.Count() > 0
unsaved = UnsavedDocuments()
if sizeof(unsaved)
txt = "The following documents have unsaved changes:" + chr(10)
for i = 0 to sizeof(unsaved) - 1 txt = txt + unsaved[i] + chr(10)
txt = txt + "Do you still want to exit?"
ShowMessageBox("Warning", txt, ["Yes", "No"], function(popup, buttonIndex)
if buttonIndex = 0
ExitMainLoop()
endif
endfunc)
return
endif
endif
ExitMainLoop()
endfunc
' Undo
' ----
function Undo()
vEditor.Undo()
endfunc
' Redo
' ----
function Redo()
vEditor.Redo()
endfunc
' Cut
' ---
function Cut()
vEditor.Cut()
endfunc
' Copy
' ----
function Copy()
vEditor.Copy()
endfunc
' Paste
' -----
function Paste()
vEditor.Paste()
endfunc
' Delete
' ------
function Delete()
vEditor.Delete()
endfunc
' SelectAll
' ---------
function SelectAll()
vEditor.SelectAll()
endfunc
' ShowFindBar
' -----------
function ShowFindBar()
if vFindBar.IsHidden() vFindBar.SetHidden(false)
if not vReplaceBar.IsHidden() vReplaceBar.SetHidden(true)
if not vGotoBar.IsHidden() vGotoBar.SetHidden(true)
vFindTextEntry.SelectAll()
SetFocus(vFindTextEntry)
endfunc
' FindNext
' --------
function FindNext()
txt = vFindTextEntry.GetText()
if txt
if not vEditor.FindNext(txt, not vFindCaseSensitive)
vOutput.AddLine("Could not find " + chr(34) + txt + chr(34))
endif
endif
endfunc
' FindPrev
' --------
function FindPrev()
txt = vFindTextEntry.GetText()
if len(txt)
if not vEditor.FindPrev(txt, not vFindCaseSensitive)
vOutput.AddLine("Could not find " + chr(34) + txt + chr(34))
endif
endif
endfunc
' FindNextOrPrev
' --------------
' Command key callback.
function FindNextOrPrev()
if keydown(KEY_SHIFT) FindPrev()
else FindNext()
endfunc
' ShowReplaceBar
' --------------
function ShowReplaceBar()
if vReplaceBar.IsHidden() vReplaceBar.SetHidden(false)
if not vFindBar.IsHidden() vFindBar.SetHidden(true)
if not vGotoBar.IsHidden() vGotoBar.SetHidden(true)
SetFocus(vReplaceTextEntry)
vReplaceTextEntry.SelectAll()
endfunc
' Replace
' -------
function Replace()
txt = vReplaceTextEntry.GetText()
if len(txt) > 0
' Replace if current selection matches search.
if (vReplaceCaseSensitive and vEditor.GetSelection() = txt) or
(vReplaceCaseSensitive = false and lower(vEditor.GetSelection()) = lower(txt))
vEditor.PasteString(vReplaceWithTextEntry.txt)
endif
' Find next.
if not vEditor.FindNext(txt, not vReplaceCaseSensitive)
vOutput.AddLine("Could not find " + chr(34) + txt + chr(34))
endif
endif
endfunc
' ReplaceNext
' -----------
function ReplaceNext()
txt = vReplaceTextEntry.GetText()
if len(txt) > 0
if not vEditor.FindNext(txt, not vReplaceCaseSensitive)
vOutput.AddLine("Could not find " + chr(34) + txt + chr(34))
endif
endif
endfunc
' ReplaceAll
' ----------
function ReplaceAll()
txt = vReplaceTextEntry.GetText()
rep = vReplaceWithTextEntry.GetText()
if len(txt) > 0
count = vEditor.ReplaceAll(txt, rep, not vReplaceCaseSensitive)
if count
vOutput.AddLine("Replaced " + count + " occurrence(s) of " + chr(34) + txt + chr(34) +
" with " + chr(34) + rep + chr(34))
else
vOutput.AddLine("Could not find " + chr(34) + txt + chr(34))
endif
endif
endfunc
' ShowGotoBar
' -----------
function ShowGotoBar()
if vGotoBar.IsHidden() vGotoBar.SetHidden(false)
if not vFindBar.IsHidden() vFindBar.SetHidden(true)
if not vReplaceBar.IsHidden() vReplaceBar.SetHidden(true)
vGotoTextEntry.SelectAll()
SetFocus(vGotoTextEntry)
endfunc
' Goto
' ----
function Goto()
ln = int(vGotoTextEntry.GetText())
vGotoBar.SetHidden(true)
if not vEditor.Goto(ln) vOutput.AddLine(ln + " is an invalid line number")
SetFocus(vEditor)
endfunc
' CompileAndRun
' -------------
function CompileAndRun()
if Compile() Run()
endfunc
' Compile
' -------
function Compile()
if SaveDocument()
fn = vEditor.GetFilename()
vOutput.AddLine("Compiling " + chr(34) + fn + chr(34))
cmd = chr(34) + chr(34) + GetPathCombined(vPath, vCompiler) + chr(34) + " " +
chr(34) + fn + chr(34) + chr(34)
result = system(cmd)
lines = split(result, chr(10))
vOutput.AddLine(result)
' Success?
if sizeof(lines) = 3 and left(lines[2], 12) = "n7b: success"
' Copy DLL files.
if sizeof(vDLLs)
for i = len(fn) - 1 to 0 if mid(fn, i) = "\" or mid(fn, i) = "/" break
path = left(fn, i + 1)
for i = 0 to sizeof(vDLLs) - 1
' Uhm, what if the version has changed of a dll?
'if not exists(path + vDLLs[i])
system "copy /Y " + chr(34) + GetPathCombined(vPath, vDLLs[i]) + chr(34) + " " +
chr(34) + path + chr(34)
'endif
next
endif
return true
endif
endif
return false
endfunc
' Run
' ---
function Run()
fn = vEditor.GetFilename()
if len(fn) > 0
for i = len(fn) - 1 to 0 if mid(fn, i) = "." break
fn = left(fn, i) + ".exe"
if exists(fn)
vOutput.AddLine("Executing " + chr(34) + fn + chr(34))
' Old, nedgui, version
'system("start " + chr(34) + chr(34) + " " + chr(34) + fn + chr(34))
cmd = "cd /D " + chr(34) + GetPath(fn) + chr(34) +
" && start " + chr(34) + chr(34) + " " + chr(34) + fn + chr(34)
'vOutput.AddLine(cmd)
system(cmd)
else
vOutput.AddLine("Could not find " + chr(34) + fn + chr(34))
endif
endif
return false
endfunc
' hack.
function FindTargetEditor()
foreach item in vEditorTabs.items.children
if typeof(item.icon) return item.content
next
return unset
endfunc
' CompileAndRunTarget
' -------------------
function CompileAndRunTarget()
target = FindTargetEditor()
if typeof(target)
current = vEditorTabs.GetCurrentItem()
vEditorTabs.SelectItem(target)
CompileAndRun()
vEditorTabs.SelectItem(current)
else
vOutput.AddLine("No target found for compiling and running")
endif
endfunc
' CompileTarget
' --------------
function CompileTarget()
target = FindTargetEditor()
if typeof(target)
current = vEditorTabs.GetCurrentItem()
vEditorTabs.SelectItem(target)
Compile()
vEditorTabs.SelectItem(current)
else
vOutput.AddLine("No target found for compiling")
endif
endfunc
' RunTarget
' ---------
function RunTarget()
target = FindTargetEditor()
if typeof(target)
current = vEditorTabs.GetCurrentItem()
vEditorTabs.SelectItem(target)
Run()
vEditorTabs.SelectItem(current)
else
vOutput.AddLine("No target found for running")
endif
endfunc
' IncreaseFontSize
' ----------------
function IncreaseFontSize()
vEdFontSize = min(vEdFontSize + 2, 24)
SetTextEditorFont(vEditorFontName, vEdFontSize)
SaveSettings()
endfunc
' DecreaseFontSize
' ----------------
function DecreaseFontSize()
vEdFontSize = max(vEdFontSize - 2, 14)
SetTextEditorFont(vEditorFontName, vEdFontSize)
SaveSettings()
endfunc
' About
' -----
function About()
txt = "Version " + vVersion + ", by Marcus" + chr(10)
txt = txt + "Compiled with n7 version " + VERSION + chr(10) + " " + chr(10)
txt = txt + "This program is public domain (CC0), so feel" + chr(10)
txt = txt + "free to do whatever you want with it."
ShowMessageBox("NED - NaaLaa Editor", txt, "Close", unset)
endfunc
' CommandHelp
' -----------
function CommandHelp()
hasHelp = vEditor.GetHelp()
vEditor.ShowHelp(unset)
ln = vEditor.GetCurrentLine()
le = len(ln)
startPos = vEditor.GetCaretX()
leftPos = startPos
c = asc(mid(ln, leftPos))
while leftPos >= 0 and (c = 32 or IsAlpha(c))
leftPos = leftPos - 1
c = asc(mid(ln, leftPos))
wend
leftPos = leftPos + 1
rightPos = startPos
c = asc(mid(ln, rightPos))
while rightPos < le and (c = 32 or IsAlpha(c))
rightPos = rightPos + 1
c = asc(mid(ln, rightPos))
wend
s = mid(ln, leftPos, rightPos - leftPos)
if not s return
words = split(s, " ")
if not sizeof(words) return
pos = startPos
while pos >= 0 and asc(mid(ln, pos)) = 32 pos = pos - 1
currentWord = GetWordAt(ln, pos)
' Check user functions.
if currentWord
foreach uf in vEditor.box.flist.GetItems()
if uf.name = currentWord
vEditor.ShowHelp(uf.full)
return
endif
next
endif
if not vCommandSyntax
vOutput.AddLine("No command help loaded")
return
endif
for index = 0 to sizeof(words) - 1 if words[index] = currentWord break
while index >= 0 and not vEditor.IsKeyword(words[index]) index = index - 1
if index < 0
vOutput.AddLine("No syntax help found")
return
endif
mainKeyword = words[index]
minKeywordIndex = index
maxKeywordIndex = index
while minKeywordIndex > 0 and vEditor.IsKeyword(words[minKeywordIndex - 1])
minKeywordIndex = minKeywordIndex - 1
wend
while maxKeywordIndex < sizeof(words) - 1 and vEditor.IsKeyword(words[maxKeywordIndex + 1])
maxKeywordIndex = maxKeywordIndex + 1
wend
maxWords = 0
syntax = unset
link = unset
' I have covid, and I'm tired ...
for i = minKeywordIndex to maxKeywordIndex
for j = i to maxKeywordIndex
if i <= index and j >= index
s = words[i]
if j > i for k = i + 1 to j s = s + " " + words[k]
if key(vCommandSyntax, s) and j + 1 - i > maxWords
maxWords = j + 1 - i
syntax = vCommandSyntax[s]
if key(vCommandFile, s)
link = vCommandFile[s]
else ' Shouldn't happen unless I mess up the file ...
link = unset
endif
endif
endif
next
next
if syntax
if hasHelp and syntax = vEditor.helpSyntax
fn = GetPathCombined(GetPathCombined(GetPathCombined(vPath, "examples"), "help"), link)
if exists(fn)
vEditor.helpSyntax = unset
AddNewEditor()
vEditor.LoadDocument(fn)
SaveSettings()
FunctionScan(vEditor)
return
else
vOutput.AddLine("Could not load example " + chr(34) + fn + chr(34))
endif
else
if link
vEditor.ShowHelp(syntax + " (Press F1 again to load an example)")
vEditor.helpSyntax = syntax
else
vEditor.ShowHelp(syntax)
vEditor.helpSyntax = unset
endif
endif
else
vOutput.AddLine("No syntax help found")
endif
endfunc
function GetWordAt(ln, pos)
le = len(ln)
if pos < 0 or pos >= le or not IsAlpha(asc(mid(ln, pos))) return unset
if pos = 0
s = 0
else
s = pos
while s > 0 and IsAlpha(asc(mid(ln, s - 1))) s = s - 1
endif
e = pos + 1
while s < le and IsAlpha(asc(mid(ln, e))) e = e + 1
return mid(ln, s, e - s)
endfunc
function IsAlpha(c)
return c >= 65 and c <= 90 or c >= 97 and c <= 122
endfunc
function IsLowerAlpha(c)
return c >= 97 and c <= 122
endfunc
function FunctionSelectAction(wdg, index)
if index < 0 return
'wdg.SelectIndex(-1)
ed = wdg.ed
wanted = wdg.GetItems()[index]
lines = ed.GetLines()
lineNumber = 0
ln = lines[lineNumber]
foundAtLine = -1
do
skipLine = true
if instr(ln, "function ") >= 0
' Remove all string constants.
lft = instr(ln, chr(34))
while lft >= 0
rgt = instr(ln, chr(34), lft + 1)
if rgt >= 0
ln = left(ln, lft) + right(ln, rgt + 1)
lft = instr(ln, chr(34))
else
break
endif
wend
' Remove comment.
cmt = instr(ln, "'")
if cmt >= 0 ln = left(ln, cmt)
' Look for function again.
fnc = instr(ln, "function ")
if fnc >= 0
fnc = fnc + 9
' Look for (
lpt = instr(ln, "(", fnc)
if lpt >= 0
fncName = replace(mid(ln, fnc, lpt - fnc), " ", "")
' Ignore unnamed functions.
if len(fncName) and fncName = wanted.name
foundAtLine = lineNumber
else
ln = right(ln, lpt + 1)
skipLine = false
endif
endif
endif
endif
if skipLine
lineNumber = lineNumber + 1
if lineNumber < sizeof(lines)
ln = lines[lineNumber]
else
ln = unset
endif
endif
until foundAtLine >= 0 or ln = unset
if not (foundAtLine >= 0 and vEditor.Goto(foundAtLine + 1))
vOutput.AddLine("Could not locate function " + wanted.name)
endif
endfunc
function FunctionScan(ed)
lines = ed.GetLines()
lineNumber = 0
ln = lines[lineNumber]
listBox = ed.box.flist;
flist = listBox.GetItems()
selIndex = listBox.GetSelectedIndex()
if selIndex >= 0
if selIndex < sizeof(listBox.GetItems())
selName = listBox.GetItems()[selIndex].name
endif
else
selName = unset
endif
clear flist
do
skipLine = true
if instr(ln, "function ") >= 0
' Remove all string constants.
lft = instr(ln, chr(34))
while lft >= 0
rgt = instr(ln, chr(34), lft + 1)
if rgt >= 0
ln = left(ln, lft) + right(ln, rgt + 1)
lft = instr(ln, chr(34))
else
break
endif
wend
' Remove comment.
cmt = instr(ln, "'")
if cmt >= 0 ln = left(ln, cmt)
' Look for function again.
fnc = instr(ln, "function ")
if fnc >= 0
fnc = fnc + 9
' Look for (
lpt = instr(ln, "(", fnc)
if lpt >= 0
fncName = replace(mid(ln, fnc, lpt - fnc), " ", "")
' Ignore unnamed functions.
if len(fncName)
' Now let's see ...
ln = right(ln, lpt + 1)
foul = false
prms = ""
do
' Remove comment.
cmt = instr(ln, "'")
if cmt >= 0 ln = left(ln, cmt)
cm = instr(ln, ",")
while cm >= 0
pname = replace(left(ln, cm), " ", "")
ln = right(ln, cm + 1)
if len(pname)
for i = 0 to len(pname) - 1
if not IsAlphaOrDigit(asc(mid(pname, i)))
foul = true
break
endif
next
if foul break
prms = prms + pname + " "
else
foul = true
break
endif
cm = instr(ln, ",")
wend
if foul break
rpt = instr(ln, ")")
if rpt >= 0
pname = replace(left(ln, rpt), " ", "")
ln = right(ln, rpt + 1)
if len(pname)
for i = 0 to len(pname) - 1
if not IsAlphaOrDigit(asc(mid(pname, i)))
foul = true
break
endif
next
if foul break
prms = prms + pname + " "
endif
skipLine = false
break
else
lineNumber = lineNumber + 1
if lineNumber < sizeof(lines)
ln = lines[lineNumber]
else
foul = true
ln = unset
break
endif
endif
loop
if not foul
if len(prms) prms = left(prms, len(prms) - 1)
flist[sizeof(flist)] = [
name: fncName,
full: fncName + "(" + replace(prms, " ", ", ") + ")"]
endif
endif
endif
endif
endif
if skipLine
lineNumber = lineNumber + 1
if lineNumber < sizeof(lines)
ln = lines[lineNumber]
else
ln = unset
endif
endif
until ln = unset
listBox.ItemsChanged()
if selName
foreach k, i in listBox.GetItems()
if i.name = selName
listBox.SelectIndex(k)
break
endif
next
endif
endfunc
function LoadCommandHelp(filename)
f = openfile(filename)
if typeof(f)
vCommandSyntax = []
vCommandFile = []
cmd = fread(f)
while cmd
syntax = fread(f)
fn = fread(f)
if syntax and filename
vCommandSyntax[cmd] = syntax
vCommandFile[cmd] = fn
fn = GetPathCombined(GetPathCombined(GetPathCombined(vPath, "examples"), "help"), fn)
endif
cmd = fread(f)
wend
free file f
endif
endfunc
' LoadKeywords
' ------------
' Load keywords from file and add them to an editor.
function LoadKeywords(ed, filename)
f = openfile(filename)
if typeof(f)
ed.ClearKeywords()
kw = fread(f)
type = 0
while typeof(kw)
' There are two predefined keyword types with different colors (COLOR_SH_KEYWORD and
' COLOR_SH_CONSTANT)
if kw = "keywords:" type = 0
elseif kw = "constants:" type = 1
else if len(kw) ed.AddKeyword(kw, type)
kw = fread(f)
wend
free file f
endif
endfunc
Posts: 316
Threads: 39
Joined: Nov 2023
Reputation:
3
07-02-2024, 07:49 PM
(This post was last modified: 07-02-2024, 07:49 PM by Marcus.)
Yeah, the version number displayed in ned is the version of ned. I was thinking about re-compiling ned. But I remember making a change in ngui.n7 when working on the enginea editor. Ned uses ngui and I don't think I've updated it to work with the new version. Was something about support for floating point values in text entry fields ... But if it works, it works. The "go to line" box could possibly stop working or make ned crash if you re-compile it
|