Editor - once again about word wrap

Just starting out? Need help? Post your questions and find answers here.
ZX80
Enthusiast
Enthusiast
Posts: 394
Joined: Mon Dec 12, 2016 1:37 pm

Editor - once again about word wrap

Post by ZX80 »

Hello everyone.

The user asks to limit the number of characters in a line, but we only have what the OS offers (#PB_Editor_WordWrap). Unfortunately, this option is not suitable. I wish I could have this in real time ("on the fly"). For this I used the Axolotl code as a basis. But this is not as simple as it may seem at first glance. If anyone has time and desire, could you help me with this ?

This is my most primitive logic, which doesn’t work at all.

Code: Select all

Global col, row, old, lim = 9

Define evMask, i


Procedure Callback(hWnd, uMsg, wParam, lParam)
  Protected result
  Protected *msgf.MSGFILTER
  Protected POINT.POINT
  Protected char
  Protected lineindex
  Protected colindex
  ;Protected col
  ;Protected row
  
  Result = #PB_ProcessPureBasicEvents
  Select uMsg
      
    Case #WM_NOTIFY
      *msgf=lParam
      Select *msgf\NMHDR\code
        Case #EN_MSGFILTER   
          Select *msgf\msg
            Case #WM_LBUTTONUP, #WM_KEYDOWN
              GetCaretPos_(@POINT)
              char = SendMessage_(GadgetID(1), #EM_CHARFROMPOS, 0, @POINT)
              lineindex = SendMessage_(GadgetID(1), #EM_LINEFROMCHAR, char, 0)
              colindex = SendMessage_(GadgetID(1), #EM_LINEINDEX, lineindex, 0)
              col = char-colindex
              row = lineindex + 1

              Debug "(" + Str(col) + ", " + Str(row) + ")"
          EndSelect
      EndSelect
  EndSelect
  ProcedureReturn Result
EndProcedure

Procedure WndProc(hWnd, uMsg, wParam, lParam)
  Protected bs = #False, char = #False
  
  If uMsg = #WM_KEYDOWN
    If wParam >= 32 And wParam <= 125
      char = #True
    EndIf

    If wParam = #VK_BACK
      bs = #True
      If col = 0
        Debug "DEL STR / calculate position"
        col = Len(GetGadgetItemText(1, row-1))
      EndIf
    EndIf
    
    If col >= lim
      Debug "Character limit exceeded"
      If bs = #False And char = #True
        Debug "Set the carriage on a new line"
        AddGadgetItem(1, -1, "")
      EndIf
    EndIf

  EndIf
  
  ProcedureReturn CallWindowProc_(old, hWnd, uMsg, wParam, lParam)
EndProcedure



If OpenWindow(0, 0, 0, 550, 300, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If LoadFont(0, "consolas", 12)
    SetGadgetFont(#PB_Default, FontID(0))
  EndIf
  
  eWnd = EditorGadget(1, 10, 10, WindowWidth(0)-20, WindowHeight(0)-20);, #PB_Editor_WordWrap)
  SetActiveGadget(1) ;Focus auf den Editor
  
  evMask = SendMessage_(GadgetID(1), #EM_GETEVENTMASK, 0, 0)
  SendMessage_(eWnd, #EM_SETEVENTMASK, 0, evMask | #ENM_KEYEVENTS | #ENM_MOUSEEVENTS )
  SetWindowCallback(@Callback())
  
  old = SetWindowLongPtr_(eWnd, #GWLP_WNDPROC, @WndProc())

  AddWindowTimer(0, 1, 10)     ; Second solution 
  
  Repeat 
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        End
      Case #PB_Event_Timer  
        If EventTimer() = 1 
          If i < 40 
            SetGadgetText(1,GetGadgetText(1)+Str(i)+",")    
            i + 1 
          Else 
            RemoveWindowTimer(0, 1)
            AddGadgetItem(1, -1, "Abcdefghijk12345")
            col = Len(GetGadgetItemText(1, CountGadgetItems(1)-1))
          EndIf 
        EndIf 

    EndSelect
  ForEver
  RemoveWindowTimer(0, 1) 


EndIf
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 5022
Joined: Sun Apr 12, 2009 6:27 am

Re: Editor - once again about word wrap

Post by RASHAD »

Maybe

Code: Select all

Global oldprocedure

Procedure editorGadgetCB(hwnd, uMsg, wParam, lParam)
  If uMsg = #WM_CHAR
    If wParam <> #VK_BACK
      If Len(GetGadgetText(0))%30 = 29
        keybd_event_(#VK_RETURN,0,0,0)
        keybd_event_(#VK_RETURN,0,#KEYEVENTF_KEYUP,0)
      EndIf
    EndIf
 
  EndIf
  ProcedureReturn CallWindowProc_(oldprocedure, hwnd, uMsg, wParam, lParam)
EndProcedure
 
OpenWindow(0, 0, 0, 300, 300, "30 char limit per line", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
EditorGadget(0, 5, 5, 290, 290, #ES_MULTILINE)
 
oldprocedure = SetWindowLongPtr_(GadgetID(0), #GWL_WNDPROC, @editorGadgetCB())
Repeat
  Select WaitWindowEvent(1)
    Case #PB_Event_CloseWindow
      Quit = 1
  EndSelect
Until Quit = 1
Egypt my love
ZX80
Enthusiast
Enthusiast
Posts: 394
Joined: Mon Dec 12, 2016 1:37 pm

Re: Editor - once again about word wrap

Post by ZX80 »

Hello, RASHAD.

Thank you for your attempt. Unfortunately, this is not handled as a gadget with the #PB_Editor_WordWrap flag. This flag doesn't do the main thing I need, which is to limit the number of characters in a line. Indenting is not the way to go (margins). I added part of Axolotl code to give a visual indication of when it's time for "Line Feed". The user wants this to be automatic. :(
Select all the text in the editor and format it according to the conditions. Yes, this is an additional action (for user). This is probably the last thing I can do here.

I can't even imagine the logic of how this could be done. Use a dummy invisible gadget ? In my opinion, this will greatly complicate the algorithm. I also look at StringGadget with multiline input support. The problem is that in certain cases I also use coloring of incorrect letters in the editor. StringGadget probably can't do this.

Sorry if I didn't explain the problem well.

In other words, I was originally planning on using EditorGadget, but this extra requirement with the character limit... ruins it.
Post Reply