#CONSTANT TRUE = 1 #CONSTANT FALSE = 0 #CONSTANT SCROLLBARSIZE = 12 #CONSTANT TITLEBARSIZE = 18 #CONSTANT MIN_WIDTH = 40 #CONSTANT MIN_HEIGHT = 30 #CONSTANT VK_BACKSPACE = 8 #CONSTANT VK_RETURN = 13 #CONSTANT VK_DELETE = 211 #CONSTANT VK_COPY = 3 #CONSTANT VK_PASTE = 22 Global NEW_FILE$ = "Untitled" Global CLICK_FLAG = 0 : `mouse is pressed down Global CARET_STAMP = 0 : `timestamp for cursor blink rate Global CARET$ = "|" : `the cursor to display Global VK_FLAG = 0 : `if an arrow key is being pressed global _mouseFlag = 0 : `used with menu functions Global status_message$ = "" : `message displayed in status bar type Menu name as string ` name of this menu active as boolean ` enabled/disabled width as integer ` width of this menu count as integer ` item count endtype type MenuItem parentID as integer `id of menu this item belongs to item as string `name of this item enabled as boolean `enabled/disabled check as integer `unused endtype type Files name as string `name of file for read/write maxWidth as integer `number of chars in longest line textIndex as integer `beginnging of this file's text in the string array textEnd as integer `ending of this file's text in the string array endtype type Window x as integer `X position of window y as integer `Y position of window width as integer `width of window height as integer `height of window fileIndex as integer `index in file array this window references thumbX as integer `scrollbar thumb X position (horizontal) thumbY as integer `scrollbar thumb Y position (vertical) thumbHeight as integer `scrollbar thumb height (vertical) thumbWidth as integer `scrollbar thumb width (horizontal) thumbXFlag as boolean `horizontal scrollbar moving thumbYFlag as boolean `vertical scrollbar moving thumbOffsetX as integer `offset from where mouse clicked horizontal scrollbar thumbOffsetY as integer `offset from where mouse clicked vertical scrollbar showVertical as boolean `show/hide vertical scrollbar showHorizontal as boolean `show/hide horizontal scrollbar titleFlag as boolean `window is being dragged titleOffsetX as integer `offset of where window title bar was grabbed with mouse X titleOffsetY as integer `offset of where window title bar was grabbed with mouse Y resizeFlag as boolean `window is being resized resizeOffsetX as integer `offset X from where mouse clicked resize corner resizeOffsetY as integer `offset Y from where mouse clicked resize corner startingLine as integer `what line number to start displaying text from (vertical scrolling) startingChar as integer `what character position to start displaying text from (horizontal scrolling) showLineNumbers as boolean `show/hide line number border visibleLines as integer `how many lines this window can display at one time visibleChars as integer `how many characters across this window can display at one time selectedRow as integer `what line number is being edited caretPos as integer `character position of cursor in 'selectedRow' endtype type SelectionNode row as integer `which line of text (from array __textLines$) char as integer `character position within that line endtype type SelectionRange start as SelectionNode `beginning of selection finish as SelectionNode `end of selection endtype Global _selection as SelectionRange dim __openFiles(0) as Files : `array of opened files dim __windows(0) as Window : `array of displayed windows dim __textLines$(0) as string : `holds lines of text from all files : `"File" indices reference this array dim menus() as Menu : `array of menus dim menuItems() as MenuItem : `array of menu items from all menus MENU_FILE = addMenu("File") MENU_EDIT = addMenu("Edit") MENU_TOOLS = addMenu("Tools") addMenuItem(MENU_FILE,"New",TRUE,-1) addMenuItem(MENU_FILE,"Open",TRUE,-1) addMenuItem(MENU_FILE,"Save",TRUE,-1) addMenuItem(MENU_FILE,"Save As",TRUE,-1) addMenuItem(MENU_FILE,"Close Window",TRUE,-1) addMenuItem(MENU_FILE,"------------",TRUE,-1) addMenuItem(MENU_FILE,"Exit",TRUE,-1) addMenuItem(MENU_EDIT,"Cut",TRUE,-1) addMenuItem(MENU_EDIT,"Copy",TRUE,-1) addMenuItem(MENU_EDIT,"Paste",TRUE,-1) addMenuItem(MENU_TOOLS,"Word Count",TRUE,-1) addMenuItem(MENU_TOOLS,"Character Count",TRUE,-1) set display mode 1024,768,16 `sync on `backdrop on `color backdrop rgb(0,0,255) `openFile("c:teTest.txt") : `non-existant file, creates blank `openFile("c:test.txt") `openFile("c:vraylog.txt") `openFile("c:thing.txt") status_message$ = "status bar" DO cls handleWindows() handleMenus() handleStatusBar() `text 2,200,prevRow$ `fastsync LOOP REM ********************************** REM handles all functionality of menus REM ********************************** function handleMenus() _mc = mouseclick() if _mc = 0 then _mouseFlag = 0 v$ = _handleMenus$(_mc) if v$ = "Edit-Copy" then copyText() if v$ = "Edit-Paste" then pasteText() if v$ = "File-New" then openFile(NEW_FILE$) if v$ = "File-Open" then openDialog() if v$ = "File-Save" then saveFile("") if v$ = "File-Save As" then saveAsDialog() if v$ = "File-Exit" then end if v$ = "File-Close Window" then closeWindow() if v$ = "Tools-Word Count" then countWords() if v$ = "Tools-Character Count" then countCharacters() endfunction REM **************************** REM Handles rendering and UI REM of all text document windows REM **************************** function handleWindows() hwind = 0 count = array count(__windows()) for i = 1 to count _drawWindow(i) h = _handleWindowUI(count+1-i) if h > hwind then hwind = h next i rem order last window focused on top if hwind > 0 and hwind < count temp as Window temp = __windows(hwind) for i = hwind to count-1 __windows(i) = __windows(i+1) next i __windows(count) = temp endif if mouseclick() = 0 then CLICK_FLAG = 0 _handleFocused() endfunction REM ********************************** REM Functionality for whichever window REM currently has focus REM ********************************** function _handleFocused() index = array count(__windows()) x = __windows(index).x y = __windows(index).y width = __windows(index).width height = __windows(index).height thumbX = __windows(index).thumbX thumbY = __windows(index).thumbY thumbHeight = __windows(index).thumbHeight fileIndex = __windows(index).fileIndex textIndex = __openFiles(fileIndex).textIndex lineCount = __openFiles(fileIndex).textEnd - textIndex lineHeight = text height("A") visibleLines = __windows(index).visibleLines editLines(index) if __windows(index).showVertical = TRUE mmz = mousemovez() if mmz < 0 then thumbY = thumbY + 10 if mmz > 0 then thumbY = thumbY - 10 if thumbY < 0 then thumbY = 0 if thumbY > height-thumbHeight then thumbY = height-thumbHeight __windows(index).thumbY = thumbY __windows(index).startingLine = textIndex + ((lineCount-visibleLines+1)*thumbY) / (height-thumbHeight) endif endfunction REM ********************************* REM Handles too many different things REM than a single function should do REM ********************************* function editLines(index as integer) x = __windows(index).x y = __windows(index).y width = __windows(index).width height = __windows(index).height caret = __windows(index).caretPos row = __windows(index).selectedRow fi = __windows(index).fileIndex startingLine = __windows(index).startingLine startingChar = __windows(index).startingChar fileIndex = __windows(index).fileIndex visibleChars = __windows(index).visibleChars lineHeight = text height("A") charWidth = text width("A") rem position cursor with mouse if mouseclick() = 1 if mouseWithin(x,y,x+width,y+height) t_row = (mousey() - y) / lineHeight t_caretPos = (mousex() - x) / charWidth + startingChar t_row = startingLine + t_row if t_row > __openFiles(fileIndex).textEnd then t_row = __openFiles(fileIndex).textEnd `__windows(index).selectedRow = row fPos = len(__textLines$(t_row)) if t_caretPos > fPos then t_caretPos = fPos `caret = __windows(index).caretPos if CLICK_FLAG = 0 CLICK_FLAG = 1 row = t_row caret = t_caretPos __windows(index).caretPos = caret __windows(index).selectedRow = row _selection.start.row = row _selection.start.char = caret else _selection.finish.row = t_row _selection.finish.char = t_caretPos endif endif endif rem position cursor with arrow keys if upkey() and VK_FLAG = 0 VK_FLAG = 1 dec row if row < 1 then row = 1 __windows(index).selectedRow = row fPos = len(__textLines$(row)) if caret > fPos then caret = fPos endif if downkey() and VK_FLAG = 0 VK_FLAG = 1 inc row lineCount = __openFiles(fileIndex).textEnd - __openFiles(fileIndex).textIndex if row > lineCount then row = lineCount __windows(index).selectedRow = row fPos = len(__textLines$(row)) if caret > fPos then caret = fPos endif if rightkey() and VK_FLAG = 0 VK_FLAG = 1 inc caret fPos = len(__textLines$(row)) if caret > fpos then caret = fpos endif if leftkey() and VK_FLAG = 0 VK_FLAG = 1 dec caret if caret < 0 then caret = 0 endif if upkey() = 0 and downkey() = 0 and rightkey() = 0 and leftkey() = 0 VK_FLAG = 0 else __windows(index).caretPos = caret endif rem text input lineText$ = __textLines$(row) buffer$ = entry$() for i = 1 to len(buffer$) ink rgb(255,255,255),0 set cursor 10,220 print asc(mid$(buffer$,i)) select asc(mid$(buffer$,i)) case VK_COPY copyText() endcase case VK_PASTE pasteText() endcase case VK_BACKSPACE if caret > 0 t$ = left$(lineText$,caret-1) lineText$ = t$ + right$(lineText$, len(lineText$)-len(t$)-1) dec caret else if row > startingLine prevRow$ = __textLines$(row-1) lineText$ = prevRow$ + lineText$ deleteLine(fi, row) caret = len(prevRow$) dec row endif endif endcase case VK_RETURN t$ = left$(lineText$,caret) __textLines$(row) = t$ lineText$ = right$(lineText$, len(lineText$)-len(t$)) insertLine(fi,lineText$,row+1) caret = 0 inc row endcase case VK_DELETE if caret < len(lineText$) t$ = left$(lineText$, caret-1) __textLines$(row) = right$(lineText$, len(lineText$)-(len(t$)+1)) else endif endcase case default t$ = left$(lineText$,caret) lineText$ = t$ + mid$(buffer$,i) + right$(lineText$, len(lineText$)-len(t$)) inc caret if caret-startingChar > visibleChars then __windows(index).startingChar = __windows(index).startingChar+1 endcase endselect next i clear entry buffer __textLines$(row) = lineText$ __windows(index).caretPos = caret __windows(index).selectedRow = row rem check if new scrollbars are needed rem horizontal if len(lineText$) > __openFiles(fileIndex).maxWidth __openFiles(fileIndex).maxWidth = len(lineText$)-1 _resizeWindow(index) endif rem vertical if (__openFiles(fileIndex).textEnd - __openFiles(fileIndex).textIndex) > __windows(index).visibleLines _resizeWindow(index) endif rem blinking cursor if timer() >= CARET_STAMP+500 CARET_STAMP = timer() if CARET$ = "|" CARET$ = "" else CARET$ = "|" endif endif if startingChar > 0 then caret = caret+1 if __windows(index).startingChar < 0 then __windows(index).startingChar = 0 cy = y+(row-startingLine)*lineHeight cx = x+(caret-startingChar)*charWidth if cy >= y and cy < y+height and cx >= x and cx < x+width then text cx,cy,CARET$ endfunction REM ******************************* REM inserts a new line into a file REM 'fileIndex' file to insert into REM 'txt' text to insert REM 'row' line number to insert at REM ******************************* function insertLine(fileIndex as integer, txt as string, row as integer) if row < array count(__textLines$()) array insert at element __textLines$(), row else array insert at bottom __textLines$() endif __textLines$(row) = txt __openFiles(fileIndex).textEnd = __openFiles(fileIndex).textEnd+1 for f = fileIndex+1 to array count(__openFiles()) __openFiles(f).textIndex = __openFiles(f).textIndex+1 __openFiles(f).textEnd = __openFiles(f).textEnd+1 next f for w = 1 to array count(__windows()) if __windows(w).fileIndex > fileIndex then __windows(w).startingLine = __windows(w).startingLine + 1 next w endfunction REM *************************************** REM Removes a line from a text file REM Adjusts indices of other affected files REM using the __textLines$() array REM 'fileIndex' file to remove line from REM 'row' line number to remove REM *************************************** function deleteLine(fileIndex as integer, row as integer) array delete element __textLines$(), row __openFiles(fileIndex).textEnd = __openFiles(fileIndex).textEnd - 1 for f = fileIndex+1 to array count(__openFiles()) __openFiles(f).textIndex = __openFiles(f).textIndex - 1 __openFiles(f).textEnd = __openFiles(f).textEnd - 1 next f for w = 1 to array count(__windows()) if __windows(w).fileIndex > fileIndex then __windows(w).startingLine = __windows(w).startingLine - 1 next w endfunction REM *********************************** REM Prompts user with a save dialog box REM Then attempts to save the file REM *********************************** function saveAsDialog() file$ = removeTrailingSpaces$(_open_save("Text File (*.txt)|*.txt|All Files (*.*)|*.*|",get dir$(),"Save File","*.*",0)) if file$ <> "" and mid$(file$,1) <> "!" then saveFile(file$) endfunction REM ************************************* REM saves a text file REM if 'file' is an empty string, REM file is saved under its given path. REM if 'file' is not empty, the save REM function acts as a Save As function REM and saves the file under the new name REM and associates it with that path REM from then on. REM ************************************* function saveFile(file as string) index = array count(__windows()) fileIndex = __windows(index).fileIndex start = __openFiles(fileIndex).textIndex finish = __openFiles(fileIndex).textEnd if file = "" file = __openFiles(fileIndex).name if file = NEW_FILE$ saveAsDialog() exitfunction endif status_message$ = "File saved" else __openFiles(fileIndex).name = file status_message$ = "File saved as "+file endif `tempFile$ = "$_"+file `if path exist(tempFile$) then delete file tempFile$ if path exist(file) then delete file file open to write 1, file for i = start to finish write string 1, __textLines$(i) next i close file 1 `if path exist(file) then delete file file `rename file tempFile$, file endfunction REM ************************************ REM Prompts user with an open dialog box REM Then attempts to open selected file REM ************************************ function openDialog() file$ = removeTrailingSpaces$(_open_save("Text File (*.txt)|*.txt|All Files (*.*)|*.*|",get dir$(),"Open File","*.*",1)) if mid$(file$,1) <> "!" then openFile(file$) endfunction REM **************** REM open a text file REM **************** function openFile(file as string) rem local variables fileLoaded = 0 maxWidth = 0 currentTextIndex = array count(__textLines$())+1 if file = NEW_FILE$ array insert at bottom __textLines$() maxWidth = 1 fileLoaded = TRUE endif rem does the file exist if fileLoaded = FALSE and path exist(file) = TRUE rem make sure this is a text file `if lower$(right$(file,4)) = ".txt" open to read 1, file rem read in all the lines from the file into the array while file end(1) = 0 read string 1, z$ if len(z$) > maxWidth then maxWidth = len(z$) array insert at bottom __textLines$() __textLines$(array count(__textLines$())) = z$ endwhile close file 1 fileLoaded = 1 `endif endif rem file loaded if fileLoaded = TRUE status_message$ = "File opened: "+file rem store structure of file array insert at bottom __openFiles() fi = array count(__openFiles()) __openFiles(fi).maxWidth = maxWidth-1 __openFiles(fi).name = file __openFiles(fi).textIndex = currentTextIndex __openFiles(fi).textEnd = array count(__textLines$()) rem create the window array insert at bottom __windows() i = array count(__windows()) __windows(i).x = 10 __windows(i).y = 40 __windows(i).width = 500 __windows(i).height = 300 __windows(i).fileIndex = fi __windows(i).startingLine = __openFiles(fi).textIndex __windows(i).showLineNumbers = FALSE __windows(i).visibleLines = __windows(i).height/text height("A") __windows(i).visibleChars = __windows(i).width / text width("W") lineCount = __openFiles(fi).textEnd - __openFiles(fi).textIndex if lineCount = 0 __windows(i).thumbHeight = 1 else __windows(i).thumbHeight = (__windows(i).visibleLines * __windows(i).height) / lineCount endif if __openFiles(fi).maxWidth <= 0 __openFiles(fi).maxWidth = 1 __windows(i).thumbWidth = 1 else __windows(i).thumbWidth = ((__windows(i).width/text width("A"))*__windows(i).width) / __openFiles(fi).maxWidth endif if __windows(i).thumbHeight < __windows(i).height then __windows(i).showVertical = TRUE if __windows(i).thumbWidth < __windows(i).width then __windows(i).showHorizontal = TRUE endif endfunction REM ************************************* REM copies selected text to the clipboard REM from the currently active window REM ************************************* function copyText() selectionFlag = 1 if _selection.start.row = _selection.finish.row and _selection.start.char = _selection.finish.char then selectionFlag = 0 if _selection.start.char > _selection.finish.char then selectionFlag = 0 copy$ = "" if selectionFlag = 1 `if _selection.start.row = _selection.finish.row for i = _selection.start.row to _selection.finish.row t$ = __textLines$(i) a = 1 b = len(t$) if i = _selection.start.row a = _selection.start.char if a > 1 then a = a+1 endif if i = _selection.finish.row : b = _selection.finish.char : newLine$ = "" : else : newLine$ = chr$(10) : endif copy$ = copy$ + substring$(t$,a,b) + newLine$ next i endif write to clipboard copy$ endfunction REM **************************************** REM pastes contents of clipboard into window REM at the cursor's position REM BUGGY!!! why? REM **************************************** function pasteText() rem focused window is always at end of array index = array count(__windows()) fileIndex = __windows(index).fileIndex textIndex = __openFiles(fileIndex).textIndex caret = __windows(index).caretPos row = __windows(index).selectedRow cb$ = get clipboard$() t$ = left$(__textLines$(row),caret) e$ = right$(__textLines$(row),len(__textLines$(row))-caret) `__textLines$(row) = t$ + cb$ for i = 1 to len(cb$) c$ = mid$(cb$,i) if c$ = chr$(10) OR c$ = chr$(13) insertLine(fileIndex, t$, row) t$ = "" inc row else t$ = t$ + c$ endif next i if t$ <> "" then insertLine(fileIndex, t$, row) __textLines$(row) = __textLines$(row) + e$ endfunction function handleStatusBar() sh = screen height() sw = screen width() size = 16 ink rgb(192,192,192),0 box 0,sh-size,sw,sh ink 0,0 line 0,sh-size,sw,sh-size line 0,sh-size,0,sh text 10,sh-size,status_message$ endfunction REM ******************* REM draws a text window REM ******************* function _drawWindow(index as integer) x = __windows(index).x y = __windows(index).y width = __windows(index).width height = __windows(index).height thumbX = __windows(index).thumbX thumbY = __windows(index).thumbY fileIndex = __windows(index).fileIndex textIndex = __openFiles(fileIndex).textIndex lineCount = __openFiles(fileIndex).textEnd - textIndex maxWidth = __openFiles(fileIndex).maxWidth lineHeight = text height("A") charWidth = text width("A") visibleChars = __windows(index).visibleChars visibleLines = __windows(index).visibleLines thumbHeight = __windows(index).thumbHeight thumbWidth = __windows(index).thumbWidth startingChar = __windows(index).startingChar displayName$ = __openFiles(fileIndex).name if text width(displayName$) > width t = width/charWidth - 3 displayName$ = left$(displayName$,t)+"..." endif rem title bar if index < array count(__windows()) c1 = rgb(192,192,192) c2 = rgb(128,128,128) else c1 = rgb(10,36,106) c2 = rgb(166,202,240) endif box x,y-TITLEBARSIZE,x+width+SCROLLBARSIZE,y,c1,c2,c1,c2 ink rgb(225,225,225),0 text x+2,y-TITLEBARSIZE,displayName$ rem scrollbars rem vertical rem track ink rgb(192,192,192),0 box x+width,y,x+width+SCROLLBARSIZE,y+height rem thumb if __windows(index).showVertical = TRUE ink rgb(128,128,128),0 box x+width,y+thumbY,x+width+SCROLLBARSIZE,y+thumbY+thumbHeight ink rgb(200,200,200),0 line x+width,y+thumbY,x+width+SCROLLBARSIZE,y+thumbY line x+width,y+thumbY,x+width,y+thumbY+thumbHeight ink rgb(40,40,40),0 line x+width+SCROLLBARSIZE,y+thumbY,x+width+SCROLLBARSIZE,y+thumbY+thumbHeight line x+width,y+thumbY+thumbHeight,x+width+SCROLLBARSIZE,y+thumbY+thumbHeight endif rem horizontal rem track ink rgb(192,192,192),0 box x,y+height,x+width,y+height+SCROLLBARSIZE rem thumb if __windows(index).showHorizontal = TRUE ink rgb(128,128,128),0 box x+thumbX,y+height,x+thumbX+thumbWidth,y+height+SCROLLBARSIZE ink rgb(200,200,200),0 line x+thumbX,y+height,x+thumbX+thumbWidth,y+height line x+thumbX,y+height,x+thumbX,y+height+SCROLLBARSIZE ink rgb(40,40,40),0 line x+thumbX,y+height+SCROLLBARSIZE,x+thumbX+thumbWidth,y+height+SCROLLBARSIZE line x+thumbX+thumbWidth,y+height,x+thumbX+thumbWidth,y+height+SCROLLBARSIZE endif rem lower corner where 2 scrollbars meet ink rgb(128,128,128),0 box x+width,y+height,x+width+SCROLLBARSIZE,y+height+SCROLLBARSIZE rem background ink rgb(208,219,219),0 box x,y,x+width,y+height rem background shadow ink rgb(25,25,25),0 box x+4,y+height+SCROLLBARSIZE,x+width+SCROLLBARSIZE+4,y+height+SCROLLBARSIZE+4 box x+width+SCROLLBARSIZE,y-TITLEBARSIZE+4,x+width+SCROLLBARSIZE+4,y+height+SCROLLBARSIZE rem if show line numbers, draw the border if __windows(index).showLineNumbers = TRUE tOffset = text width(str$(lineCount)+" ")+4 box x,y,x+tOffset-4,y+height,rgb(208,219,219),rgb(208,219,219),rgb(160,171,171),rgb(160,171,171) ink rgb(128,128,128),0 box x+tOffset-5,y,x+tOffset-4,y+height alignSize = len(str$(lineCount)) else tOffset = 2 endif selectionFlag = 1 if _selection.start.row = _selection.finish.row and _selection.start.char = _selection.finish.char then selectionFlag = 0 if _selection.start.char > _selection.finish.char then selectionFlag = 0 rem the text routine startingLine = __windows(index).startingLine for i = startingLine to startingLine + visibleLines-1 L = i - startingLine if i <= __openFiles(fileIndex).textEnd rem display line number border if __windows(index).showLineNumbers = TRUE then text x+2,y+L*lineHeight, justify$(str$(i-textIndex+1),alignSize,0) rem get visible text if i > 0 and i <= array count(__textLines$()) then t$ = substring$(__textLines$(i), startingChar,startingChar+visibleChars) rem reset text color for the line to be displayed ink 0,0 rem draw selection boxes if selectionFlag = 1 rem if this line is part of the selection if i >= _selection.start.row and i <= _selection.finish.row sy1 = y+L*lineHeight rem if this entire line should be highlighted if i > _selection.start.row and i < _selection.finish.row sx1 = x+tOffset sx2 = sx1+len(t$)*charWidth ink rgb(0,0,255),0 box sx1,sy1,sx2,sy1+lineHeight ink rgb(255,255,255),0 text x+tOffset,sy1, t$ else `i is either first or last row of selection rem if selection is all on same line if _selection.start.row = _selection.finish.row sx1 = x+tOffset+_selection.start.char*charWidth sx2 = x+tOffset+_selection.finish.char*charWidth ink rgb(0,0,255),0 box sx1,sy1,sx2,sy1+lineHeight ink rgb(255,255,255),0 c1 = _selection.start.char c2 = _selection.finish.char if _selection.start.char < startingChar then c1 = startingChar if _selection.finish.char > startingChar+visibleChars then c2 = startingChar+visibleChars middle$ = substring$(__textLines$(i), c1, c2) edge = 1 if _selection.start.char = startingChar then edge = 0 text x+tOffset+(_selection.start.char-startingChar-edge)*charWidth,sy1,middle$ begin$ = substring$(__textLines$(i),startingChar,_selection.start.char) last$ = substring$(__textLines$(i),_selection.finish.char+1,startingChar+visibleChars) ink 0,0 text x+tOffset,sy1,begin$ text x+tOffset+(len(middle$+begin$)-edge)*charWidth,sy1,last$ else rem first row of a multi-line selection if i = _selection.start.row sx1 = x+tOffset+_selection.start.char*charWidth sx2 = x+tOffset+len(t$)*charWidth begin$ = substring$(__textLines$(i),startingChar,_selection.start.char) last$ = substring$(__textLines$(i),_selection.start.char+1,startingChar+visibleChars) sx1 = x+tOffset+len(begin$)*charWidth sx2 = x+tOffset+len(t$)*charWidth ink rgb(0,0,255),0 box sx1,sy1,sx2,sy1+lineHeight ink rgb(255,255,255),0 text x+tOffset+len(begin$)*charWidth,sy1,last$ ink 0,0 text x+tOffset,sy1,begin$ else `last row of a multi-line selection sx1 = x+tOffset sx2 = x+tOffset+_selection.finish.char*charWidth begin$ = substring$(__textLines$(i),startingChar,_selection.finish.char) last$ = substring$(__textLines$(i),_selection.finish.char+1,startingChar+visibleChars) sx1 = x+tOffset sx2 = x+tOffset+len(begin$)*charWidth ink rgb(0,0,255),0 box sx1,sy1,sx2,sy1+lineHeight ink rgb(255,255,255),0 text x+tOffset,sy1,begin$ ink 0,0 text x+tOffset+len(begin$)*charWidth,sy1,last$ endif endif endif else rem display text text x+tOffset,y+L*lineHeight, t$ endif else rem display text text x+tOffset,y+L*lineHeight, t$ endif endif next i endfunction REM ******************** REM handles UI of window REM ******************** function _handleWindowUI(index as integer) x = __windows(index).x y = __windows(index).y width = __windows(index).width height = __windows(index).height thumbX = __windows(index).thumbX thumbY = __windows(index).thumbY thumbHeight = __windows(index).thumbHeight thumbWidth = __windows(index).thumbWidth fileIndex = __windows(index).fileIndex textIndex = __openFiles(fileIndex).textIndex lineCount = __openFiles(fileIndex).textEnd - textIndex maxWidth = __openFiles(fileIndex).maxWidth lineHeight = text height("A") visibleLines = __windows(index).visibleLines visibleChars = __windows(index).visibleChars grabbedWindow = 0 if thumbY < 0 then thumbY = 0 if thumbY > height-thumbHeight then thumbY = height-thumbHeight __windows(index).thumbY = thumbY if mouseclick() = 1 rem handle vertical scrollbar if __windows(index).showVertical = TRUE if CLICK_FLAG = 0 and mouseWithin(x+width,y+thumbY,x+width+SCROLLBARSIZE,y+thumbY+thumbHeight) __windows(index).thumbYFlag = TRUE __windows(index).thumbOffsetY = thumbY - mousey() CLICK_FLAG = 1 endif if __windows(index).thumbYFlag = TRUE thumbY = mousey() + __windows(index).thumbOffsetY if thumbY < 0 then thumbY = 0 if thumbY > height-thumbHeight then thumbY = height-thumbHeight __windows(index).thumbY = thumbY __windows(index).startingLine = textIndex + ((lineCount-visibleLines+1)*thumbY) / (height-thumbHeight) endif endif rem handle horizontal scrollbar if __windows(index).showHorizontal = TRUE if CLICK_FLAG = 0 and mouseWithin(x+thumbX,y+height,x+thumbX+thumbWidth,y+height+SCROLLBARSIZE) __windows(index).thumbXFlag = TRUE __windows(index).thumbOffsetX = thumbX - mousex() CLICK_FLAG = 1 endif if __windows(index).thumbXFlag = TRUE thumbX = mousex() + __windows(index).thumbOffsetX if thumbX < 0 then thumbX = 0 if thumbX > width-thumbWidth then thumbX = width-thumbWidth __windows(index).thumbX = thumbX __windows(index).startingChar = ((maxWidth-visibleChars)*thumbX) / (width-thumbWidth) endif endif rem handle titlebar if CLICK_FLAG = 0 and mouseWithin(x,y-TITLEBARSIZE,x+width+SCROLLBARSIZE,y) __windows(index).titleFlag = TRUE __windows(index).titleOffsetX = x - mousex() __windows(index).titleOffsetY = y - mousey() CLICK_FLAG = 1 endif if __windows(index).titleFlag = TRUE __windows(index).x = mousex() + __windows(index).titleOffsetX __windows(index).y = mousey() + __windows(index).titleOffsetY endif rem handle resizing if CLICK_FLAG = 0 and mouseWithin(x+width,y+height,x+width+SCROLLBARSIZE,y+height+SCROLLBARSIZE) __windows(index).resizeFlag = TRUE __windows(index).resizeOffsetX = x+width - mousex() __windows(index).resizeOffsetY = y+height - mousey() CLICK_FLAG = 1 endif if __windows(index).resizeFlag = TRUE __windows(index).width = mousex() - __windows(index).x + __windows(index).resizeOffsetX __windows(index).height = mousey() - __windows(index).y + __windows(index).resizeOffsetY if __windows(index).width < MIN_WIDTH then __windows(index).width = MIN_WIDTH if __windows(index).height < MIN_HEIGHT then __windows(index).height = MIN_HEIGHT _resizeWindow(index) endif rem if windows was clicked on, make it top component if CLICK_FLAG = 0 and mouseWithin(x,y-TITLEBARSIZE,x+width+SCROLLBARSIZE,y+height) grabbedWindow = index `CLICK_FLAG = 1 endif else __windows(index).thumbXFlag = FALSE __windows(index).thumbYFlag = FALSE __windows(index).titleFlag = FALSE __windows(index).resizeFlag = FALSE endif endfunction grabbedWindow REM ****************************** REM this is called whenever a REM window's size has been changed REM recalculates scrollbar and REM viewing sizes REM ****************************** function _resizeWindow(index as integer) fi = __windows(index).fileIndex lineCount = __openFiles(fi).textEnd - __openFiles(fi).textIndex + 1 __windows(index).visibleLines = __windows(index).height/text height("A") __windows(index).thumbHeight = (__windows(index).visibleLines * __windows(index).height) / lineCount __windows(index).thumbWidth = ((__windows(index).width/text width("A"))*__windows(index).width) / __openFiles(fi).maxWidth __windows(index).visibleLines = __windows(index).height/text height("A") __windows(index).visibleChars = __windows(index).width / text width("W") if __windows(index).thumbHeight < __windows(index).height __windows(index).showVertical = TRUE else __windows(index).showVertical = FALSE endif if __windows(index).thumbWidth < __windows(index).width __windows(index).showHorizontal = TRUE else __windows(index).showHorizontal = FALSE endif `__windows(index).thumbX = (__windows(index).startingChar*(__windows(index).width - __windows(index).thumbWidth)) / (__openFiles(fi).maxWidth - __windows(index).visibleChars) endfunction REM *************************** REM Create a new drop-down menu REM *************************** function addMenu(name as string) m as Menu m.name = name array insert at bottom menus() count = array count(menus()) menus(count) = m endfunction count REM ***************************** REM add a menu item to menu 'pid' REM ***************************** function addMenuItem(pid as integer, item as string, enabled as boolean, check as integer) m as MenuItem m.parentID = pid m.item = item m.enabled = enabled m.check = check array insert at bottom menuItems() menuItems(array count(menuItems())) = m rem make sure menu is drawn wide enough to handle this item's name width = text width(item)+6 if width > menus(pid).width then menus(pid).width = width menus(pid).count = menus(pid).count + 1 endfunction REM ******************** REM Handles the menus UI REM ******************** function _handleMenus$(mc as integer) v$ = "" offsetX = 0 active = -1 activeOffset = 0 rem text height, vertical spacing tw = 16 rem draw menu bar ink rgb(192,192,192),0 box 0,0,screen width(),tw rem clock box tx = screen width() - (text width("99:99 :AM")+4) ink 0,0 text tx+2,1,getTime$() line tx,1,screen width()-1,1 line tx,1,tx,tw-1 ink rgb(255,255,255),0 line tx,tw-1,screen width()-1,tw-1 line screen width()-1,1,screen width()-1,tw-1 for i = 0 to array count(menus()) width = text width(menus(i).name) if mc = 1 if mousex() >= offsetX and mousex() <= offsetX+width+6 and mousey() >= 0 and mousey() <= tw if _mouseFlag = 0 _mouseFlag = 1 if menus(i).active = 0 menus(i).active = 1 else menus(i).active = 0 endif for t = 0 to array count(menus()) if t <> i then menus(t).active = 0 next t endif endif endif if menus(i).active = 1 active = i activeOffset = offsetX ink rgb(0,180,250),0 box offsetX,0,offsetX+width+6,tw else `ink rgb(192,192,192),0 endif `box offsetX,0,offsetX+width+6,tw ink 0,0 text offsetX+3,0,menus(i).name offsetX = offsetX + width + 6 next i if active > -1 ink rgb(192,192,192),0 box activeOffset,tw,activeOffset+menus(active).width,tw+menus(active).count*tw offsetY = 0 ink 0,0 for i = 0 to array count(menuItems()) if menuItems(i).parentID = active inc offsetY if mousex() > activeOffset and mousex() < activeOffset+menus(active).width and mousey() > offsetY*tw and mousey() < (offsetY+1)*tw ink rgb(0,180,250),0 box activeOffset+1,offsetY*tw+1,activeOffset+menus(active).width-1,(offsetY+1)*tw-1 rem if this item was clicked if mc = 1 if _mouseFlag = 0 _mouseFlag = 1 if menuItems(i).enabled = 1 v$ = menus(active).name + "-" + menuItems(i).item menus(active).active = 0 exitfunction v$ endif endif endif endif if menuItems(i).enabled = 1 ink 0,0 else ink rgb(120,120,120),0 endif text activeOffset+3,offsetY*tw,menuItems(i).item endif next i endif endfunction v$ REM ************************************** REM Close the active window REM technically, i should be releasing REM all the resources used by this window, REM but im lazy and its 5:30am REM ************************************** function closeWindow() array delete element __windows(), array count(__windows()) endfunction REM **************************************** REM Counts words (3 or more characters) REM and displays the total in the status bar REM **************************************** function countWords() fileIndex = __windows(array count(__windows())).fileIndex start = __openFiles(fileIndex).textIndex finish = __openFiles(fileIndex).textEnd total = 0 for i = start to finish t$ = __textLines$(i) temp$ = "" for j = 1 to len(t$) c$ = mid$(t$,j) if c$ = " " if len(temp$) > 2 then inc total temp$ = "" else temp$ = temp$ + c$ endif next j if len(temp$) > 2 then inc total next i status_message$ = "Word count: "+str$(total) endfunction REM **************************************** REM Counts number of characters REM and displays the total in the status bar REM **************************************** function countCharacters() fileIndex = __windows(array count(__windows())).fileIndex start = __openFiles(fileIndex).textIndex finish = __openFiles(fileIndex).textEnd total = 0 for i = start to finish inc total, len(__textLines$(i)) next i status_message$ = "Character count: "+str$(total) endfunction REM **************************** REM returns a substring of 's' REM beginning and ending indices REM are both inclusive REM **************************** function substring$(s as string, bIndex, eIndex) if eIndex < 0 then exitfunction "" s = left$(s,eIndex) if len(s)-(bIndex-1) < 0 then exitfunction "" s = right$(s, len(s)-(bIndex-1)) endfunction s REM ******************************* REM Returns a string of the current REM time in 12hour REM ******************************* function getTime$() hour$ = left$(get time$(), 2) v = val(hour$) day$ = " am" if v > 11 day$ = " pm" if v > 12 then hour$ = str$(v-12) endif if len(hour$) < 2 then hour$ = " "+right$(hour$,1) min$ = right$(left$(get time$(),5), 2) time$ = hour$+":"+min$+day$ endfunction time$ REM ********************** REM Justifies text REM 0 for right, 1 for left REM *********************** function justify$(s as string, length as integer, alignment as integer) if alignment = 0 then s = space$(length - len(s)) + s if alignment = 1 then s = s + space$(length - len(s)) endfunction s REM **************************** REM returns 1 if mouse is within REM the defined box area REM **************************** function mouseWithin(x1,y1,x2,y2) if mousex() > x1 and mousex() < x2 and mousey() > y1 and mousey() < y2 then exitfunction 1 endfunction 0 REM ****************************************** REM removes trailing whitespaces from a string REM ****************************************** function removeTrailingSpaces$(s as string) L = len(s) for i = L to 1 step -1 if mid$(s,i) <> " " then exitfunction left$(s,i) next i endfunction "" REM ******************************************************** REM * * REM * Windows Dialogs * REM * * REM ******************************************************** Function _open_save(filter As String,initdir As String,dtitle As String,defext As String,open As Boolean) `filter = "Text Documents ( *.txt )|*.txt|All Files ( *.* )|*.*|" `initdir = "C:" `dtitle = "Open ~ Test" `defext = "txt" `open = 1 For Open Dialogu, 0 for save dialogue `Get DLL numbers user32 As Integer comdlg32 As Integer `Load in required DLL's user32 = _find_fee_dll() Load DLL "user32.dll",user32 comdlg32 = _find_fee_dll() Load DLL "comdlg32.dll",comdlg32 `Get handle ( unique ID ) to the calling ( this ) window hwnd As DWord hwnd = Call DLL(user32,"GetActiveWindow") `Unload DLL as it is no longer needed Delete DLL user32 `Get the Memblock Number OPENFILENAME As Integer OPENFILENAME = _find_free_mem() `Make The Memblock containing the OPENFILENAME structure Make MemBlock OPENFILENAME,76 `Get the pointer to the just created Structure lpofn As DWord lpofn = Get MemBlock Ptr(OPENFILENAME) `Declare temp variables to hold data for OPENFILENAME structure size As Integer filebuffer As String filebufferptr As DWord flags As DWord filter = filter + "|" initdir = initdir + "|" dtitle = dtitle + "|" defext = defext + "|" filebuffer = "|" + Space$(255) + "|" filebufferptr = _get_str_ptr(filebuffer) flags = 0x00001000 || 0x00000004 || 0x00000002 size = 0 Write MemBlock DWord OPENFILENAME,0,76 : `lStructSize Write MemBlock DWord OPENFILENAME,4,hwnd : `hwndOwner `Write MemBlock DWord OPENFILENAME,8,NULL : `hInstance Write MemBlock DWord OPENFILENAME,12,_get_str_ptr(filter) : `lpstrFilter `Write MemBlock DWord OPENFILENAME,16,0 : `lpstrCustomFilter `Write MemBlock DWord OPENFILENAME,20,NULL : `nMaxCustFilter Write MemBlock DWord OPENFILENAME,24,1 : `nFilterIndex Write MemBlock DWord OPENFILENAME,28,filebufferptr : `lpstrFile Write MemBlock DWord OPENFILENAME,32,256 : `nMaxFile `Write MemBlock DWord OPENFILENAME,36,0 : `lpstrFileTitle `Write MemBlock DWord OPENFILENAME,40,NULL : `nMaxFileTitle Write MemBlock DWord OPENFILENAME,44,_get_str_ptr(initdir) : `lpstrInitialDir Write MemBlock DWord OPENFILENAME,48,_get_str_ptr(dtitle) : `lpstrTitle Write MemBlock DWord OPENFILENAME,52,flags : `Flags `Write MemBlock Word OPENFILENAME,56,NULL : `nFileOffset `Write MemBlock Word OPENFILENAME,58,NULL : `nFileExtension Write MemBlock DWord OPENFILENAME,60,_get_str_ptr(defext) : `lpstrDefExt `Write MemBlock DWord OPENFILENAME,64,NULL : `lCustData `Write MemBlock DWord OPENFILENAME,68,NULL : `lpfnHook `Write MemBlock DWord OPENFILENAME,72,0 : `lpTemplateName `Call the Command to open the dialouge retval As DWord If open retval = Call DLL(comdlg32,"GetOpenFileNameA",lpofn) Else retval = Call DLL(comdlg32,"GetSaveFileNameA",lpofn) EndIf `Check if it was sucecfull If retval <> 0 code$ = _get_str(filebufferptr,256) Else retval = Call DLL(comdlg32,"CommDlgExtendedError") Select retval Case 0xFFFF : code$ = "!The dialog box could not be created. The common dialog box function's call to the DialogBox function failed. For example, this error occurs if the common dialog box call specifies an invalid window handle." : EndCase Case 0x0006 : code$ = "!The common dialog box function failed to find a specified resource." : EndCase Case 0x0004 : code$ = "!The ENABLETEMPLATE flag was set in the Flags member of the initialization structure for the corresponding common dialog box, but you failed to provide a corresponding instance handle." : EndCase Case 0x0002 : code$ = "!The common dialog box function failed during initialization. This error often occurs when sufficient memory is not available." : EndCase Case 0x000B : code$ = "!The ENABLEHOOK flag was set in the Flags member of the initialization structure for the corresponding common dialog box, but you failed to provide a pointer to a corresponding hook procedure." : EndCase Case 0x0008 : code$ = "!The common dialog box function failed to lock a specified resource." : EndCase Case 0x0003 : code$ = "!The ENABLETEMPLATE flag was set in the Flags member of the initialization structure for the corresponding common dialog box, but you failed to provide a corresponding template." : EndCase Case 0x0007 : code$ = "!The common dialog box function failed to load a specified string." : EndCase Case 0x0001 : code$ = "!The lStructSize member of the initialization structure for the corresponding common dialog box is invalid." : EndCase Case 0x0005 : code$ = "!The common dialog box function failed to load a specified string." : EndCase Case 0x3003 : code$ = "!The buffer pointed to by the lpstrFile member of the OPENFILENAME structure is too small for the file name specified by the user. The first two bytes of the lpstrFile buffer contain an integer value specifying the size, in TCHARs, required to receive the full name." : EndCase Case 0x0009 : code$ = "!The common dialog box function was unable to allocate memory for internal structures." : EndCase Case 0x3002 : code$ = "!A file name is invalid." : EndCase Case 0x000A : code$ = "!The common dialog box function was unable to lock the memory associated with a handle." : EndCase Case 0x3001 : code$ = "!An attempt to subclass a list box failed because sufficient memory was not available." : EndCase Case Default : code$ = "!WHOOPS!" : EndCase EndSelect EndIF Delete DLL comdlg32 EndFunction code$ Function _get_str_ptr(pstr As String) `pstr$ should be a "|" ( NULL ) seperated string. memnum As Integer strlen As Integer char As Byte memptr As DWord strptr As DWord memnum = _find_free_mem() strlen = Len(pstr) Make MemBlock memnum,strlen For i = 1 To strlen If Mid$(pstr,i) = "|" char = 0 Else char = Asc(Mid$(pstr,i)) EndIf Write MemBlock Byte memnum,(i - 1),char Next i memptr = Get MemBlock Ptr(memnum) strptr = Make Memory(strlen) Copy Memory strptr,memptr,strlen Delete MemBlock memnum EndFunction strptr Function _get_str(strptr As DWord,strsize As Integer) `strptr is the pointer returned by _get_str_ptr() `strsize is the Integer length of the string specified by the pointer memnum As Integer memptr As DWord str As String char As String memnum = _find_free_mem() Make MemBlock memnum,strsize memptr = Get MemBlock Ptr(memnum) Copy Memory memptr,strptr,strsize For i = 1 To strsize str = str + Chr$(MemBlock Byte(memnum,i - 1)) Next i EndFunction str Function _find_fee_dll() retval = 0 Repeat Inc retval Until DLL Exist(retval) = 0 EndFunction retval Function _find_free_mem() retval = 50 Repeat Inc retval Until MemBlock Exist(retval) = 0 EndFunction retval