Scintilla using SublimeText-like code-scroller (not Unicode)

Share your advanced PureBasic knowledge/code with the community.
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Scintilla using SublimeText-like code-scroller (not Unicode)

Post by fsw »

EDIT: Developed on Linux, other operating systems not fully tested. Not Unicode friendly.

After seing Eddy's scintilla code and the resemblance with SublimeText I wanted to implement SublimeText's MiniMap (code scroller instead of a vertical scrollbar).
Not beeing a 2D coder myself I knew I need help and after some search found Stargate's canvas scrollbar code.

The code below seems to work (based on Eddy's and Stargate's code) but I believe there are some conceptual mistakes based on my inability to wrap my head around it.
There are some strange effects that maybe someone else has a solution for. (like when the window is maximized, etc.)
Also didn't find a working solution on changing the width of the code-scroller while changing the size of the main window.
(scintilla gadget width and code-scroller gadget width depend on each other - my code always had strange artifacts)
In any case, the code below definately shows how not to do it.

Anyway, have fun coding.

Code: Select all

;
; Proof of concept:
; Scintilla with code-scroller
; like Sublime Text (MiniMap)
;
; Scintilla documentation:
; http://www.scintilla.org/ScintillaDoc.html
;
EnableExplicit

Enumeration
   #Window
   #Gadget
   #Font
   #SciMain
EndEnumeration

#SideViewWidth = 120

#MENU_EXTEND_SELECTION = 10

Global EnableScroll.i, maxPositionsOnMap.i
Global totalEditorLinesOfCode.i, firstVisibleEditorLine.i, visibleEditorLines.i
Global scrollerPosition.i, scrollerTextFrontColor.i, scrollerTextBackColor.i, scrollerBarActiveColor.i, scrollerBarDeactiveColor.i

Global NewList Item.s()
Global txt$, txtLen

; load the font
LoadFont(#Font, "Monospace", 2)

; load the test text
Declare.s LoadText()
txt$ = LoadText()

;-start
txtLen=StringByteLength(txt$, #PB_UTF8)
;- default settings
scrollerTextFrontColor   = RGB (195, 213, 255)
scrollerTextBackColor    = RGB ( 70,  78,  85)
scrollerBarActiveColor   = RGBA(100, 252, 195, 50)
scrollerBarDeactiveColor = RGBA(200, 200, 200, 50)

Procedure MakeUTF8Text(text.s)
  Static buffer.s
  
   buffer = Space(StringByteLength(text, #PB_UTF8))
   PokeS(@buffer, text, -1, #PB_UTF8)
   
   ProcedureReturn @buffer
EndProcedure

Procedure CodeScrollerGadgetUpdate(Gadget)
  Protected scrollerFontHeight.i, Y.i, scrollerBarHeight.i
  Protected TextLength.i, Text$, Index.i
  
    
    ;- get needed editor data
    
    ; This returns the number of lines in the document.
    ; An empty document contains 1 line.
    ; A document holding only an end of line sequence has 2 lines.
    totalEditorLinesOfCode = ScintillaSendMessage(#SciMain, #SCI_GETLINECOUNT, 0)
    Debug "totalEditorLinesOfCode: " + totalEditorLinesOfCode
    
    ; there's a strange (but logical) thing:
    ; when pulling down the bar the scroller background moves up
    ; this means the scroller "step" is never one line but two
    firstVisibleEditorLine = ScintillaSendMessage(#SciMain, #SCI_GETFIRSTVISIBLELINE, 0) / 2; + (scrollerPosition / 10)
    Debug "firstVisibleEditorLine: " + firstVisibleEditorLine
    
    visibleEditorLines = ScintillaSendMessage(#SciMain, #SCI_LINESONSCREEN, 0)
    Debug "visible Editor Lines: " + visibleEditorLines
    
    Debug "scrollerPosition: " + scrollerPosition
    
    ; Fetch the text from the editor
    TextLength = ScintillaSendMessage(#SciMain, #SCI_GETTEXTLENGTH, 0, 0)
    Text$ = Space(TextLength)
    ScintillaSendMessage(#SciMain, #SCI_GETTEXT, TextLength, @Text$)     
    
    ; copy the editor text into the linked list
    ClearList(Item()) 
    
    If totalEditorLinesOfCode = 1
      ; make sure there is at least one list element
      AddElement(Item())
      Item() = ""
    Else
      ; copy line by line the text from the editor into the linked list for the code scroller
      Repeat
        Index + 1
        AddElement(Item())
        Item() = StringField(Text$, Index, Chr(13))
        ;Debug "Line " + Str(Index) + ": " + Item()
      Until Index = totalEditorLinesOfCode
    EndIf
    
  ;- now that the list is filled lets draw
  If StartDrawing(CanvasOutput(Gadget))
    ; prepare scrollbar window
    DrawingMode(#PB_2DDrawing_Default)
    Box(0, 0, OutputWidth(), OutputHeight(), RGB(70, 78, 85))
    DrawingFont(FontID(#Font))    
    scrollerFontHeight = TextHeight("#")
    
    If SelectElement(Item(), firstVisibleEditorLine)
      Repeat
        
        DrawText(0, Y, Item(), scrollerTextFrontColor, scrollerTextBackColor)
        
        Y + (scrollerFontHeight )
      Until NextElement(Item()) = #False Or Y > (OutputHeight() - scrollerBarHeight)
    EndIf
    Debug "Y: " + Y
    
    ; Scrollbar
      
    DrawingMode(#PB_2DDrawing_AlphaBlend);#PB_2DDrawing_XOr)
    
    ; set bar height (seems to be correct)
    scrollerBarHeight = visibleEditorLines * scrollerFontHeight
      
    ; Y is for the visible lines scroller
    If OutputHeight() < (totalEditorLinesOfCode * scrollerFontHeight)
      Y = (OutputHeight() + scrollerBarHeight) * ((scrollerPosition) * scrollerFontHeight) / ((totalEditorLinesOfCode) * scrollerFontHeight)
    Else
      Y = ((totalEditorLinesOfCode * scrollerFontHeight) + scrollerBarHeight) * ((scrollerPosition) * scrollerFontHeight) / (OutputHeight()) ; * scrollerFontHeight)
    EndIf
    
    If GetGadgetAttribute(Gadget, #PB_Canvas_MouseX) >= 0
        EnableScroll = #True
           
        ;scrollbar color mouse cursor over
        Box(0, Y, OutputWidth(), scrollerBarHeight, scrollerBarActiveColor)
        
        If GetGadgetAttribute(Gadget, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
          scrollerPosition = (ListSize(Item())) * (GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)- scrollerBarHeight / 2) / (OutputHeight() + scrollerBarHeight)
          
          If scrollerPosition < 0 
            scrollerPosition = 0 
          ElseIf scrollerPosition > totalEditorLinesOfCode
            scrollerPosition = totalEditorLinesOfCode
          EndIf
          
          ; minus (scrollerPosition / 10) is for compensation 
          ; don't like these king of "magic" numbers
          ScintillaSendMessage(#SciMain, #SCI_SETFIRSTVISIBLELINE, scrollerPosition * 2 - (scrollerPosition / 10), 0)
        Else
          scrollerPosition = firstVisibleEditorLine
        EndIf
        
      Else
        EnableScroll = #False
        Debug "scrollbar color when the cursor is not over the gadget"
        ;scrollbar color cursor not over
        Box(0, Y, OutputWidth(), scrollerBarHeight, scrollerBarDeactiveColor)
           
      EndIf
       Debug "Y: " + Y
    StopDrawing()
  EndIf
  
EndProcedure

Procedure CodeScrollerGadgetEvent(Gadget)
  Shared scrollerPosition ;needs to be global because it's calculated somewhere else...
  
   Select EventType()
      Case #PB_EventType_MouseWheel
        scrollerPosition - 3 * GetGadgetAttribute(Gadget, #PB_Canvas_WheelDelta)
        
         If scrollerPosition < 0 
           scrollerPosition = 0 
         ElseIf scrollerPosition > totalEditorLinesOfCode 
           scrollerPosition = totalEditorLinesOfCode 
         EndIf
         
         CodeScrollerGadgetUpdate(Gadget)
      Case #PB_EventType_MouseMove, #PB_EventType_LeftButtonDown
         CodeScrollerGadgetUpdate(Gadget)
   EndSelect
EndProcedure

Procedure CodeScrollerGadget(gad, x, y, w, h, flags = 0)
  ProcedureReturn CanvasGadget(gad, x, y, w, h, flags)
EndProcedure


;-
;- SCINTILLA
Procedure ExtendScintillaSelection()
  Protected mainSel, selStart, selEnd
  
   mainSel  = ScintillaSendMessage(0, #SCI_GETMAINSELECTION)
   selStart = ScintillaSendMessage(0, #SCI_GETSELECTIONNSTART, mainSel)
   selEnd   = ScintillaSendMessage(0, #SCI_GETSELECTIONNEND,   mainSel)
   
EndProcedure

; Set Text Mode
Procedure SetTextMode(gad.i)
  ScintillaSendMessage(gad, #SCI_SETWRAPMODE, #SC_WRAP_NONE)
  ScintillaSendMessage(gad, #SCI_SETCODEPAGE, #SC_CP_UTF8)
  ScintillaSendMessage(gad, #SCI_SETVIRTUALSPACEOPTIONS, #SCVS_RECTANGULARSELECTION | #SCVS_USERACCESSIBLE) ; allow cursor and rect selection to move beyond end of line
EndProcedure

; Set Current Line Highlighting
Procedure SetCurrentLineHighlighting(gad.i)
  ScintillaSendMessage(gad, #SCI_SETCARETLINEVISIBLE, 1)
  ScintillaSendMessage(gad, #SCI_SETCARETLINEVISIBLEALWAYS, 1)
  ScintillaSendMessage(gad, #SCI_SETCARETLINEBACKALPHA, 50)
  ScintillaSendMessage(gad, #SCI_SETCARETLINEBACK, RGB(100, 252, 195))
EndProcedure

; Set Text style
Procedure SetTextStyle(gad.i, font.s, size.i)
  ScintillaSendMessage(gad, #SCI_STYLESETFONT, #STYLE_DEFAULT, MakeUTF8Text(font)) ; rectangle selection works better with mono-width font
  ScintillaSendMessage(gad, #SCI_STYLESETSIZE, #STYLE_DEFAULT, size)
  ScintillaSendMessage(gad, #SCI_STYLESETBACK, #STYLE_DEFAULT, RGB(70, 78, 85))
  ScintillaSendMessage(gad, #SCI_STYLESETFORE, #STYLE_DEFAULT, RGB(195, 213, 255))
  ScintillaSendMessage(gad, #SCI_STYLECLEARALL)
EndProcedure

; Set Margin size and style
Procedure SetMarginStyle(gad.i, font.s, width.s)
  Protected marginWidth
  ScintillaSendMessage(gad, #SCI_STYLESETFONT, #STYLE_LINENUMBER, MakeUTF8Text(font))
  ScintillaSendMessage(gad, #SCI_STYLESETBACK, #STYLE_LINENUMBER, RGB(53, 55, 57))
  ScintillaSendMessage(gad, #SCI_STYLESETFORE, #STYLE_LINENUMBER, RGB(200, 200, 200))
  marginWidth=ScintillaSendMessage(gad, #SCI_TEXTWIDTH, #STYLE_LINENUMBER, MakeUTF8Text(width))
  ScintillaSendMessage(gad, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)
  ScintillaSendMessage(gad, #SCI_SETMARGINWIDTHN, 0, marginWidth)
  marginWidth=0
  ScintillaSendMessage(gad, #SCI_SETMARGINMASKN, 2, #SC_MASK_FOLDERS)
  ScintillaSendMessage(gad, #SCI_SETMARGINWIDTHN, 2, marginWidth)
  ScintillaSendMessage(gad, #SCI_SETMARGINSENSITIVEN, 2, #True)
EndProcedure

; Set Main Caret and Selection
Procedure MainCaretSelection(gad.i)
  ScintillaSendMessage(gad, #SCI_SETCARETSTICKY, 1) ;make always visible
  ScintillaSendMessage(gad, #SCI_SETCARETWIDTH, 3)  ;make thicker
  ScintillaSendMessage(gad, #SCI_SETCARETFORE, RGB(255, 160, 136))
  ScintillaSendMessage(gad, #SCI_SETSELALPHA, 100)
  ScintillaSendMessage(gad, #SCI_SETSELBACK, 1, RGB(255, 160, 136))
  ScintillaSendMessage(gad, #SCI_SETSELFORE, 1, RGB(200, 200, 200))
EndProcedure

; Set Additional Caret and Selection
Procedure AddCaretSelection(gad.i)
  ScintillaSendMessage(gad, #SCI_SETADDITIONALCARETFORE, RGB(157, 64, 41))
  ScintillaSendMessage(gad, #SCI_SETADDITIONALCARETSBLINK, 1)
  ScintillaSendMessage(gad, #SCI_SETADDITIONALSELALPHA, 100)
  ScintillaSendMessage(gad, #SCI_SETADDITIONALSELBACK, RGB(255, 160, 136))
  ScintillaSendMessage(gad, #SCI_SETADDITIONALSELFORE, RGB(200, 200, 200))
EndProcedure

; Enable multi cursor editing
Procedure EnableMultiCursor(gad.i)
  ScintillaSendMessage(gad, #SCI_SETRECTANGULARSELECTIONMODIFIER, #SCMOD_ALT) ; select rectangle range by holding down the ALT key while dragging with the mouse
  ScintillaSendMessage(gad, #SCI_SETMULTIPLESELECTION, 1)                     ; select multiple ranges by holding down the CTRL or CMD key while dragging with the mouse
  ScintillaSendMessage(gad, #SCI_SETMULTIPASTE, #SC_MULTIPASTE_EACH)
  ScintillaSendMessage(gad, #SCI_SETADDITIONALSELECTIONTYPING, 1)
EndProcedure

; Enable hotkey for selection auto extension CTRL + D
Procedure HotKeyCTRL_D()
  AddKeyboardShortcut(#Window, #PB_Shortcut_Control | #PB_Shortcut_D, #MENU_EXTEND_SELECTION)
  BindEvent(#PB_Event_Menu, ExtendScintillaSelection())
EndProcedure

; Change text
Procedure ChangeText(gad.i, txt.s, txtLength.i)
  
  ScintillaSendMessage(gad, #SCI_SETTEXT, 0, MakeUTF8Text(txt))
  ScintillaSendMessage(gad, #SCI_GOTOPOS, txtLength)
  SetActiveGadget(gad)
  
  Debug "#SCI_LINESONSCREEN: " + ScintillaSendMessage(gad, #SCI_LINESONSCREEN, 0)
EndProcedure

;-
Procedure MainWindowResize()
  Protected mainWidth  = WindowWidth(#Window)
  Protected mainHeight = WindowHeight(#Window)
  Protected sideWidth  = GadgetWidth(#Gadget)
  
  ResizeGadget(#SciMain, 0, 0, mainWidth - sideWidth, mainHeight)
  ResizeGadget(#Gadget, mainWidth - sideWidth, 0, sideWidth, mainHeight)
  
  CodeScrollerGadgetUpdate(#Gadget)
EndProcedure
;-
;- MAIN
InitScintilla()

OpenWindow(#Window, 0, 0, 600, 305, "WindowTitle", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget)

ScintillaGadget(#SciMain, 0, 0, WindowWidth(#Window) - #SideViewWidth, WindowHeight(#Window), 0);@ScintillaCallBack())

CodeScrollerGadget(#Gadget, WindowWidth(#Window) - #SideViewWidth, 0, #SideViewWidth, WindowHeight(#Window), #PB_Canvas_Border | #PB_Canvas_Keyboard)

SetTextMode(#SciMain)
SetCurrentLineHighlighting(#SciMain)
SetTextStyle(#SciMain, "Courier New", 8)
SetMarginStyle(#SciMain, "Arial", "_999")
MainCaretSelection(#SciMain)
AddCaretSelection(#SciMain)
EnableMultiCursor(#SciMain)
HotKeyCTRL_D()
ChangeText(#SciMain, txt$, txtLen)
ScintillaSendMessage(#SciMain, #SCI_GOTOPOS, 0)
; the code scroll Bar is used instead
ScintillaSendMessage(#SciMain, #SCI_SETVSCROLLBAR, 0)
;ScintillaSendMessage(#SciMain, #SCI_SETFIRSTVISIBLELINE, 0, 0)

BindEvent(#PB_Event_SizeWindow, @MainWindowResize(), #Window)

SmartWindowRefresh(#Window, #True)

CodeScrollerGadgetUpdate(#Gadget)
 
Repeat
   
   Select WaitWindowEvent()
         
      Case #PB_Event_CloseWindow
         End
         
      Case #PB_Event_Gadget
         Select EventGadget()
           Case #SciMain
             CodeScrollerGadgetUpdate(#Gadget)
           Case #Gadget
             CodeScrollerGadgetUpdate(#Gadget)
           Default
             CodeScrollerGadgetUpdate(#Gadget)
         EndSelect
         
   EndSelect
   
 ForEver
 
 End
 
 Procedure.s LoadText()
   ProcedureReturn " 1 Scintilla is a free source code editing component."+#CR$+
        " 2 "+#CR$+
        " 3 It comes with complete source code and a license that permits use in any project or product personal or commercial."+#CR$+
        " 4 The license may be viewed here. "+#CR$+
        " 5  "+#CR$+
        " 6 The source code, as well as the library documentation may be found on the Scintilla Homepage."+#CR$+
        " 7 From the Scintilla Homepage : "+#CR$+
        " 8 As well as features found in standard text editing components, Scintilla includes features especially useful when editing and debugging source code."+#CR$+
        " 9 "+#CR$+
        "10 These include support for syntax styling, error indicators, code completion and call tips."+#CR$+
        "11 The selection margin can contain markers like those used in debuggers to indicate breakpoints and the current line."+#CR$+
        "12 "+#CR$+
        "13 Styling choices are more open than with many editors, allowing the use of proportional fonts, bold and italics, multiple foreground and background colors and multiple fonts."+#CR$+
        "14 "+#CR$+
        "15 "+#CR$+
        "16 "+#CR$+
        "17 "+#CR$+
        "18 "+#CR$+
        "19 "+#CR$+
        "20 +++++++++++++++++++++++++++++++++++++++++++++++++++"+#CR$+
        "21 "+#CR$+
        "22 "+#CR$+
        "23 "+#CR$+
        "24 "+#CR$+
        "25 "+#CR$+
        "26 "+#CR$+
        "27 "+#CR$+
        "28 "+#CR$+
        "29 "+#CR$+
        "30 +++++++++++++++++++++++++++++++++++++++++++++++++++"+#CR$+
        "31 "+#CR$+
        "32 "+#CR$+
        "33 "+#CR$+
        "34 "+#CR$+
        "35 "+#CR$+
        "36 "+#CR$+
        "37 "+#CR$+
        "38 "+#CR$+
        "39 "+#CR$+
        "40 +++++++++++++++++++++++++++++++++++++++++++++++++++"+#CR$+
        "41 "+#CR$+
        "42 "+#CR$+
        "43"+#CR$+
        "44 "+#CR$+
        "45 "+#CR$+
        "46 "+#CR$+
        "47 "+#CR$+
        "48 "+#CR$+
        "49 "+#CR$+
        "50 +++++++++++++++++++++++++++++++++++++++++++++++++++"+#CR$+
        "51 "+#CR$+
        "52 "+#CR$+
        "53"+#CR$+
        "54 "+#CR$+
        "55 "+#CR$+
        "56 "+#CR$+
        "57 "+#CR$+
        "58 "+#CR$+
        "59 "+#CR$+
        "60 +++++++++++++++++++++++++++++++++++++++++++++++++++"+#CR$+
        "61 "+#CR$+
        "62 "+#CR$+
        "63"+#CR$+
        "64 "+#CR$+
        "65 "+#CR$+
        "66 "+#CR$+
        "67 "+#CR$+
        "68 "+#CR$+
        "69 "+#CR$+
        "70 +++++++++++++++++++++++++++++++++++++++++++++++++++"+#CR$+
        "71 "+#CR$+
        "72 "+#CR$+
        "73"+#CR$+
        "74 "+#CR$+
        "75 "+#CR$+
        "76 "+#CR$+
        "77 "+#CR$+
        "78 "+#CR$+
        "79 "+#CR$+
        "80 +++++++++++++++++++++++++++++++++++++++++++++++++++"+#CR$+
        "81 "+#CR$+
        "82 "+#CR$+
        "83"+#CR$+
        "84 "+#CR$+
        "85 "+#CR$+
        "86 "+#CR$+
        "87 "+#CR$+
        "88 "+#CR$+
        "89 "+#CR$+
        "90 +++++++++++++++++++++++++++++++++++++++++++++++++++"+#CR$+
        "91 "+#CR$+
        "92 "+#CR$+
        "93"+#CR$+
        "94 "+#CR$+
        "95 "+#CR$+
        "96 "+#CR$+
        "97 "+#CR$+
        "98 "+#CR$+
        "99 "+#CR$+
        "100 +++++++++++++++++++++++++++++++++++++++++++++++++++"+#CR$+
        " "+#CR$
 EndProcedure
 
Last edited by fsw on Mon Nov 17, 2014 9:06 pm, edited 5 times in total.

I am to provide the public with beneficial shocks.
Alfred Hitshock
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Scintilla using SublimeText-like code-scroller

Post by davido »

@fsw
Looks good.
Thank you for providing another Scintilla demo. :D
DE AA EB
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Scintilla using SublimeText-like code-scroller

Post by fsw »

Thanks Davido.

BTW: The code was developed on Linux.

ALSO: Switch Unicode off in the compiler settings if the text in the scroller is not properly aligned.

Please feel free to test the code on other platforms.

I am to provide the public with beneficial shocks.
Alfred Hitshock
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: Scintilla using SublimeText-like code-scroller (not Unic

Post by eddy »

A clone document view could do the job.

a minimap scintilla needs :
  • clone syntax highlighter
  • clone selection
  • clone current line
  • custom highlighter for visible screen lines
  • minimap auto size
  • minimap caching system could improve loading performance
Image

Code: Select all

EnableExplicit
InitScintilla()

#MENU_EXTEND_SELECTION=10
Define i, txt$, marginWidth, lastLineEndPos, DialogXml$

Procedure MakeUTF8Text(text.s)
   Static buffer.s
   buffer=Space(StringByteLength(text, #PB_UTF8))
   PokeS(@buffer, text, -1, #PB_UTF8)
   ProcedureReturn @buffer
EndProcedure

Procedure ExtendScintillaSelection()
   Protected mainSel, selStart, selEnd
   mainSel=ScintillaSendMessage(0, #SCI_GETMAINSELECTION)
   selStart=ScintillaSendMessage(0, #SCI_GETSELECTIONNSTART, mainSel)
   selEnd=ScintillaSendMessage(0, #SCI_GETSELECTIONNEND, mainSel)
   
EndProcedure

txt$="Scintilla is a free source code editing component. It comes with " + 
     #LF$ + "complete source code and a license that permits use in any project " + 
     #LF$ + "or product personal or commercial. The license may be viewed here. " + 
     #LF$ + "The source code, as well as the library documentation may be found " + 
     #LF$ + "on the Scintilla Homepage. " + 
     #LF$ + 
     #LF$ + "From the Scintilla Homepage : As well As " + 
     #LF$ + "features found in standard text editing components, Scintilla includes " + 
     #LF$ + "features especially useful when editing And debugging source code." + 
     #LF$ + 
     #LF$ + 
     #LF$ + "These include support For syntax styling, error indicators, code " + 
     #LF$ + "completion And call tips.The selection margin can contain markers " + 
     #LF$ + "like those used in debuggers To indicate breakpoints and the current " + 
     #LF$ + "line.Styling choices are more open than With many editors, allowing the" + 
     #LF$ + " use of proportional fonts, bold And italics, multiple foreground " + 
     #LF$ + "and background colors And multiple fonts."
For i=0 To 1000
   txt$ + #LF$ + #LF$ + #LF$ + #LF$ + "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
Next

Runtime Procedure test()
   Debug "test"
EndProcedure

DialogXml$="<window id='100' " + 
           "   name='SublimeDialog' " + 
           "   text='Editing with Multi cursor (like eclipse or sublimetext)' " + 
           "   margin='0' minwidth='600' minheight='300' " + 
           "   flags='#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget' >" + 
           "   <hbox expand='item:1' spacing='0'>" + 
           "      <scintilla id='0' />" + 
           "      <scintilla id='1' width='100' />" + 
           "   </hbox>" + 
           "</window>"
Enumeration
   #Dialog
   #Xml
EndEnumeration
If CatchXML(#Xml, @DialogXml$, StringByteLength(DialogXml$), 0, #PB_UTF8) And XMLStatus(#Xml)=#PB_XML_Success And CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "SublimeDialog")
   
   ; Set Text Mode
   ScintillaSendMessage(0, #SCI_SETWRAPMODE, #SC_WRAP_NONE)
   ScintillaSendMessage(0, #SCI_SETCODEPAGE, #SC_CP_UTF8)
   ScintillaSendMessage(0, #SCI_SETVIRTUALSPACEOPTIONS, #SCVS_RECTANGULARSELECTION | #SCVS_USERACCESSIBLE) ; allow cursor and rect selection to move beyond end of line
                                                                                                           ; Set Current Line Highlighting
   ScintillaSendMessage(0, #SCI_SETCARETLINEVISIBLE, 1)
   ScintillaSendMessage(0, #SCI_SETCARETLINEVISIBLEALWAYS, 1)
   ScintillaSendMessage(0, #SCI_SETCARETLINEBACKALPHA, 50)
   ScintillaSendMessage(0, #SCI_SETCARETLINEBACK, RGB(100, 252, 195))
   ; Set Text style
   ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_DEFAULT, MakeUTF8Text("Courier New")) ; rectangle selection works better with mono-width font
   ScintillaSendMessage(0, #SCI_STYLESETBACK, #STYLE_DEFAULT, RGB(70, 78, 85))
   ScintillaSendMessage(0, #SCI_STYLESETFORE, #STYLE_DEFAULT, RGB(195, 213, 255))
   ScintillaSendMessage(0, #SCI_STYLECLEARALL)
   ; Set Margin size and style
   ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_LINENUMBER, MakeUTF8Text("Arial"))
   ScintillaSendMessage(0, #SCI_STYLESETBACK, #STYLE_LINENUMBER, RGB(53, 55, 57))
   ScintillaSendMessage(0, #SCI_STYLESETFORE, #STYLE_LINENUMBER, RGB(200, 200, 200))
   marginWidth=ScintillaSendMessage(0, #SCI_TEXTWIDTH, #STYLE_LINENUMBER, MakeUTF8Text("_9999"))
   ScintillaSendMessage(0, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)
   ScintillaSendMessage(0, #SCI_SETMARGINWIDTHN, 0, marginWidth)
   marginWidth=0
   ScintillaSendMessage(0, #SCI_SETMARGINMASKN, 2, #SC_MASK_FOLDERS)
   ScintillaSendMessage(0, #SCI_SETMARGINWIDTHN, 2, marginWidth)
   ScintillaSendMessage(0, #SCI_SETMARGINSENSITIVEN, 2, #True)
   ; Set Main Caret and Selection
   ScintillaSendMessage(0, #SCI_SETCARETSTICKY, 1) ;make always visible
   ScintillaSendMessage(0, #SCI_SETCARETWIDTH, 3)  ;make thicker
   ScintillaSendMessage(0, #SCI_SETCARETFORE, RGB(255, 160, 136))
   ScintillaSendMessage(0, #SCI_SETSELALPHA, 100)
   ScintillaSendMessage(0, #SCI_SETSELBACK, 1, RGB(255, 160, 136))
   ScintillaSendMessage(0, #SCI_SETSELFORE, 1, RGB(200, 200, 200))
   ; Set Additional Caret and Selection
   ScintillaSendMessage(0, #SCI_SETADDITIONALCARETFORE, RGB(157, 64, 41))
   ScintillaSendMessage(0, #SCI_SETADDITIONALCARETSBLINK, 1)
   ScintillaSendMessage(0, #SCI_SETADDITIONALSELALPHA, 100)
   ScintillaSendMessage(0, #SCI_SETADDITIONALSELBACK, RGB(255, 160, 136))
   ScintillaSendMessage(0, #SCI_SETADDITIONALSELFORE, RGB(200, 200, 200))
   ; Enable multi cursor editing
   ScintillaSendMessage(0, #SCI_SETRECTANGULARSELECTIONMODIFIER, #SCMOD_ALT) ; select rectangle range by holding down the ALT key while dragging with the mouse
   ScintillaSendMessage(0, #SCI_SETMULTIPLESELECTION, 1)                     ; select multiple ranges by holding down the CTRL or CMD key while dragging with the mouse
   ScintillaSendMessage(0, #SCI_SETMULTIPASTE, #SC_MULTIPASTE_EACH)
   ScintillaSendMessage(0, #SCI_SETADDITIONALSELECTIONTYPING, 1)
   ; Enable hotkey for selection auto extension CTRL + D
   AddKeyboardShortcut(100, #PB_Shortcut_Control | #PB_Shortcut_D, #MENU_EXTEND_SELECTION)
   BindEvent(#PB_Event_Menu, ExtendScintillaSelection())
   
   ; Change text, then jump to end of last line
   ScintillaSendMessage(0, #SCI_SETTEXT, 0, MakeUTF8Text(txt$))
   lastLineEndPos=ScintillaSendMessage(0, #SCI_GETLINEENDPOSITION, ScintillaSendMessage(0, #SCI_GETLINECOUNT)-1)
   ScintillaSendMessage(0, #SCI_GOTOPOS, lastLineEndPos)
   SetActiveGadget(0)
   
   ;minimap
   ScintillaSendMessage(1, #SCI_SETDOCPOINTER, 0, ScintillaSendMessage(0, #SCI_GETDOCPOINTER)) ; clone doc
   ScintillaSendMessage(1, #SCI_SETWRAPMODE, #SC_WRAP_NONE)
   ScintillaSendMessage(1, #SCI_SETCODEPAGE, #SC_CP_UTF8)
   ScintillaSendMessage(1, #SCI_SETCARETLINEVISIBLE, 1)
   ScintillaSendMessage(1, #SCI_SETCARETLINEVISIBLEALWAYS, 1)
   ScintillaSendMessage(1, #SCI_SETCARETLINEBACKALPHA, 50)
   ScintillaSendMessage(1, #SCI_SETCARETLINEBACK, RGB(100, 252, 195))
   ScintillaSendMessage(1, #SCI_SETMARGINWIDTHN, 0, 0)
   ScintillaSendMessage(1, #SCI_SETMARGINWIDTHN, 1, 0)
   ScintillaSendMessage(1, #SCI_SETMARGINWIDTHN, 2, 0)
   ScintillaSendMessage(1, #SCI_STYLESETFONT, #STYLE_DEFAULT, MakeUTF8Text("Courier New")) ; clone font 
   ScintillaSendMessage(1, #SCI_STYLESETSIZE, #STYLE_DEFAULT, 2)
   ScintillaSendMessage(1, #SCI_STYLESETBACK, #STYLE_DEFAULT, RGB(70, 78, 85))
   ScintillaSendMessage(1, #SCI_STYLESETFORE, #STYLE_DEFAULT, RGB(195, 213, 255))
   ScintillaSendMessage(1, #SCI_STYLECLEARALL)

   ; Tweak scrollbars and border display
   ScintillaSendMessage(0, #SCI_SETVSCROLLBAR, 0)
   ScintillaSendMessage(0, #SCI_SETHSCROLLBAR, 0)
   ScintillaSendMessage(1, #SCI_SETVSCROLLBAR, 0)
   ScintillaSendMessage(1, #SCI_SETHSCROLLBAR, 0)
   SetWindowLongPtr_(GadgetID(0), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(0), #GWL_EXSTYLE) & ~#WS_EX_CLIENTEDGE)
   SetWindowLongPtr_(GadgetID(1), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(1), #GWL_EXSTYLE) & ~#WS_EX_CLIENTEDGE)
   ResizeWindow(100, #PB_Ignore, #PB_Ignore, WindowWidth(100) + 1, WindowHeight(100) + 1) ;force refreshing

EndIf

Repeat: Until WaitWindowEvent()=#PB_Event_CloseWindow
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Scintilla using SublimeText-like code-scroller (not Unic

Post by fsw »

eddy wrote:A clone document view could do the job.
Nice one Eddy.
However, the MiniMap scintilla gadget needs to be read only.
As it is now I can edit it which should not be doable.
(as it is a scrollbar, not a place to edit code...)

IMHO, things like:
eddy wrote:
  • clone selection
  • clone current line
are not really needed.
Not sure what the functional benefit would be.

However, this:
eddy wrote:
  • minimap auto size
  • custom highlighter for visible screen lines
are needed.
The "custom highlighter for visible screen lines" needs to vertically drive the main scintilla gadget.

Things like:
eddy wrote:
  • clone syntax highlighter
  • minimap caching system could improve loading performance
are "nice to have" things...

I am to provide the public with beneficial shocks.
Alfred Hitshock
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Scintilla using SublimeText-like code-scroller (not Unic

Post by fsw »

Actually using the scintilla gadget as the code scroller (SublimeText MiniMap) doesn't seem to work right.
As soon as I add:

Code: Select all

  ScintillaSendMessage(1, #SCI_SETREADONLY, 1)
to make the scroller read-only, the editor scintilla gadget becomes read-only as well.
Don't know why, might be how the scintilla control is implemented into PureBasic or it's a basic fault of scintilla.
(Tested on Linux)

I am to provide the public with beneficial shocks.
Alfred Hitshock
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: Scintilla using SublimeText-like code-scroller (not Unic

Post by Tenaja »

I have done this for a thumbnail view, but have not tried to make it readonly. I believe the problem is this line:

Code: Select all

	ScintillaSendMessage(1, #SCI_SETDOCPOINTER, 0, ScintillaSendMessage(0, #SCI_GETDOCPOINTER)) ; clone doc
Because you are sharing the document, setting it readonly on one window sets it for both.

One solution is to set it read only when the thumbnail view gets focus, and disable read-only when the editable window gets focus. Obviously more maintenance, but it should work.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: Scintilla using SublimeText-like code-scroller (not Unic

Post by eddy »

I tested a solution for autosizing problem.
The minimap text edges match editor ones but the minimap width seems to be pretty big on my screen.

Code: Select all

EnableExplicit
InitScintilla()

#MENU_EXTEND_SELECTION=10
Define i, txt$, marginWidth, lastLineEndPos, DialogXml$

Procedure MakeUTF8Text(text.s)
   Static buffer.s
   buffer=Space(StringByteLength(text, #PB_UTF8))
   PokeS(@buffer, text, -1, #PB_UTF8)
   ProcedureReturn @buffer
EndProcedure

Procedure ExtendScintillaSelection()
   Protected mainSel, selStart, selEnd
   mainSel=ScintillaSendMessage(0, #SCI_GETMAINSELECTION)
   selStart=ScintillaSendMessage(0, #SCI_GETSELECTIONNSTART, mainSel)
   selEnd=ScintillaSendMessage(0, #SCI_GETSELECTIONNEND, mainSel)
   
EndProcedure

txt$="Scintilla is a free source code editing component. It comes with " + 
     #LF$ + "complete source code and a license that permits use in any project " + 
     #LF$ + "or product personal or commercial. The license may be viewed here. " + 
     #LF$ + "The source code, as well as the library documentation may be found " + 
     #LF$ + "on the Scintilla Homepage. " + 
     #LF$ + 
     #LF$ + "From the Scintilla Homepage : As well As " + 
     #LF$ + "features found in standard text editing components, Scintilla includes " + 
     #LF$ + "features especially useful when editing And debugging source code." + 
     #LF$ + 
     #LF$ + 
     #LF$ + "These include support For syntax styling, error indicators, code " + 
     #LF$ + "completion And call tips.The selection margin can contain markers " + 
     #LF$ + "like those used in debuggers To indicate breakpoints and the current " + 
     #LF$ + "line.Styling choices are more open than With many editors, allowing the" + 
     #LF$ + " use of proportional fonts, bold And italics, multiple foreground " + 
     #LF$ + "and background colors And multiple fonts."
For i=0 To 10
   txt$ + #LF$ + #LF$ + #LF$ + #LF$ + "++++++++++++++++++++++++++++++"
Next

Procedure ResizeMinimap()
   Protected marginTotalWidth=0, marginIndex
   For marginIndex=0 To #SC_MAX_MARGIN
      marginTotalWidth + ScintillaSendMessage(0, #SCI_GETMARGINWIDTHN, marginIndex)
   Next
   Debug marginTotalWidth
   Protected *longLineText=MakeUTF8Text(Space(300))
   Protected mini=ScintillaSendMessage(1, #SCI_TEXTWIDTH, #STYLE_DEFAULT, *longLineText)
   Protected big=ScintillaSendMessage(0, #SCI_TEXTWIDTH, #STYLE_DEFAULT, *longLineText) 
   Protected width=(GadgetWidth(111)-marginTotalWidth)*big / (big + mini)+marginTotalWidth
   ResizeGadget(0, 0, 0, width, GadgetHeight(111))
   ResizeGadget(1, width, 0, WindowWidth(100)-width, GadgetHeight(111))
EndProcedure

DialogXml$="<window id='100' " + 
           "   name='SublimeDialog' " + 
           "   text='Editing with Multi cursor (like eclipse or sublimetext)' " + 
           "   margin='0' minwidth='600' minheight='300' " + 
           "   flags='#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget' >" + 
           "   <container id='111'>" + 
           "   </container>" + 
           "</window>"
Enumeration
   #Dialog
   #Xml
EndEnumeration
If CatchXML(#Xml, @DialogXml$, StringByteLength(DialogXml$), 0, #PB_UTF8) And XMLStatus(#Xml)=#PB_XML_Success And CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "SublimeDialog")
   
   OpenGadgetList(111)
   ScintillaGadget(0, 0, 0, 0, 0, #Null)
   ScintillaGadget(1, 0, 0, 0, 0, #Null)
   CloseGadgetList()
   BindEvent(#PB_Event_SizeWindow, @ResizeMinimap(), 100)
   
   ; Set Text Mode
   ScintillaSendMessage(0, #SCI_SETWRAPMODE, #SC_WRAP_NONE)
   ScintillaSendMessage(0, #SCI_SETCODEPAGE, #SC_CP_UTF8)
   ScintillaSendMessage(0, #SCI_SETVIRTUALSPACEOPTIONS, #SCVS_RECTANGULARSELECTION | #SCVS_USERACCESSIBLE) ; allow cursor and rect selection to move beyond end of line
                                                                                                           ; Set Current Line Highlighting
   ScintillaSendMessage(0, #SCI_SETCARETLINEVISIBLE, 1)
   ScintillaSendMessage(0, #SCI_SETCARETLINEVISIBLEALWAYS, 1)
   ScintillaSendMessage(0, #SCI_SETCARETLINEBACKALPHA, 50)
   ScintillaSendMessage(0, #SCI_SETCARETLINEBACK, RGB(100, 252, 195))
   ; Set Text style
   ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_DEFAULT, MakeUTF8Text("Courier New")) ; rectangle selection works better with mono-width font
   ScintillaSendMessage(0, #SCI_STYLESETBACK, #STYLE_DEFAULT, RGB(70, 78, 85))
   ScintillaSendMessage(0, #SCI_STYLESETFORE, #STYLE_DEFAULT, RGB(195, 213, 255))
   ScintillaSendMessage(0, #SCI_STYLECLEARALL)
   ; Set Margin size and style
   ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_LINENUMBER, MakeUTF8Text("Arial"))
   ScintillaSendMessage(0, #SCI_STYLESETBACK, #STYLE_LINENUMBER, RGB(53, 55, 57))
   ScintillaSendMessage(0, #SCI_STYLESETFORE, #STYLE_LINENUMBER, RGB(200, 200, 200))
   marginWidth=ScintillaSendMessage(0, #SCI_TEXTWIDTH, #STYLE_LINENUMBER, MakeUTF8Text("_9999"))
   ScintillaSendMessage(0, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)
   ScintillaSendMessage(0, #SCI_SETMARGINWIDTHN, 0, marginWidth)
   marginWidth=0
   ScintillaSendMessage(0, #SCI_SETMARGINMASKN, 2, #SC_MASK_FOLDERS)
   ScintillaSendMessage(0, #SCI_SETMARGINWIDTHN, 2, marginWidth)
   ScintillaSendMessage(0, #SCI_SETMARGINSENSITIVEN, 2, #True)
   ; Set Main Caret and Selection
   ScintillaSendMessage(0, #SCI_SETCARETSTICKY, 1) ;make always visible
   ScintillaSendMessage(0, #SCI_SETCARETWIDTH, 3)  ;make thicker
   ScintillaSendMessage(0, #SCI_SETCARETFORE, RGB(255, 160, 136))
   ScintillaSendMessage(0, #SCI_SETSELALPHA, 100)
   ScintillaSendMessage(0, #SCI_SETSELBACK, 1, RGB(255, 160, 136))
   ScintillaSendMessage(0, #SCI_SETSELFORE, 1, RGB(200, 200, 200))
   ; Set Additional Caret and Selection
   ScintillaSendMessage(0, #SCI_SETADDITIONALCARETFORE, RGB(157, 64, 41))
   ScintillaSendMessage(0, #SCI_SETADDITIONALCARETSBLINK, 1)
   ScintillaSendMessage(0, #SCI_SETADDITIONALSELALPHA, 100)
   ScintillaSendMessage(0, #SCI_SETADDITIONALSELBACK, RGB(255, 160, 136))
   ScintillaSendMessage(0, #SCI_SETADDITIONALSELFORE, RGB(200, 200, 200))
   ; Enable multi cursor editing
   ScintillaSendMessage(0, #SCI_SETRECTANGULARSELECTIONMODIFIER, #SCMOD_ALT) ; select rectangle range by holding down the ALT key while dragging with the mouse
   ScintillaSendMessage(0, #SCI_SETMULTIPLESELECTION, 1)                     ; select multiple ranges by holding down the CTRL or CMD key while dragging with the mouse
   ScintillaSendMessage(0, #SCI_SETMULTIPASTE, #SC_MULTIPASTE_EACH)
   ScintillaSendMessage(0, #SCI_SETADDITIONALSELECTIONTYPING, 1)
   ; Enable hotkey for selection auto extension CTRL + D
   AddKeyboardShortcut(100, #PB_Shortcut_Control | #PB_Shortcut_D, #MENU_EXTEND_SELECTION)
   BindEvent(#PB_Event_Menu, ExtendScintillaSelection())
   
   ; Change text, then jump to end of last line
   ScintillaSendMessage(0, #SCI_SETTEXT, 0, MakeUTF8Text(txt$))
   lastLineEndPos=ScintillaSendMessage(0, #SCI_GETLINEENDPOSITION, ScintillaSendMessage(0, #SCI_GETLINECOUNT)-1)
   ScintillaSendMessage(0, #SCI_GOTOPOS, lastLineEndPos)
   SetActiveGadget(0)
   
   ;minimap
   ScintillaSendMessage(1, #SCI_SETDOCPOINTER, 0, ScintillaSendMessage(0, #SCI_GETDOCPOINTER)) ; clone doc
   ScintillaSendMessage(1, #SCI_SETWRAPMODE, #SC_WRAP_NONE)
   ScintillaSendMessage(1, #SCI_SETCODEPAGE, #SC_CP_UTF8)
   ScintillaSendMessage(1, #SCI_SETCARETLINEVISIBLE, 1)
   ScintillaSendMessage(1, #SCI_SETCARETLINEVISIBLEALWAYS, 1)
   ScintillaSendMessage(1, #SCI_SETCARETLINEBACKALPHA, 50)
   ScintillaSendMessage(1, #SCI_SETCARETLINEBACK, RGB(100, 252, 195))
   ScintillaSendMessage(1, #SCI_SETMARGINWIDTHN, 0, 0)
   ScintillaSendMessage(1, #SCI_SETMARGINWIDTHN, 1, 0)
   ScintillaSendMessage(1, #SCI_SETMARGINWIDTHN, 2, 0)
   ScintillaSendMessage(1, #SCI_STYLESETFONT, #STYLE_DEFAULT, MakeUTF8Text("Courier New")) ; clone font
   ScintillaSendMessage(1, #SCI_STYLESETSIZE, #STYLE_DEFAULT, 2)
   ScintillaSendMessage(1, #SCI_STYLESETBACK, #STYLE_DEFAULT, RGB(70, 78, 85))
   ScintillaSendMessage(1, #SCI_STYLESETFORE, #STYLE_DEFAULT, RGB(195, 213, 255))
   ScintillaSendMessage(1, #SCI_STYLECLEARALL)
   
   ; Tweak scrollbars and border display
   ScintillaSendMessage(0, #SCI_SETVSCROLLBAR, 0)
   ScintillaSendMessage(0, #SCI_SETHSCROLLBAR, 0)
   ScintillaSendMessage(1, #SCI_SETVSCROLLBAR, 0)
   ScintillaSendMessage(1, #SCI_SETHSCROLLBAR, 0)
   SetWindowLongPtr_(GadgetID(0), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(0), #GWL_EXSTYLE) & ~#WS_EX_CLIENTEDGE)
   SetWindowLongPtr_(GadgetID(1), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(1), #GWL_EXSTYLE) & ~#WS_EX_CLIENTEDGE)
   ResizeWindow(100, #PB_Ignore, #PB_Ignore, WindowWidth(100) + 1, WindowHeight(100) + 1) ;force refreshing
   
EndIf

Repeat: Until WaitWindowEvent()=#PB_Event_CloseWindow
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Scintilla using SublimeText-like code-scroller (not Unic

Post by fsw »

Tenaja wrote:I have done this for a thumbnail view, but have not tried to make it readonly. I believe the problem is this line:

Code: Select all

	ScintillaSendMessage(1, #SCI_SETDOCPOINTER, 0, ScintillaSendMessage(0, #SCI_GETDOCPOINTER)) ; clone doc
Because you are sharing the document, setting it readonly on one window sets it for both.

One solution is to set it read only when the thumbnail view gets focus, and disable read-only when the editable window gets focus. Obviously more maintenance, but it should work.
Yes, that's what I found out as well.
Readonly does refer to the document not the scintilla gadgets.

Here is the code to get the focus be included into the callbacks:
(works on Linux and Windows, didn't test it on OSX yet)

Code: Select all

  Static focus.i

  If *scinotify\nmhdr\code = #SCN_FOCUSIN
    Debug "> editor HAS FOCUS"
    focus = #True
  EndIf
  If *scinotify\nmhdr\code = #SCN_FOCUSOUT
    Debug "> editor LOST FOCUS"
    focus = #False
  EndIf
  
And it works quite well.

Later today I will post my "work in progress" what I've done so far.

I am to provide the public with beneficial shocks.
Alfred Hitshock
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Scintilla using SublimeText-like code-scroller (not Unic

Post by fsw »

eddy wrote:I tested a solution for autosizing problem.
The minimap text edges match editor ones but the minimap width seems to be pretty big on my screen.
Yes it becomes big, however IMHO it does not really pose a problem.
(at least for me YMMV) :D

Maybe this functionality can be made switchable; fixed size <-> dynamic size


Also, I was thinking about if it would be beneficial to use scintillas zoom function instead of a fixed size for the code-scroller.

So many options :P

I am to provide the public with beneficial shocks.
Alfred Hitshock
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: Scintilla using SublimeText-like code-scroller (not Unic

Post by Tenaja »

fsw wrote:Also, I was thinking about if it would be beneficial to use scintillas zoom function instead of a fixed size for the code-scroller.

So many options :P
That is what I do. If there is a click, get the line, and move the displayed line on the second sci gadget.
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Scintilla using SublimeText-like code-scroller (not Unic

Post by fsw »

Here is what I have so far.

Thought to incorporate the visible area into the vscroll gadget.
The only "scintilla" solution I could find was to use a selection as the display for the editor's visible area.

It's not perfect (still work in progress) but looks promising.
However the user cannot really click on the bar without sometimes starting the "drag&drop" function...

Like I said, a work in progress... :P

Code: Select all

EnableExplicit
InitScintilla()

#Window = 1
#MENU_EXTEND_SELECTION=10

Define i, txt$, marginWidth, lastLineEndPos, Event

Procedure MakeUTF8Text(text.s)
   Static buffer.s
   buffer=Space(StringByteLength(text, #PB_UTF8))
   PokeS(@buffer, text, -1, #PB_UTF8)
   ProcedureReturn @buffer
EndProcedure

Procedure ExtendScintillaSelection()
   Protected mainSel, selStart, selEnd
   mainSel=ScintillaSendMessage(0, #SCI_GETMAINSELECTION)
   selStart=ScintillaSendMessage(0, #SCI_GETSELECTIONNSTART, mainSel)
   selEnd=ScintillaSendMessage(0, #SCI_GETSELECTIONNEND, mainSel)
EndProcedure

;txt$="         " ; used for testing...

txt$="Scintilla is a free source code editing component. It comes with " +
     #LF$ + "complete source code and a license that permits use in any project " +
     #LF$ + "or product personal or commercial. The license may be viewed here. " +
     #LF$ + "The source code, as well as the library documentation may be found " +
     #LF$ + "on the Scintilla Homepage. " +
     #LF$ +
     #LF$ + "From the Scintilla Homepage : As well As " +
     #LF$ + "features found in standard text editing components, Scintilla includes " +
     #LF$ + "features especially useful when editing And debugging source code." +
     #LF$ +
     #LF$ +
     #LF$ + "These include support For syntax styling, error indicators, code " +
     #LF$ + "completion And call tips.The selection margin can contain markers " +
     #LF$ + "like those used in debuggers To indicate breakpoints and the current " +
     #LF$ + "line.Styling choices are more open than With many editors, allowing the" +
     #LF$ + " use of proportional fonts, bold And italics, multiple foreground " +
     #LF$ + "and background colors And multiple fonts." +
     #LF$ + #LF$ + #LF$ + "20  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
For i=30 To 1000 Step 10
  txt$ + #LF$ + #LF$ + #LF$ + #LF$ + #LF$ + #LF$ + #LF$ + #LF$ + #LF$ + #LF$
  txt$ + Str(i) + "  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
Next

Procedure EditCallBack(Gadget, *scinotify.SCNotification)

  Debug "EditCallBack"
  Static focus.i, oldposition.i
  ; You code here
  If *scinotify\nmhdr\code = #SCN_FOCUSIN
    Debug "> editor FOCUS"
    focus = #True
  EndIf
  If *scinotify\nmhdr\code = #SCN_FOCUSOUT
    Debug "> editor LOST FOCUS"
    focus = #False
  EndIf
  
  
  If focus
    Debug "editor: still have the focus :)"  
            
    ; this makes the editor writeable
    If ScintillaSendMessage(0, #SCI_GETREADONLY) = 1
      ScintillaSendMessage(0, #SCI_SETREADONLY, 0)
    EndIf
    ; this sets the cursor where the other one is
    If ScintillaSendMessage(1, #SCI_GETCURRENTPOS) <> ScintillaSendMessage(0, #SCI_GETCURRENTPOS)
      
      ; TO DO !!! need to distinguish if the current line moves down or up....
      ; main editor's position moves the vscroll selection 
      ; if editor's current line is inside the visible area the vscroll selection doesn't move
      ; seems to work...
      If ScintillaSendMessage(0, #SCI_LINEFROMPOSITION, ScintillaSendMessage(0, #SCI_GETCURRENTPOS)) < ScintillaSendMessage(0, #SCI_GETFIRSTVISIBLELINE) + ScintillaSendMessage(0, #SCI_LINESONSCREEN)
        
        ScintillaSendMessage(1, #SCI_GOTOPOS, ScintillaSendMessage(0, #SCI_POSITIONFROMLINE, ScintillaSendMessage(0, #SCI_GETFIRSTVISIBLELINE) + ScintillaSendMessage(0, #SCI_LINESONSCREEN)) - 1)
        ScintillaSendMessage(1, #SCI_SETSELECTION, ScintillaSendMessage(1, #SCI_POSITIONFROMLINE, ScintillaSendMessage(1, #SCI_LINEFROMPOSITION, ScintillaSendMessage(1, #SCI_GETCURRENTPOS))), ScintillaSendMessage(1, #SCI_GETLINEENDPOSITION, ScintillaSendMessage(1, #SCI_LINEFROMPOSITION, ScintillaSendMessage(1, #SCI_GETCURRENTPOS)) - ScintillaSendMessage(0, #SCI_LINESONSCREEN)))
      EndIf
    
    EndIf

  EndIf
EndProcedure

Procedure VScrollCallBack(Gadget, *scinotify.SCNotification)
  
  Debug "VScrollCallBack"
  Static focus.i
  ; You code here
  If *scinotify\nmhdr\code = #SCN_FOCUSIN
    Debug "> vscroll: FOCUS"
    focus = #True
  EndIf
  If *scinotify\nmhdr\code = #SCN_FOCUSOUT
    Debug "> vscroll: LOST FOCUS"
    focus = #False
  EndIf

  If focus
    Debug "vscroll: still have the focus :)"
    
    ; this makes the vscroll readonly
    If ScintillaSendMessage(0, #SCI_GETREADONLY) = 0
      ScintillaSendMessage(0, #SCI_SETREADONLY, 1)
    EndIf
    ; this sets the cursor where the other one is
    If ScintillaSendMessage(0, #SCI_LINEFROMPOSITION, ScintillaSendMessage(0, #SCI_GETCURRENTPOS)) <> ScintillaSendMessage(1, #SCI_LINEFROMPOSITION, ScintillaSendMessage(1, #SCI_GETCURRENTPOS))
      
      ScintillaSendMessage(0, #SCI_GOTOLINE, ScintillaSendMessage(1, #SCI_LINEFROMPOSITION, ScintillaSendMessage(1, #SCI_GETCURRENTPOS)))
      
      If ScintillaSendMessage(0, #SCI_GETCURRENTPOS) > ScintillaSendMessage(1, #SCI_GETCURRENTPOS)
        
        ; set the line at the top of the visible lines
        ScintillaSendMessage(0, #SCI_SETFIRSTVISIBLELINE, ScintillaSendMessage(0, #SCI_LINEFROMPOSITION, ScintillaSendMessage(0, #SCI_GETCURRENTPOS))); + (ScintillaSendMessage(0, #SCI_LINESONSCREEN)))
      Else
        
        If ScintillaSendMessage(0, #SCI_LINEFROMPOSITION, ScintillaSendMessage(0, #SCI_GETCURRENTPOS)) > ScintillaSendMessage(0, #SCI_GETLINECOUNT) - (ScintillaSendMessage(0, #SCI_LINESONSCREEN) + 1) ;SCI_GETLINEVISIBLE)
          ScintillaSendMessage(1, #SCI_SETFIRSTVISIBLELINE, ScintillaSendMessage(1, #SCI_POSITIONFROMLINE, ScintillaSendMessage(1, #SCI_GETLINECOUNT), (ScintillaSendMessage(0, #SCI_LINESONSCREEN)))); + 1)
        Else 
          ; set the line at the top of the visible lines
          ScintillaSendMessage(0, #SCI_SETFIRSTVISIBLELINE, ScintillaSendMessage(0, #SCI_LINEFROMPOSITION, ScintillaSendMessage(0, #SCI_GETCURRENTPOS))); - (ScintillaSendMessage(0, #SCI_LINESONSCREEN)))
          ScintillaSendMessage(1, #SCI_SETSELECTION, ScintillaSendMessage(0, #SCI_POSITIONFROMLINE, ScintillaSendMessage(0, #SCI_LINEFROMPOSITION, ScintillaSendMessage(0, #SCI_GETCURRENTPOS))), ScintillaSendMessage(0, #SCI_GETLINEENDPOSITION, ScintillaSendMessage(0, #SCI_LINEFROMPOSITION, ScintillaSendMessage(0, #SCI_GETCURRENTPOS)) + ScintillaSendMessage(0, #SCI_LINESONSCREEN)))
        EndIf
        
      EndIf
      
    EndIf
       
  EndIf

EndProcedure
  

Procedure MainWindowResize()
  Protected mainWidth  = WindowWidth(#Window)
  Protected mainHeight = WindowHeight(#Window)
  Protected sideWidth  = GadgetWidth(1)
 
  ResizeGadget(0, 0, 0, mainWidth - sideWidth, mainHeight)
  ResizeGadget(1, mainWidth - sideWidth, 0, sideWidth, mainHeight)
 
EndProcedure

OpenWindow(#Window, 0, 0, 600, 400, "Editing with Multi cursor (like eclipse or sublimetext)", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget)

ScintillaGadget(0, 0, 0, WindowWidth(#Window) - 100, WindowHeight(#Window), @EditCallBack())

ScintillaGadget(1, GadgetWidth(0), 0, 100, WindowHeight(#Window), @VScrollCallBack())

; Set Text Mode
ScintillaSendMessage(0, #SCI_SETWRAPMODE, #SC_WRAP_NONE)
ScintillaSendMessage(0, #SCI_SETCODEPAGE, #SC_CP_UTF8)
ScintillaSendMessage(0, #SCI_SETVIRTUALSPACEOPTIONS, #SCVS_RECTANGULARSELECTION | #SCVS_USERACCESSIBLE) ; allow cursor and rect selection to move beyond end of line
                                                                                                        ; Set Current Line Highlighting
ScintillaSendMessage(0, #SCI_SETCARETLINEVISIBLE, 1)
ScintillaSendMessage(0, #SCI_SETCARETLINEVISIBLEALWAYS, 1)
ScintillaSendMessage(0, #SCI_SETCARETLINEBACKALPHA, 50)
ScintillaSendMessage(0, #SCI_SETCARETLINEBACK, RGB(100, 252, 195))

; Set Text style
ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_DEFAULT, MakeUTF8Text("Courier New")) ; rectangle selection works better with mono-width font
ScintillaSendMessage(0, #SCI_STYLESETSIZE, #STYLE_DEFAULT, 10)
ScintillaSendMessage(0, #SCI_STYLESETBACK, #STYLE_DEFAULT, RGB(70, 78, 85))
ScintillaSendMessage(0, #SCI_STYLESETFORE, #STYLE_DEFAULT, RGB(195, 213, 255))
ScintillaSendMessage(0, #SCI_STYLECLEARALL)
; Set Margin size and style
ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_LINENUMBER, MakeUTF8Text("Arial"))
ScintillaSendMessage(0, #SCI_STYLESETBACK, #STYLE_LINENUMBER, RGB(53, 55, 57))
ScintillaSendMessage(0, #SCI_STYLESETFORE, #STYLE_LINENUMBER, RGB(200, 200, 200))
marginWidth=ScintillaSendMessage(0, #SCI_TEXTWIDTH, #STYLE_LINENUMBER, MakeUTF8Text("_9999"))
ScintillaSendMessage(0, #SCI_SETMARGINTYPEN, 0, #SC_MARGIN_NUMBER)
ScintillaSendMessage(0, #SCI_SETMARGINWIDTHN, 0, marginWidth)
marginWidth=0
ScintillaSendMessage(0, #SCI_SETMARGINMASKN, 2, #SC_MASK_FOLDERS)
ScintillaSendMessage(0, #SCI_SETMARGINWIDTHN, 2, marginWidth)
ScintillaSendMessage(0, #SCI_SETMARGINSENSITIVEN, 2, #True)
; Set Main Caret and Selection
ScintillaSendMessage(0, #SCI_SETCARETSTICKY, 1) ;make always visible
ScintillaSendMessage(0, #SCI_SETCARETWIDTH, 3)  ;make thicker
ScintillaSendMessage(0, #SCI_SETCARETFORE, RGB(255, 160, 136))
ScintillaSendMessage(0, #SCI_SETSELALPHA, 100)
ScintillaSendMessage(0, #SCI_SETSELBACK, 1, RGB(255, 160, 136))
ScintillaSendMessage(0, #SCI_SETSELFORE, 1, RGB(200, 200, 200))
; Set Additional Caret and Selection
ScintillaSendMessage(0, #SCI_SETADDITIONALCARETFORE, RGB(157, 64, 41))
ScintillaSendMessage(0, #SCI_SETADDITIONALCARETSBLINK, 1)
ScintillaSendMessage(0, #SCI_SETADDITIONALSELALPHA, 100)
ScintillaSendMessage(0, #SCI_SETADDITIONALSELBACK, RGB(255, 160, 136))
ScintillaSendMessage(0, #SCI_SETADDITIONALSELFORE, RGB(200, 200, 200))
; Enable multi cursor editing
ScintillaSendMessage(0, #SCI_SETRECTANGULARSELECTIONMODIFIER, #SCMOD_ALT) ; select rectangle range by holding down the ALT key while dragging with the mouse
ScintillaSendMessage(0, #SCI_SETMULTIPLESELECTION, 1)                     ; select multiple ranges by holding down the CTRL or CMD key while dragging with the mouse
ScintillaSendMessage(0, #SCI_SETMULTIPASTE, #SC_MULTIPASTE_EACH)
ScintillaSendMessage(0, #SCI_SETADDITIONALSELECTIONTYPING, 1)
; Enable hotkey for selection auto extension CTRL + D
AddKeyboardShortcut(#Window, #PB_Shortcut_Control | #PB_Shortcut_D, #MENU_EXTEND_SELECTION)
BindEvent(#PB_Event_Menu, ExtendScintillaSelection())

; Change text, then jump to end of last line
ScintillaSendMessage(0, #SCI_SETTEXT, 0, MakeUTF8Text(txt$))
lastLineEndPos=ScintillaSendMessage(0, #SCI_GETLINEENDPOSITION, ScintillaSendMessage(0, #SCI_GETLINECOUNT)-1)
ScintillaSendMessage(0, #SCI_GOTOPOS, lastLineEndPos)
SetActiveGadget(0)

;code-map
ScintillaSendMessage(1, #SCI_SETDOCPOINTER, 0, ScintillaSendMessage(0, #SCI_GETDOCPOINTER)) ; clone doc
ScintillaSendMessage(1, #SCI_SETWRAPMODE, #SC_WRAP_NONE)
ScintillaSendMessage(1, #SCI_SETCODEPAGE, #SC_CP_UTF8)
ScintillaSendMessage(1, #SCI_SETCARETLINEVISIBLE, 1)
ScintillaSendMessage(1, #SCI_SETCARETLINEVISIBLEALWAYS, 1)
ScintillaSendMessage(1, #SCI_SETCARETLINEBACKALPHA, 50)
ScintillaSendMessage(1, #SCI_SETCARETLINEBACK, RGB(100, 252, 195))

ScintillaSendMessage(1, #SCI_SETMARGINWIDTHN, 0, 0)
ScintillaSendMessage(1, #SCI_SETMARGINWIDTHN, 1, 0)
ScintillaSendMessage(1, #SCI_SETMARGINWIDTHN, 2, 0)
ScintillaSendMessage(1, #SCI_STYLESETFONT, #STYLE_DEFAULT, MakeUTF8Text("Courier New")) ; clone font
ScintillaSendMessage(1, #SCI_STYLESETSIZE, #STYLE_DEFAULT, 1)
; background and foreground
ScintillaSendMessage(1, #SCI_STYLESETBACK, #STYLE_DEFAULT, RGB(70, 78, 85))
ScintillaSendMessage(1, #SCI_STYLESETFORE, #STYLE_DEFAULT, RGB(195, 213, 255))
; 
; this is the attempt to show the amount of visible lines in the vscroll
ScintillaSendMessage(1, #SCI_SETSELECTIONMODE, 1)
Debug "SELECTIONISRECTANGLE: " + ScintillaSendMessage(1, #SCI_SELECTIONISRECTANGLE)
ScintillaSendMessage(1, #SCI_SETSELEOLFILLED, 1)
ScintillaSendMessage(1, #SCI_SETSELALPHA, 100)
ScintillaSendMessage(1, #SCI_SETSELBACK, 1, RGB(100, 252, 195))
ScintillaSendMessage(1, #SCI_SETSELFORE, 1, RGB(200, 200, 200))

ScintillaSendMessage(1, #SCI_STYLECLEARALL)

; Tweak scrollbars and border display
ScintillaSendMessage(0, #SCI_SETVSCROLLBAR, 0)
ScintillaSendMessage(0, #SCI_SETHSCROLLBAR, 1)
ScintillaSendMessage(1, #SCI_SETVSCROLLBAR, 0)
ScintillaSendMessage(1, #SCI_SETHSCROLLBAR, 0)
; 
ScintillaSendMessage(1, #SCI_SETREADONLY, 1)
ScintillaSendMessage(0, #SCI_SETREADONLY, 0)
; 
ResizeWindow(#Window, #PB_Ignore, #PB_Ignore, WindowWidth(#Window) + 1, WindowHeight(#Window) + 1) ;force refreshing

ScintillaSendMessage(0, #SCI_GOTOPOS, 0)

SmartWindowRefresh(#Window, #True)
BindEvent(#PB_Event_SizeWindow, @MainWindowResize(), #Window)

; this sets the visible "portion" on the vscroll after start
ScintillaSendMessage(1, #SCI_SETSELECTION, ScintillaSendMessage(0, #SCI_POSITIONFROMLINE, ScintillaSendMessage(0, #SCI_LINEFROMPOSITION, ScintillaSendMessage(0, #SCI_GETCURRENTPOS))), ScintillaSendMessage(0, #SCI_GETLINEENDPOSITION, ScintillaSendMessage(0, #SCI_LINEFROMPOSITION, ScintillaSendMessage(0, #SCI_GETCURRENTPOS)) + ScintillaSendMessage(0, #SCI_LINESONSCREEN)))

Repeat
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow

I am to provide the public with beneficial shocks.
Alfred Hitshock
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Scintilla using SublimeText-like code-scroller (not Unic

Post by fsw »

Tenaja wrote:
fsw wrote:Also, I was thinking about if it would be beneficial to use scintillas zoom function instead of a fixed size for the code-scroller.

So many options :P
That is what I do. If there is a click, get the line, and move the displayed line on the second sci gadget.
Do I understand correctly that (inside the vscroll) you only zoom the current line?
To what font size do you zoom?
Is this to avoid to have a vscroll-bar for the visible area on the editor?

If I can't get my vscroll-bar solution working right... maybe your way is the way to go.
(if I understand correctly what you are doing...)

I am to provide the public with beneficial shocks.
Alfred Hitshock
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Scintilla using SublimeText-like code-scroller (not Unic

Post by fsw »

Just tested the zoom function for the first time.
Zooming is applied to the whole document, not just a single line.

Zooming-in on a mouse-click is probably a nice way to avoid the vscroll-bar issues I'm fiddling around with...

I am to provide the public with beneficial shocks.
Alfred Hitshock
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: Scintilla using SublimeText-like code-scroller (not Unic

Post by eddy »

Here is an other test.
The next step is to calculate properly vertical scrollbar position between editor and minimap.
Folded and hidden lines make this task more complex.

Code: Select all

EnableExplicit
InitScintilla()

#MENU_EXTEND_SELECTION=10

Procedure MakeUTF8Text(text.s)
   Static buffer.s
   buffer=Space(StringByteLength(text, #PB_UTF8))
   PokeS(@buffer, text, -1, #PB_UTF8)
   ProcedureReturn @buffer
EndProcedure

Procedure SciStyle(Scintilla, style=#STYLE_DEFAULT, foreColor=#PB_Ignore, backColor=#PB_Ignore, useBold=#PB_Ignore, useItalic=#PB_Ignore, font$="", fontSize=#PB_Ignore)
   If foreColor<>#PB_Ignore : ScintillaSendMessage(Scintilla, #SCI_STYLESETFORE, style, foreColor) : EndIf
   If backColor<>#PB_Ignore : ScintillaSendMessage(Scintilla, #SCI_STYLESETBACK, style, backColor) : EndIf
   If font$<>"" : ScintillaSendMessage(Scintilla, #SCI_STYLESETFONT, style, MakeUTF8Text(font$)) : EndIf
   If fontSize<>#PB_Ignore : ScintillaSendMessage(Scintilla, #SCI_STYLESETSIZE, style, fontSize) : EndIf
   If useBold<>#PB_Ignore : ScintillaSendMessage(Scintilla, #SCI_STYLEGETBOLD, style, useBold) : EndIf
   If useItalic<>#PB_Ignore : ScintillaSendMessage(Scintilla, #SCI_STYLEGETITALIC, style, useItalic) : EndIf
EndProcedure

Procedure SciInit(Scintilla, font$, fontSize, foreColor=$000000, backColor=$FFFFFF, scrollbarV=#True, scrollbarH=#True, borders=#True, cursorBeyondEndOfLine=#False, wrapMode=#SC_WRAP_NONE, codePage=#SC_CP_UTF8)
   ;configure text mode
   ScintillaSendMessage(Scintilla, #SCI_SETWRAPMODE, wrapMode)
   ScintillaSendMessage(Scintilla, #SCI_SETCODEPAGE, codePage)
   ;configure virtual space options
   ScintillaSendMessage(Scintilla, #SCI_SETVIRTUALSPACEOPTIONS, #SCVS_NONE)
   If cursorBeyondEndOfLine : ScintillaSendMessage(Scintilla, #SCI_SETVIRTUALSPACEOPTIONS, #SCVS_RECTANGULARSELECTION | #SCVS_USERACCESSIBLE) : EndIf
   ;configure default style
   SciStyle(Scintilla, #STYLE_DEFAULT, foreColor, backColor, #False, #False, font$, fontSize) ; rectangle selection works better with mono-width font
   ScintillaSendMessage(Scintilla, #SCI_STYLECLEARALL)
   ;show/hide scrollbars
   ScintillaSendMessage(Scintilla, #SCI_SETVSCROLLBAR, scrollbarV)
   ScintillaSendMessage(Scintilla, #SCI_SETHSCROLLBAR, scrollbarH)
   ;show/hide borders
   If Not borders : SetWindowLongPtr_(GadgetID(Scintilla), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(Scintilla), #GWL_EXSTYLE) & ~#WS_EX_CLIENTEDGE) : EndIf
EndProcedure

Procedure SciShowCaretLine(Scintilla, visible=#True, alwaysVisible=#True, backColor=$EEEEEE, backAlpha=255)
   ScintillaSendMessage(Scintilla, #SCI_SETCARETLINEVISIBLE, Bool(visible))
   ScintillaSendMessage(Scintilla, #SCI_SETCARETLINEVISIBLEALWAYS, Bool(alwaysVisible))
   ScintillaSendMessage(Scintilla, #SCI_SETCARETLINEBACK, backColor)
   ScintillaSendMessage(Scintilla, #SCI_SETCARETLINEBACKALPHA, backAlpha)
EndProcedure

Procedure SciShowCarets(Scintilla, visible=#True, othersVisible=#True, thickness=1, blinkPeriod=500, alwaysVisible=#True, foreColor=$111111, othersBlinking=#True, othersForeColor=$222222)
   ;main caret
   ScintillaSendMessage(Scintilla, #SCI_SETCARETWIDTH, Bool(visible) * thickness)
   ScintillaSendMessage(Scintilla, #SCI_SETCARETSTICKY, Bool(visible And alwaysVisible))
   ScintillaSendMessage(Scintilla, #SCI_SETCARETFORE, foreColor)
   ScintillaSendMessage(Scintilla, #SCI_SETCARETPERIOD, blinkPeriod)
   ;additional carets
   ScintillaSendMessage(Scintilla, #SCI_SETADDITIONALCARETSVISIBLE, Bool(othersVisible))
   ScintillaSendMessage(Scintilla, #SCI_SETADDITIONALCARETSBLINK, Bool(othersVisible And othersBlinking))
   ScintillaSendMessage(Scintilla, #SCI_SETADDITIONALCARETFORE, othersForeColor)
EndProcedure

Procedure SciShowSelections(Scintilla, visible=#True, othersVisible=#True, textColoring=#True, foreColor=$222222, backColor=$DDDDDD, backAlpha=255, othersTyping=#True, othersForeColor=$333333, othersBackColor=$CCCCCC, othersBackAlpha=255)
   ;main selection
   ScintillaSendMessage(Scintilla, #SCI_SETSELALPHA, Bool(visible) * backAlpha)
   ScintillaSendMessage(Scintilla, #SCI_SETSELBACK, Bool(visible), backColor)
   ScintillaSendMessage(Scintilla, #SCI_SETSELFORE, Bool(visible And textColoring), foreColor)
   ;additional selections
   ScintillaSendMessage(Scintilla, #SCI_SETADDITIONALSELALPHA, Bool(othersVisible) * othersBackAlpha)
   ScintillaSendMessage(Scintilla, #SCI_SETADDITIONALSELBACK, Bool(othersVisible) * othersBackColor)
   ScintillaSendMessage(Scintilla, #SCI_SETADDITIONALSELFORE, Bool(othersVisible And textColoring) * othersForeColor)
   ScintillaSendMessage(Scintilla, #SCI_SETADDITIONALSELECTIONTYPING, Bool(othersTyping))
EndProcedure

Procedure SciMargin(Scintilla, index=0, width=16, typen=#SC_MARGIN_NUMBER, mask=#SC_MASK_FOLDERS, clickable=#True)
   ScintillaSendMessage(Scintilla, #SCI_SETMARGINTYPEN, index, typen)         ; margin type (number or text)
   ScintillaSendMessage(Scintilla, #SCI_SETMARGINMASKN, index, mask)          ; determines which combination of margin symbols can be displayed
   ScintillaSendMessage(Scintilla, #SCI_SETMARGINWIDTHN, index, width)
   ScintillaSendMessage(Scintilla, #SCI_SETMARGINSENSITIVEN, index, Bool(clickable))
EndProcedure

Procedure SciCloneDocument(Scintilla, ScintillaToClone)
   ScintillaSendMessage(Scintilla, #SCI_SETDOCPOINTER, 0, ScintillaSendMessage(ScintillaToClone, #SCI_GETDOCPOINTER))
EndProcedure

Define LoremIpsum$, WordList$="lorem,ipsum,dolor,sit,amet,consectetuer,adipiscing,elit,sed,diam,nonummy,nibh,euismod,tincidunt,ut,laoreet,dolore,magna,aliquam,erat"
Define word, paragraph, linebreak
For paragraph=0 To 20
   For word=0 To 30 + paragraph
      LoremIpsum$ + StringField(WordList$, Random(20, 1), ",") + " "
      linebreak + 1 : If (linebreak % (5 + paragraph / 2))=0 : LoremIpsum$ + #LF$ : EndIf
   Next
   LoremIpsum$ + #LF$ + #LF$ + "++++++++++++++++++++++++++++++" + #LF$ + #LF$
Next

Runtime Enumeration
   #Dialog : #Xml : #Container : #Minimap : #Editor
EndEnumeration

Procedure ResizeAll()
   Protected marginTotalWidth=0, marginIndex
   For marginIndex=0 To #SC_MAX_MARGIN
      marginTotalWidth + ScintillaSendMessage(#Editor, #SCI_GETMARGINWIDTHN, marginIndex)
   Next
   Debug marginTotalWidth
   Protected *longLineText=MakeUTF8Text(Space(300))
   Protected mini=ScintillaSendMessage(#Minimap, #SCI_TEXTWIDTH, #STYLE_DEFAULT, *longLineText)
   Protected big=ScintillaSendMessage(#Editor, #SCI_TEXTWIDTH, #STYLE_DEFAULT, *longLineText)
   Protected width=(GadgetWidth(#Container)-marginTotalWidth)*big / (big + mini) + marginTotalWidth
   If width<(GadgetWidth(#Container)-200) : width=(GadgetWidth(#Container)-200) : EndIf
   ResizeGadget(#Editor, 0, 0, width, GadgetHeight(#Container))
   ResizeGadget(#Minimap, width, 0, GadgetWidth(#Container)-width, GadgetHeight(#Container))
EndProcedure

Procedure UpdateMinimap(Gadget, *scinotify.SCNotification)
   If *scinotify\nmhdr\code=#SCN_UPDATEUI And *scinotify\updated=#SC_UPDATE_V_SCROLL
      Protected l, l0, l1
      ;l0=ScintillaSendMessage(#Minimap, #SCI_GETFIRSTVISIBLELINE)
      ;l1=l0 + ScintillaSendMessage(#Minimap, #SCI_LINESONSCREEN)
      ;max=ScintillaSendMessage(#Minimap, #SCI_GETLINECOUNT)-ScintillaSendMessage(#Minimap, #SCI_LINESONSCREEN)
      Protected sInfo.SCROLLINFO
      sInfo\fMask=#SIF_PAGE | #SIF_POS | #SIF_RANGE | #SIF_TRACKPOS
      Debug GetScrollInfo_(GadgetID(#Minimap), #SB_VERT, @sInfo)
      Debug "" + sInfo\nMin + " " + sInfo\nMax + " " + sInfo\nPos + " " + sInfo\nTrackPos
      Debug GetScrollInfo_(GadgetID(#Editor), #SB_VERT, @sInfo)
      Debug "." + sInfo\nMin + " " + sInfo\nMax + " " + sInfo\nPos + " " + sInfo\nTrackPos
      
      l0=ScintillaSendMessage(#Editor, #SCI_GETFIRSTVISIBLELINE)
      l1=l0 + ScintillaSendMessage(#Editor, #SCI_LINESONSCREEN)
      ScintillaSendMessage(#Minimap, #SCI_MARKERDELETEALL, 0)
      For l=l0 To l1
         ScintillaSendMessage(#Minimap, #SCI_MARKERADD, l, 0)
      Next
   EndIf
EndProcedure

Define Xml$="<window id='100' name='scintilla-minimap' text='Editing with Multi cursor (like eclipse or sublimetext)' " + 
            "   margin='0' minwidth='600' minheight='300' " + 
            "   flags='#PB_Window_ScreenCentered | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_SystemMenu | #PB_Window_SizeGadget' >" + 
            "   <container id='#Container'>" + 
            "   </container>" + 
            "</window>"
If CatchXML(#Xml, @Xml$, StringByteLength(Xml$), 0, #PB_UTF8) And XMLStatus(#Xml)=#PB_XML_Success And CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "scintilla-minimap")
   
   OpenGadgetList(#Container)
   ScintillaGadget(#Minimap, 0, 0, 0, 0, @UpdateMinimap())
   ScintillaGadget(#Editor, 0, 0, 0, 0, @UpdateMinimap())
   SetActiveGadget(#Editor)
   CloseGadgetList()
   BindEvent(#PB_Event_SizeWindow, @ResizeAll())
   
   SciInit(#Editor, "Courier New", 8, RGB(195, 213, 255), RGB(70, 78, 85), #False, #False, #False, #True)
   SciStyle(#Editor, #STYLE_LINENUMBER, RGB(200, 200, 200), RGB(53, 55, 57), #False, #False, "Arial")
   SciMargin(#Editor, 0, ScintillaSendMessage(#Editor, #SCI_TEXTWIDTH, #STYLE_LINENUMBER, MakeUTF8Text("_9999")))
   SciShowCarets(#Editor, #True, #True, 3, 500, #True, RGB(255, 160, 136), #True, RGB(157, 64, 41))
   SciShowCaretLine(#Editor, #True, #True, RGB(100, 252, 195), 50)
   SciShowSelections(#Editor, #True, #True, #True, RGB(200, 200, 200), RGB(255, 160, 136), 100, #True, RGB(200, 200, 200), RGB(255, 160, 136), 100)
   ScintillaSendMessage(#Editor, #SCI_SETTEXT, 0, MakeUTF8Text(LoremIpsum$))
   
   SciInit(#Minimap, "Courier New", 2, RGB(195, 213, 255), RGB(70, 78, 85), #False, #False, #False)
   SciMargin(#Minimap, 0, 0)
   SciMargin(#Minimap, 1, 0)
   SciShowCarets(#Minimap, #False, #False)
   SciShowSelections(#Minimap, #False, #False)
   SciCloneDocument(#Minimap, #Editor)
   ScintillaSendMessage(#Minimap, #SCI_SETFONTQUALITY, #SC_EFF_QUALITY_ANTIALIASED)
   
   ScintillaSendMessage(#Editor, #SCI_MARKERDEFINE, 0, #SC_MARK_EMPTY)
   ScintillaSendMessage(#Minimap, #SCI_MARKERDEFINE, 0, #SC_MARK_BACKGROUND)
   ScintillaSendMessage(#Minimap, #SCI_MARKERSETBACK, 0, RGB(104, 111, 158))
   
   ResizeWindow(100, #PB_Ignore, #PB_Ignore, WindowWidth(100) + 1, WindowHeight(100) + 1) ;force refreshing
   
   
EndIf

Repeat: Until WaitWindowEvent()=#PB_Event_CloseWindow
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
Post Reply