Unless someone spots a bug in the code, I think this is about as far as I will go with this. Everything else is just cosmetics as well as enabling Save, Save As, and checking for valid clipboard content.
The main purpose was to add line numbers and I think we reached that goal, ...and then some
Code: Select all
; *************************************************************
; Title: Sparkies EditorGadget with line numbers"
; Author: Spakie
; Start Date: December 24, 2004 9:50 AM
; Version 0.27B: December 29, 2004 2:10 PM
; License: Free to use, optimize, and modify at will :)
; *************************************************************
; ********************************************************
; --> Start Constants
; ********************************************************
#SES_EMULATESYSEDIT = 1
#SCF_ALL = 4
#PFM_NUMBERINGSTART = $8000
#PFM_NUMBERINGSTYLE = $2000
#PFM_NUMBERINGTAB = $4000
; ********************************************************
; <-- End Constants
; ********************************************************
; ********************************************************
; --> Start Enumerations
; ********************************************************
Enumeration
#MainWin
EndEnumeration
Enumeration
#StatusBar
#MainMenu
#EditorPopup
EndEnumeration
Enumeration
#LineNumbers
#Editor
#Lines_Conatiner
EndEnumeration
; ********************************************************
; <-- End Enumerations
; ********************************************************
; ********************************************************
; --> Start Structures
; ********************************************************
; --> CHARRANGE structure for 'Select All' popup menu command
editSel.CHARRANGE
; --> CHARFORMAT structure for text formatting
egFormat.CHARFORMAT
egFormat\cbSize = SizeOf(CHARFORMAT)
; ********************************************************
; <-- End Structures
; ********************************************************
; ********************************************************
; --> Start Main window callback procedure
; ********************************************************
Procedure.l myWindowCallback(hwnd, msg, wparam, lparam)
Shared previousItems
result = #PB_ProcessPureBasicEvents
Select msg
Case #WM_COMMAND
If lparam = GadgetID(#Editor)
Select wparam >>16&$FFFF
Case #EN_VSCROLL
; --> Keep linenumbers in sync with EditorGadget scrolling up or down (clicking scroll buttons)
SendMessage_(GadgetID(#Editor), #EM_GETSCROLLPOS, 0, @egOne.POINT)
; --> Keep numbers from scrolling left
egOne\x = 0
SendMessage_(GadgetID(#LineNumbers), #EM_SETSCROLLPOS, 0, egOne)
Case #EN_UPDATE
; --> Keep linenumbers in sync with EditorGadget scrolling up or down (dragging scroll thumb)
SendMessage_(GadgetID(#Editor), #EM_GETSCROLLPOS, 0, @egOne.POINT)
; --> Keep numbers from scrolling left
egOne\x = 0
SendMessage_(GadgetID(#LineNumbers), #EM_SETSCROLLPOS, 0, egOne)
Case #EN_CHANGE
; --> Keep linenumbers in sync with EditorGadget adding or removing items
currentLine = SendMessage_(GadgetID(#Editor), #EM_LINEFROMCHAR, -1, 0)+1
lnItems = CountGadgetItems(#LineNumbers)
egItems = CountGadgetItems(#Editor)
; --> Add neeeded number of items in Linenumbers
If egItems > lnItems
For i = lnItems+1 To egItems
AddGadgetItem(#LineNumbers, i, RSet(Str(i), 4, "0"))
Next i
EndIf
; --> Remove un-neeeded number of items in Linenumbers
If egItems < lnItems
For i = lnItems To egItems Step -1
RemoveGadgetItem(#LineNumbers, i)
Next i
; --> Remove the last CR/LF left behind by RemoveGadgetItem
; --> Readonly off for linenumbers
SendMessage_(GadgetID(#LineNumbers), #EM_SETREADONLY, 0, 0)
SendMessage_(GadgetID(#LineNumbers), #WM_KEYDOWN, #VK_BACK, 0)
SendMessage_(GadgetID(#LineNumbers), #WM_KEYUP, #VK_BACK, 0)
; --> Readonly for linenumbers
SendMessage_(GadgetID(#LineNumbers), #EM_SETREADONLY, 1, 0)
EndIf
; --> Keep linenumbers in sync with EditorGadget scrolling up or down (dragging scroll thumb)
SendMessage_(GadgetID(#Editor), #EM_GETSCROLLPOS, 0, @egOne.POINT)
; --> Keep numbers from scrolling left
egOne\x = 0
SendMessage_(GadgetID(#LineNumbers), #EM_SETSCROLLPOS, 0, egOne)
EndSelect
EndIf
EndSelect
ProcedureReturn result
EndProcedure
; ********************************************************
; <-- End Main window callback procedure
; ********************************************************
; ********************************************************
; --> Start open file procedure
; ********************************************************
Procedure openTheFile()
oFile$ = OpenFileRequester("Select a File", "c:\", "Text file (.txt) | *.txt", 0)
If FileSize(oFile$) > 0 And FileSize(oFile$) < 65535
If ReadFile(0, oFile$)
ClearGadgetItemList(#LineNumbers)
ClearGadgetItemList(#Editor)
While Eof(0) = 0
egText$ + ReadString() + Chr(13)
Wend
AddGadgetItem(#Editor, -1, egText$)
CloseFile(0)
Else
MessageRequester("Error", "Could not open file: " + oFile$, #MB_ICONERROR)
EndIf
Else
MessageRequester("Error", "File not found: " + oFile$, #MB_ICONERROR)
EndIf
EndProcedure
; ********************************************************
; <-- End open file procedure
; ********************************************************
; ********************************************************
; --> Start main window , menu, and gadgets
; ********************************************************
If OpenWindow(#MainWin, 0, 0, 700, 500, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "EditorGadget w/Line Numbers") And CreateGadgetList(WindowID(0))
SetWindowCallback(@myWindowCallback())
CreateStatusBar(#StatusBar, WindowID(#MainWin))
; ********************************************************
; --> Start Main menu
; ********************************************************
CreateMenu(#MainMenu, WindowID(#MainWin))
MenuTitle("&File")
MenuItem(101, "&Open..." + Chr(9 ) + "Ctrl+O")
MenuItem(102, "&Save")
MenuItem(103, "S&ave as")
MenuItem(104, "&Quit" + Chr(9) + "Ctrl+Q")
MenuTitle("&Edit")
MenuItem(111, "&Undo" + Chr(9 ) + "Ctrl+z")
MenuBar()
MenuItem(112, "&Cut" + Chr(9 ) + "Ctrl+X")
MenuItem(113, "C&opy" + Chr(9 ) + "Ctrl+C")
MenuItem(114, "&Paste" + Chr(9 ) + "Ctrl+V")
MenuBar()
MenuItem(115, "Select &All" + Chr(9 ) + "Ctrl+A")
MenuTitle("&Options")
OpenSubMenu("&Editor")
MenuItem(121, "&Font...")
MenuItem(122, "&Background Color...")
CloseSubMenu()
OpenSubMenu("&Numbers")
MenuItem(123, "&Font Color...")
MenuItem(124, "&Background Color...")
CloseSubMenu()
; --> Disable 'save' and 'save as' for now
DisableMenuItem(102, 1)
DisableMenuItem(103, 1)
; ********************************************************
; <-- End Main menu
; ********************************************************
; ********************************************************
; --> Start keyboard shortcuts
; ********************************************************
AddKeyboardShortcut(#MainWin, #PB_Shortcut_Control | #PB_Shortcut_O, 101)
; disabled AddKeyboardShortcut(#MainWin, #PB_Shortcut_Control | #PB_Shortcut_S, 102)
; disabled AddKeyboardShortcut(#MainWin, #PB_Shortcut_Control | #PB_Shortcut_A, 103)
AddKeyboardShortcut(#MainWin, #PB_Shortcut_Control | #PB_Shortcut_Q, 104)
; ********************************************************
; <-- End keyboard shortcuts
; ********************************************************
; ********************************************************
; --> Start EditorGadget for Linenumbers
; ********************************************************
; --> Container is narrower than Linenumbers to hide scrollbar
ContainerGadget(#Lines_Conatiner, 0, 0, 60, 460)
EditorGadget(#LineNumbers, 3, 3, 85, 454)
AddGadgetItem(#LineNumbers, -1, "0001")
; --> Set background color for numbers
SendMessage_(GadgetID(#LineNumbers), #EM_SETBKGNDCOLOR, 0, RGB(248, 248, 220))
; --> Readonly for linenumbers
SendMessage_(GadgetID(#LineNumbers), #EM_SETREADONLY, 1, 0)
CloseGadgetList()
; ********************************************************
; <-- End EditorGadget for Linenumbers
; ********************************************************
; ********************************************************
; --> Start EditorGadget for Editor
; ********************************************************
EditorGadget(#Editor, 60, 3, 637, 454)
; --> Set left margin for #Editor
SendMessage_(GadgetID(#Editor), #EM_SETMARGINS, #EC_LEFTMARGIN, 5)
; --> Draft mode forces ASCII text at all times
SendMessage_(GadgetID(#Editor), #EM_SETEDITSTYLE , #SES_EMULATESYSEDIT, #SES_EMULATESYSEDIT)
; --> Set Editor to 64K text limit
SendMessage_(GadgetID(#Editor), #EM_SETLIMITTEXT, 0, 0)
; --> Set background color for Editorgadget
SendMessage_(GadgetID(#Editor), #EM_SETBKGNDCOLOR, 0, RGB(228, 228, 200))
; --> Set #EN_UPDATE, #EN_CHANGE and #EN_SCROLL event catching for EditorGadget
SendMessage_(GadgetID(#Editor), #EM_SETEVENTMASK, 0, #ENM_UPDATE | #ENM_CHANGE | #ENM_SCROLL | #ENM_KEYEVENTS)
; ********************************************************
; <-- End EditorGadget for Editor
; ********************************************************
; *******************************************************
; --> Start filling CHARFORMAT structure
; ********************************************************
; --> Set our formatting mask to change font, size, and color
egFormat\dwMask = #CFM_SIZE | #CFM_COLOR | #CFM_FACE
; --> I'll use 12pt Arial (yHeight is twips 1/1440 of an inch | 1/20 of printer point)
egFormat\yHeight = 12*20
fontName$ = "Arial"
PokeS(@egFormat\szFaceName, fontName$)
; --> Send info to both EditorGadgets
egFormat\crTextColor = RGB(0, 80, 0)
SendMessage_(GadgetID(#LineNumbers), #EM_SETCHARFORMAT, #SCF_ALL, @egFormat)
egFormat\crTextColor = RGB(0, 0, 80)
SendMessage_(GadgetID(#Editor), #EM_SETCHARFORMAT, #SCF_ALL, @egFormat)
; *******************************************************
; <-- End filling CHARFORMAT structure
; ********************************************************
; ********************************************************
; --> Start popup menu for EditorGadget
; ********************************************************
CreatePopupMenu(#EditorPopup)
MenuItem(201, "&Undo")
MenuBar()
MenuItem(202, "&Cut")
MenuItem(203, "C&opy")
MenuItem(204, "&Paste")
MenuBar()
MenuItem(205, "Select &All")
; ********************************************************
; <-- End popup menu for EditorGadget
; ********************************************************
; ********************************************************
; --> Start Main loop
; ********************************************************
Repeat
event = WaitWindowEvent()
; --> Keep focus out of linenumbers
If EventGadgetID() = #LineNumbers
ActivateGadget(#Editor)
EndIf
Select event
Case #WM_RBUTTONDOWN
xPos = WindowMouseX()-5
yPos = WindowMouseY()-5
; ********************************************************
; --> Start display popup menu for EditorGadget
; ********************************************************
; --> Make sure mouse is over Editor befor displaying popup menu
If xPos >= GadgetX(#Editor)+2 And xPos <= (GadgetX(#Editor)+ GadgetWidth(#Editor)-4)
If yPos >= GadgetY(#Editor)+2 And yPos <= (GadgetY(#Editor)+ GadgetHeight(#Editor)-4)
If Len(GetGadgetText(#Editor)) < 1
; --> If no text found in Editor, disable all menu items except 'Paste'
DisableMenuItem(201,1)
DisableMenuItem(202,1)
DisableMenuItem(203,1)
DisableMenuItem(205,1)
DisableMenuItem(206,1)
Else
; --> otherwise, enable all menu items
DisableMenuItem(201,0)
DisableMenuItem(202,0)
DisableMenuItem(203,0)
DisableMenuItem(205,0)
DisableMenuItem(206,0)
EndIf
DisplayPopupMenu(#EditorPopup, WindowID())
EndIf
EndIf
; ********************************************************
; <-- End display popup menu for EditorGadget
; ********************************************************
; ********************************************************
; --> Start handling menu events
; ********************************************************
Case #PB_EventMenu
Select EventMenuID()
; --> Main menu items 101 - 199
Case 101
; --> File > Open
openTheFile()
Case 102
; --> File > Save
Debug "Save disabled"
Case 103
; --> File > Save As
Debug "Save as disabled"
Case 104
; --> File > Quit
CloseWindow(#MainWin)
Case 111
; --> Edit > Undo
SendMessage_(GadgetID(#Editor), #WM_UNDO, 0, 0)
Case 112
; --> Edit > Cut
SendMessage_(GadgetID(#Editor), #WM_CUT, 0, 0)
Case 113
; --> Edit > Copy
SendMessage_(GadgetID(#Editor), #WM_COPY, 0, 0)
SendMessage_(GadgetID(#Editor), #EM_SETSEL, -1, 0)
ActivateGadget(#Editor)
Case 114
; --> Edit > Paste
; >>>>>> Still need to check for proper format do disable paste command as necessary <<<<<<
SendMessage_(GadgetID(#Editor), #WM_PASTE, 0, 0)
Case 115
; --> Edit > Select All
editSel\cpMin = 0
editSel\cpMax = -1
SendMessage_(GadgetID(#Editor), #EM_EXSETSEL, 0, @editSel)
Case 121
; --> Options > Editor > Font
If fontSelector = #True
FontRequester(SelectedFontName(), SelectedFontSize(), #PB_FontRequester_Effects)
Else
If FontRequester("Arial", 11, #PB_FontRequester_Effects) > 0
fontSelector = #True
EndIf
EndIf
fontName$ = SelectedFontName()
egFormat\crTextColor = SelectedFontColor()
If SelectedFontSize() > 14
MessageRequester("Attention", "Defaulting to max font size of 14", #MB_ICONINFORMATION)
egFormat\yHeight = 14*20
EndIf
PokeS(@egFormat\szFaceName, fontName$)
egFormat\dwMask = #CFM_SIZE | #CFM_COLOR | #CFM_FACE
SendMessage_(GadgetID(#Editor), #EM_SETCHARFORMAT, #SCF_ALL, @egFormat)
egFormat\dwMask = #CFM_SIZE | #CFM_FACE
SendMessage_(GadgetID(#LineNumbers), #EM_SETCHARFORMAT, #SCF_ALL, @egFormat)
Case 122
; --> Options > Editor > Background Color
egBackColor = ColorRequester()
If egBackColor > -1
SendMessage_(GadgetID(#Editor), #EM_SETBKGNDCOLOR, 0, egBackColor)
EndIf
Case 123
; --> Options > Numbers > Font Color
lnTextColor = ColorRequester()
egFormat\crTextColor = lnTextColor
If lnTextColor > -1
egFormat\dwMask = #CFM_COLOR
SendMessage_(GadgetID(#LineNumbers), #EM_SETCHARFORMAT, #SCF_ALL, @egFormat)
EndIf
Case 124
; --> Options > Numbers > Background Color
egBackColor = ColorRequester()
If egBackColor > -1
SendMessage_(GadgetID(#LineNumbers), #EM_SETBKGNDCOLOR, 0, egBackColor)
EndIf
; --> Popup menu items 201 - 299
Case 201
; --> Undo
SendMessage_(GadgetID(#Editor), #WM_UNDO, 0, 0)
Case 202
; --> Cut
SendMessage_(GadgetID(#Editor), #WM_CUT, 0, 0)
Case 203
; --> Copy
SendMessage_(GadgetID(#Editor), #WM_COPY, 0, 0)
SendMessage_(GadgetID(#Editor), #EM_SETSEL, -1, 0);
ActivateGadget(#Editor)
Case 204
; --> Paste
; >>>>>> Still need to check for proper format do disable paste command as necessary <<<<<<
SendMessage_(GadgetID(#Editor), #WM_PASTE, 0, 0)
Case 205
; --> Select All
editSel\cpMin = 0
editSel\cpMax = -1
SendMessage_(GadgetID(#Editor), #EM_EXSETSEL, 0, @editSel)
EndSelect
; ********************************************************
; <-- End handling menu events
; ********************************************************
EndSelect
Until event = #PB_Event_CloseWindow
EndIf
; ********************************************************
; <-- End Main loop
; ********************************************************
End



