Scintilla not changeable text area

Just starting out? Need help? Post your questions and find answers here.
User avatar
rmenezes
User
User
Posts: 14
Joined: Sat Oct 11, 2014 11:28 pm

Scintilla not changeable text area

Post by rmenezes »

Hey

So I needed Scintilla to let me insert a read-only section at the start of text and lock it in place. This area would be filled later, progammatically. Maybe I could use this in a self-documenting feature or something. Or not.

Anyway, I took a peek at the #SCI_STYLESETCHANGEABLE message. In ScintillaDocs it is said that it is an "experimental and incompletely implemented style attribute". Caveat emptor. Ok, I understand that. But maybe it could still be usefull as it is. So I wrote this simple tester code:

Code: Select all

EnableExplicit
InitScintilla()

#STYLE_PROTECTED = 30
Define sciFont.s, hdr$, hdrLen, memBuffer

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

Procedure DoSciEvent()
  Shared hdrLen
  Protected posNow
  If EventType() = #PB_EventType_RightClick
    posNow = ScintillaSendMessage(0, #SCI_GETCURRENTPOS)
    If ScintillaSendMessage(0, #SCI_GETSTYLEAT, posNow) = #STYLE_PROTECTED
      ScintillaSendMessage(0, #SCI_GOTOPOS, hdrLen)
      MessageRequester("WARNING!", "Restricted area. Trespassers will be shot.")
    EndIf
  EndIf
EndProcedure

hdr$ = ""
hdr$ + "----------------------------------------" + #CR$
hdr$ + "----                                ----" + #CR$
hdr$ + "----    This is a protected area    ----" + #CR$
hdr$ + "----        (ma non troppo)         ----" + #CR$
hdr$ + "----                                ----" + #CR$
hdr$ + "----------------------------------------" + #CR$
hdrLen = StringByteLength(hdr$,#PB_UTF8)
sciFont = "Courier New"
memBuffer = AllocateMemory(Len(sciFont) + 1)
PokeS(memBuffer, sciFont, -1, #PB_Ascii)

OpenWindow(0, 0, 0, 600, 700, "Block me lines!", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ScintillaGadget(0, 0, 0, WindowWidth(0), WindowHeight(0), 0)
ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_DEFAULT, memBuffer)
ScintillaSendMessage(0, #SCI_SETWRAPMODE, #SC_WRAP_WHITESPACE)
ScintillaSendMessage(0, #SCI_SETCODEPAGE, #SC_CP_UTF8)
ScintillaSendMessage(0, #SCI_STYLESETBACK, #STYLE_PROTECTED, RGB($EE, $EE, $EE))
ScintillaSendMessage(0, #SCI_STYLESETCHANGEABLE, #STYLE_PROTECTED, 0)
ScintillaSendMessage(0, #SCI_SETTEXT, 0, MakeUTF8Text(hdr$))
ScintillaSendMessage(0, #SCI_STARTSTYLING, 0, $1F)
ScintillaSendMessage(0, #SCI_SETSTYLING, hdrLen, #STYLE_PROTECTED)
ScintillaSendMessage(0, #SCI_GOTOPOS, hdrLen)
SetActiveGadget(0)
BindGadgetEvent(0, @DoSciEvent())

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
End
I my test machine it worked pretty good, actually: I could not position the caret within the styled area neither using the cursos keys nor with mouse leftclick. But oh, the rightclick... There was the caret, smack in the middle of the text, and Scintilla let me insert text normally. So I trapped the rightclick event (as per netmaestro, in another post): if it happened within the protected area, I would just move the caret to the first editable position past it. Success! That is, if you didn't rightclick and held it that way. Then you could insert text again. Allright, I guess I can live with that. I mean, if you really want to mess it up...

But the caret could still be positioned right before the protected area (either by arrow keys, as it jumped past it, or by leftclicking there) and then I was able to insert text again, pushing the following text forward. Not cool. Not cool at all. My protected area must remain there, at the start of the text, always. Then I realized I was out of beer. And ideas.

Any thoughts?

Ricardo
Nullius in verba.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Scintilla not changeable text area

Post by IdeasVacuum »

Why not use a separate gadget (StringGadget) and make that read only?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: Scintilla not changeable text area

Post by Tenaja »

If you trap the Scintilla notification (Case #SCN_CHARADDED), you can remove the new character if it is in an invalid location.


See srod's GOSCI for an example of a callback that traps those notifications, in proc GOSCI_ScintillaCallBackXXX.
User avatar
rmenezes
User
User
Posts: 14
Joined: Sat Oct 11, 2014 11:28 pm

Re: Scintilla not changeable text area

Post by rmenezes »

@vacuumm

That's true. That can be done. But what about the challenge? Ultimately, this is an exercise on pushing the prosaic "envelope". And an excuse to go for more beer :)

@tenaja

Good call. That 'll be my next attempt. I don't know how to remove the CHARADDED character once it is in (couldn't find it in the SciDocs). Lemme look at them GoSCI code. Maybe I'll find my answer there.


To be continued.

Ricardo
Nullius in verba.
User avatar
rmenezes
User
User
Posts: 14
Joined: Sat Oct 11, 2014 11:28 pm

Re: Scintilla not changeable text area

Post by rmenezes »

Oh, yeah.

Be it known to one and all that in Scintilla we don't delete chars. We replace them! So, with a big thank you to srod for his GoSCI and tenaja for his suggestion to look it up, here's a revised version of the previous code:

Code: Select all


EnableExplicit
InitScintilla()

#STYLE_PROTECTED = 30
Define sciFont.s, hdr$, hdrLen, memBuffer

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

Procedure DoSciCallback(i, *scinotify.SCNotification)
  Shared hdrLen
  Protected posNow
  Select *scinotify\nmhdr\code
    Case #SCN_CHARADDED
      posNow = ScintillaSendMessage(i, #SCI_GETCURRENTPOS)
      If posNow < hdrLen
        ; delete this sucker
        ScintillaSendMessage(i, #SCI_SETTARGETSTART, 0)
        ScintillaSendMessage(i, #SCI_SETTARGETEND, posNow)
        ScintillaSendMessage(i, #SCI_REPLACETARGET, -1, @"")
        ScintillaSendMessage(i, #SCI_GOTOPOS, hdrLen)
    EndIf
  EndSelect
EndProcedure

Procedure DoSciEvent()
  Shared hdrLen
  Protected posNow
  If EventType() = #PB_EventType_RightClick
    posNow = ScintillaSendMessage(0, #SCI_GETCURRENTPOS)
    If posNow < hdrLen
      ScintillaSendMessage(0, #SCI_GOTOPOS, hdrLen)
      MessageRequester("WARNING!", "Restricted area. Trespassers will be shot.")
    EndIf
  EndIf
EndProcedure

hdr$ = ""
hdr$ + "----------------------------------------" + #CR$
hdr$ + "----                                ----" + #CR$
hdr$ + "----    This is a protected area    ----" + #CR$
hdr$ + "----        (ma non troppo)         ----" + #CR$
hdr$ + "----                                ----" + #CR$
hdr$ + "----------------------------------------" + #CR$
hdrLen = StringByteLength(hdr$,#PB_UTF8)
sciFont = "Courier New"
memBuffer = AllocateMemory(Len(sciFont) + 1)
PokeS(memBuffer, sciFont, -1, #PB_Ascii)

OpenWindow(0, 0, 0, 600, 700, "Block me lines!", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ScintillaGadget(0, 0, 0, WindowWidth(0), WindowHeight(0), @DoSciCallback())
ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_DEFAULT, memBuffer)
ScintillaSendMessage(0, #SCI_SETWRAPMODE, #SC_WRAP_WHITESPACE)
ScintillaSendMessage(0, #SCI_SETCODEPAGE, #SC_CP_UTF8)
ScintillaSendMessage(0, #SCI_STYLESETBACK, #STYLE_PROTECTED, RGB($EE, $EE, $EE))
ScintillaSendMessage(0, #SCI_STYLESETCHANGEABLE, #STYLE_PROTECTED, 0)
ScintillaSendMessage(0, #SCI_SETTEXT, 0, MakeUTF8Text(hdr$))
ScintillaSendMessage(0, #SCI_STARTSTYLING, 0, $1F)
ScintillaSendMessage(0, #SCI_SETSTYLING, hdrLen, #STYLE_PROTECTED)
ScintillaSendMessage(0, #SCI_GOTOPOS, hdrLen)
SetActiveGadget(0)
BindGadgetEvent(0, @DoSciEvent())

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
End
Now I light up my cigar (can't wait to find more chars to delete - I mean, replace).

Ricardo
Nullius in verba.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: Scintilla not changeable text area

Post by eddy »

using scintilla UI notification

Code: Select all

EnableExplicit
InitScintilla()

#STYLE_PROTECTED=30
Define sciFont.s, hdr$, hdrLen, memBuffer

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

ProcedureDLL LockScintillaCB(Gadget, *scinotify.SCNotification)
   Shared hdrLen
   With *scinotify
      If \nmhdr\code=#SCN_UPDATEUI
         If \updated & #SC_UPDATE_CONTENT
            ;typing text
         EndIf
         If \updated & #SC_UPDATE_H_SCROLL
            ;scrolling
         EndIf
         If \updated & #SC_UPDATE_V_SCROLL
            ;scrolling
         EndIf
         If \updated & #SC_UPDATE_SELECTION
            ;selection changed
            Protected posNow=ScintillaSendMessage(0, #SCI_GETCURRENTPOS)
            If ScintillaSendMessage(0, #SCI_GETSTYLEAT, posNow)=#STYLE_PROTECTED
               ScintillaSendMessage(0, #SCI_GOTOPOS, hdrLen)
               MessageRequester("WARNING!", "Restricted area. Trespassers will be shot.")
            EndIf
         EndIf
      EndIf
   EndWith
EndProcedure

hdr$=""
hdr$ + "----------------------------------------" + #CR$
hdr$ + "----                                ----" + #CR$
hdr$ + "----    This is a protected area    ----" + #CR$
hdr$ + "----        (ma non troppo)         ----" + #CR$
hdr$ + "----                                ----" + #CR$
hdr$ + "----------------------------------------" + #CR$
hdrLen=StringByteLength(hdr$, #PB_UTF8)
sciFont="Courier New"
memBuffer=AllocateMemory(Len(sciFont) + 1)
PokeS(memBuffer, sciFont, -1, #PB_Ascii)

OpenWindow(0, 0, 0, 600, 700, "Block me lines!", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ScintillaGadget(0, 0, 0, WindowWidth(0), WindowHeight(0), @LockScintillaCB())
ScintillaSendMessage(0, #SCI_STYLESETFONT, #STYLE_DEFAULT, memBuffer)
ScintillaSendMessage(0, #SCI_SETWRAPMODE, #SC_WRAP_WHITESPACE)
ScintillaSendMessage(0, #SCI_SETCODEPAGE, #SC_CP_UTF8)
ScintillaSendMessage(0, #SCI_STYLESETBACK, #STYLE_PROTECTED, RGB($EE, $EE, $EE))
ScintillaSendMessage(0, #SCI_STYLESETCHANGEABLE, #STYLE_PROTECTED, 0)
ScintillaSendMessage(0, #SCI_SETTEXT, 0, MakeUTF8Text(hdr$))
ScintillaSendMessage(0, #SCI_STARTSTYLING, 0, $1F)
ScintillaSendMessage(0, #SCI_SETSTYLING, hdrLen, #STYLE_PROTECTED)
ScintillaSendMessage(0, #SCI_GOTOPOS, hdrLen)
SetActiveGadget(0)

Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
End
Last edited by eddy on Wed Dec 10, 2014 10:12 pm, edited 1 time in total.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
Vera
Addict
Addict
Posts: 858
Joined: Tue Aug 11, 2009 1:56 pm
Location: Essen (Germany)

Re: Scintilla not changeable text area

Post by Vera »

Hi rmenezes,

with a double-click on the block (will mark a line) and twice on any key ... your block is gone for good. :mrgreen:
... and anything one likes to write thereafter vanishes into the mist 8)

Tested on Linux ... so you might not mind ~ cheers Vera
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Scintilla not changeable text area

Post by davido »

Oddly, the right-click is not recognised on OSX. :?
DE AA EB
User avatar
rmenezes
User
User
Posts: 14
Joined: Sat Oct 11, 2014 11:28 pm

Re: Scintilla not changeable text area

Post by rmenezes »

Eddy's solution worked fine in 64w7. Will try on UX next.

BTW, @vera, generally it's the other way around in my case: it has to work on Linux first and then on Windows :)

Thanks guys. The next round's on me.

Ricardo
Nullius in verba.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: Scintilla not changeable text area

Post by eddy »

Code: Select all

[/b]
- Remark : \updated property is bit flag

Here is the correct way to test its value:
[code]         If \updated & #SC_UPDATE_CONTENT
            ;typing text
         EndIf
         If\updated & #SC_UPDATE_H_SCROLL
            ;scrolling 
         EndIf
         If\updated & #SC_UPDATE_V_SCROLL
            ;scrolling 
         EndIf
         If \updated & #SC_UPDATE_SELECTION
            ;selection changes
         EndIf
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
Post Reply