Best way to add a gutter, with line numbers?

Working on new editor enhancements?
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by NIN.

I reinvented the PB editor pretty successfully, for use with Blitz3D. I'd like to add a gutter on the left, showing line numbers. I can think of a few ways it might work, but what would be best?

Thanks. If you want to use this for PB, the source is included:
http://www.leadwerks.com/storage/ide.zip
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by NIN.

Also, is there a windows image for forward and back buttons? I found #STD_REDOW in the editor source, and am guessing there must be an #STD_BACK or something. Where do I find these constants, by the way?

Thank you.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by fred.

You can add line number but using textgadgets and update them when the scrollbar is used.. Should be easy and fast enough.

Fred - AlphaSND
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by NIN.

I just used DrawText to fill in some line numbers. I have a couple more questions.

How do I get the scrolled position of the RTF gadget, so I can "scroll" the line numbers?

Is there any way to enclose the drawing viewport so that numbers don't go down into the status bar? I could use an image hack, but an enclosed drawing viewport would be better.

Thanks for the help.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by El_Choni.

Code: Select all

FirstVisibleLine = SendMessage_(RichEditID, #EM_GETFIRSTVISIBLELINE, 0, 0)
BTW, I wonder if you can draw your numbers directly in the left margin of the RTF Gadget by using StartDrawing(GetDC_(RichEditID))?

Bye,

El_Choni
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by NIN.

El_Choni, that's useful, but it only tells me the nearest line. I still have no way of telling if the top line is half-off the screen, so my line numbers don't line up exactly.

Also...where should I put the gutter-drawing stuff? I have it right after the wait window event, and it flickers a lot. How do I tell when the richedit gadget has been scrolled?

Thanks a lot.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by PB.

> I reinvented the PB editor pretty successfully, for use with Blitz3D.

:cry: What can I say...
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by NIN.

If you like anything I added, there is no reason you can't use it with PB.

Now, back to my questions!
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by fred.
Originally posted by NIN
Now, back to my questions!
Be more gentle please. This topic is primaly to enhance the PureBasic editor, not to help to build a forked one (for another language...).

You can use a Clip Region API call to limit the drawing to the current DC (returned by StartDrawing()).

Fred - AlphaSND
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by NIN.

Thanks. Is it possible to see how much the RTF gadget is scrolled, beyond just what the first visible line is?

Anyone interested in improving the PB IDE should definitely check this out when I finish. I am near-done, except for about two things, and all these features would work just as well with any language.

I modelled the added features after the DBPro editor and DarkEDIT. If you doucle-click an include file in the code explorer, it gets opened. The left-most file is always the one that gets run. Code "libraries" are automatically included at compile time.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by El_Choni.

I've been looking around for help in using line numbers, and downloaded an example from the win32asm message board, here:

http://board.win32asmcommunity.net/atta ... stid=35978

I've translated it to PB (only the important parts), but, as in the original example, I'm not able to make the line numbers height equal to the RTF lines height. Anyone can help?:

Code: Select all

#RICHEDIT = #WS_CHILD|#WS_VISIBLE|#WS_VSCROLL|#ES_MULTILINE|#ES_AUTOVSCROLL|#ES_NOHIDESEL
#WINDOW_PARAMETERS = #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget
Global RichEditID, hWindow, WindowWidth, WindowHeight
Global hLnFont, rc.RECT, FontHeight, buffer.s, OldRedProc
Procedure Error(message.s, fatal.b)
  FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError_(), 0, AllocateMemory(0, 256, 0), 256, 0)
  MessageRequester("Error", message+Chr(10)+Chr(10)+PeekS(MemoryID()), 0)
  FreeMemory(0)
  If fatal
    End
  EndIf
EndProcedure
Procedure DrawLineNumbers()
  hDC = GetDC_(RichEditID)
  OldObject = SelectObject_(hDC, hLnFont)
  lineno = SendMessage_(RichEditID, #EM_GETFIRSTVISIBLELINE, 0, 0)+1
  GetClientRect_(RichEditID, rc)
  rc\right = 28
  FillRect_(hDC, rc, GetStockObject_(#GRAY_BRUSH))
  SetBkMode_(hDC, #TRANSPARENT)
  SetTextColor_(hDC, $0FFFF)
  lastline = WindowHeight/FontHeight+lineno
  While lineno#SIZE_MINIMIZED
        WindowWidth = lParam&$ffff
        WindowHeight = lParam>>16
        MoveWindow_(RichEditID, 0, 0, WindowWidth, WindowHeight, 1)
      EndIf
  EndSelect
  ProcedureReturn result
EndProcedure
hWindow = OpenWindow(0, 0, 0, 640, 480, #WINDOW_PARAMETERS, "RichEdit line numbers example")
If hWindow
  SetClassLong_(hWindow, #GCL_HBRBACKGROUND, 0) ; remove resize flicker
  If LoadLibrary_("RICHED20.DLL")
    RichClass.s = "RichEdit20A"
  ElseIf LoadLibrary_("RICHED32.DLL")
    RichClass.s = "RichEdit"
  Else
    Error("RichEdit library not present.", 0)
    End
  EndIf
  WindowWidth = WindowWidth()
  WindowHeight = WindowHeight()
  RichEditID = CreateWindowEx_(#WS_EX_CLIENTEDGE, RichClass, 0, #RICHEDIT, 0, 0, WindowWidth, WindowHeight, hWindow, 0, GetModuleHandle_(0), 0)
  If RichEditID
    SendMessage_(RichEditID, #EM_GETRECT, 0, rc)
    rc\left+32
    SendMessage_(RichEditID, #EM_SETRECT, 0, rc)
    lfnt.LOGFONT
    cf.CHARFORMAT
    FontName.s = "Courier New"
    lstrcpy_(@lfnt\lfFaceName[0], @FontName)
    lstrcpy_(@cf\szFaceName[0], @FontName)
    lfnt\lfHeight = -12
    lfnt\lfWeight = 400
    hLnFont = CreateFontIndirect_(lfnt)
    hFont = CreateFontIndirect_(lfnt)
    cf\cbSize = SizeOf(CHARFORMAT)
    cf\dwMask = #CFM_FACE|#CFM_SIZE
    cf\yHeight=(-lfnt\lfHeight)*15
    SendMessage_(RichEditID, #EM_SETCHARFORMAT, #SCF_SELECTION, cf)
    hDC = GetDC_(RichEditID)
    OldObject = SelectObject_(hDC, hFont)
    GetTextExtentPoint32_(hDC, @"WWWW", 4, siz.SIZE)
    FontHeight = siz\cy
    SelectObject_(hDC, OldObject)
    ReleaseDC_(RichEditID, hDC)
    OldRedProc = SetWindowLong_(RichEditID, #GWL_WNDPROC, @RedProc())
    SetWindowCallback(@WndProc())
    Repeat
      EventID = WaitWindowEvent()
    Until EventID = #PB_EventCloseWindow
  Else
    Error("Could not create the RichEdit control.", 0)
    End
  EndIf
Else 
  Error("Could not create the main window.", 0)
EndIf
End
Bye,

El_Choni
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Jose.

Guys, not sure if this will help, but onther idea could be to use another RTF box with just line numbers in it, this would align the two.

Keep trying.


Registered PureBasic User
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by vanleth.

Not sure if this is related, but in the API-Guide 3.7 fetched on the PB-resource site, there is a Linenumber example for a RichEdit Control under the SendMessage() command.

This is Visual Basic code

Code: Select all

'Adding line numbers to the front of text in a rich text box 
'Example by HeSaidJoe
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long 
Private Declare Function SendMessageStr Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As String) As Long 
Private Const EM_GETLINE = &HC4 
Private Const EM_GETLINECOUNT = &HBA 
Private Const EM_LINEINDEX = &HBB 
Private Const EM_LINELENGTH = &HC1 
Private Sub Command1_Click() 
    Dim lngCount As Long 
    Dim lngLineIndex As Long 
    Dim lngLength As Long 
    Dim strBuffer As String 
    Dim strRichText As String 
    Dim i As Integer 
    'Get Line count 
    lngCount = SendMessage(RichTextBox1.hwnd, EM_GETLINECOUNT, 0, 0) 
    With RichTextBox1 
        For i = 0 To lngCount - 1 
            'Get line index 
            lngLineIndex = SendMessage(.hwnd, EM_LINEINDEX, i, 0) 
            'get line length 
            lngLength = SendMessage(.hwnd, EM_LINELENGTH, lngLineIndex, 0) 
            'resize buffer 
            strBuffer = Space(lngLength) 
            'get line text 
            Call SendMessageStr(.hwnd, EM_GETLINE, i, ByVal strBuffer) 
            'Number each line 
            strRichText = strRichText & CStr(i + 1) & " " & strBuffer & vbCrLf 
        Next 
        'rewrite numbered text in RichTextBox 
        .Text = strRichText 
    End With 
End Sub
Private Sub Form_Load() 
    With RichTextBox1 
        .Text = "line one" & vbCrLf 
        .Text = .Text & "line two" & vbCrLf 
        .Text = .Text & "line three" 
    End With 
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by NIN.

I think the best bet would be to add line numbers in the RTF box, with maybe a gray or other colored background. That way you don't have to worry about keeping things lined up.

Shouldn't be that hard, just make a function to convert each line of code to a lined string, then back again.
Post Reply