How Syncronize scroll in two gadgets?

Just starting out? Need help? Post your questions and find answers here.
chen
Enthusiast
Enthusiast
Posts: 338
Joined: Fri Dec 23, 2005 2:20 pm
Location: Quebec, Canada
Contact:

How Syncronize scroll in two gadgets?

Post by chen »

Hi,

Is there a way to syncronize vertical scrolling in two gadgets?

Im trying to manage 2 editorGadgets, one of them contains data and
the other one row numbers... thats the idea.

The editorGadgets showing the number has a hidden vertical scroll bar,
I get this placing this gadget in a ContainerGadget.

The second Editor contains the data and its vertical scroll bar is visible..
I want using this bar to syncronize the up-down movement using only
this scroll bar....

Code: Select all

If OpenWindow(0, 0, 0, 322, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
     
    ContainerGadget(2,5,5,50,133)
      EditorGadget(0, 5, 5, 65, 133)
    CloseGadgetList()
    EditorGadget(1, 60, 10, 250, 133)
    For a = 0 To 20 
      AddGadgetItem(0, a, Str(a)) 
      AddGadgetItem(1, a, "Line "+Str(a))
    Next 
    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 
  EndIf 
Help required... thanks
Xombie
Addict
Addict
Posts: 898
Joined: Thu Jul 01, 2004 2:51 am
Location: Tacoma, WA
Contact:

Post by Xombie »

You mean like ...

Code: Select all

EnableExplicit
;
Define.l HoldEvent, a, HoldLine, CurrentLine, lResult
;
Define.b DoQuit
;
If OpenWindow(0, 0, 0, 322, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
   ContainerGadget(2,5,5,50,133) 
      EditorGadget(0, 5, 5, 65, 133) 
   CloseGadgetList() 
   EditorGadget(1, 60, 10, 250, 133) 
   For a = 0 To 20 
      AddGadgetItem(0, a, Str(a)) 
      AddGadgetItem(1, a, "Line "+Str(a)) 
   Next
   ;
   Repeat
      ;
      HoldEvent = WaitWindowEvent()
      ;
      If HoldEvent = #PB_Event_CloseWindow
         ; Close the program.
         DoQuit = #True
         ;
      ElseIf HoldEvent = #PB_Event_Gadget
         ;
         If EventGadget() = 1
            ;
            If EventType() = 1024
               ;
               HoldLine = SendMessage_(GadgetID(1), #EM_GETFIRSTVISIBLELINE, 0, 0)
               ;
               CurrentLine = SendMessage_(GadgetID(0), #EM_GETFIRSTVISIBLELINE, 0, 0)
               ; 
               lResult = SendMessage_(GadgetID(0), #EM_LINESCROLL, 0, HoldLine - CurrentLine)
               ;
            EndIf
            ;
         EndIf
         ;
      EndIf
      ;
   Until DoQuit
   ;
EndIf
;-
End
;-
... that?

EDIT: Incidentally, you can use...

Code: Select all

ShowScrollbar_(GadgetID(1), #SB_BOTH, #False)
... to turn off a control's scrollbar rather than using the container.
chen
Enthusiast
Enthusiast
Posts: 338
Joined: Fri Dec 23, 2005 2:20 pm
Location: Quebec, Canada
Contact:

Post by chen »

Yes, Like that...

One question?... Is there a way to do it without API or is the only way?

Thanks Xombie
Xombie
Addict
Addict
Posts: 898
Joined: Thu Jul 01, 2004 2:51 am
Location: Tacoma, WA
Contact:

Post by Xombie »

Hmmm... not that I see. Maybe Fred could add it to the SetGadgetAttribute() and add something like a "#PB_Editor_LineNumber" constant?
chen
Enthusiast
Enthusiast
Posts: 338
Joined: Fri Dec 23, 2005 2:20 pm
Location: Quebec, Canada
Contact:

Post by chen »

Ok...
Im testing your code and I see this:

If you scroll down line by line the line number are sincronized with the data
But?
If you advance by page there are no one-one relation.... for example

65 point to line 66

Code: Select all

EnableExplicit
;
Define.l HoldEvent, a, HoldLine, CurrentLine, lResult
;
Define.b DoQuit
;
If OpenWindow(0, 0, 0, 322, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
  ContainerGadget(2,5,5,50,138)
    EditorGadget(0, 5, 5, 65, 140)
  CloseGadgetList()
  EditorGadget(1, 60, 10, 250, 133)
  For a = 0 To 1000
    AddGadgetItem(0, a, Str(a))
    AddGadgetItem(1, a, "Line "+Str(a))
  Next
  ;
  Repeat
    ;
    HoldEvent = WaitWindowEvent()
    ;
    If HoldEvent = #PB_Event_CloseWindow
      ; Close the program.
      DoQuit = #True
      ;
    ElseIf HoldEvent = #PB_Event_Gadget
      ;
      If EventGadget() = 1
        ;
        If EventType() = 1024
          ;
          HoldLine = SendMessage_(GadgetID(1), #EM_GETFIRSTVISIBLELINE, 0, 0)
          ;
          CurrentLine = SendMessage_(GadgetID(0), #EM_GETFIRSTVISIBLELINE, 0, 0)
          ;
          lResult = SendMessage_(GadgetID(0), #EM_LINESCROLL, 0, HoldLine - CurrentLine)
          ;
        EndIf
        ;
      EndIf
      ;
    EndIf
    ;
  Until DoQuit
  ;
EndIf
;-
End
;-
DO I need to consider something else...?

Anyway Im going to try by myself.... thanks indeed...
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Here's another way which synchronises even when dragging the thumb:

Code: Select all

Global oldproc

Procedure WindowCallback(hWnd, uMsg, wParam, lParam)
  Protected topitem, currentitem
    Result = CallWindowProc_(oldproc, hWnd, uMsg, wParam, lParam)
    Select uMsg
      Case #WM_VSCROLL
        SendMessage_(GadgetID(0), #WM_VSCROLL, wParam, lParam)
      Case #WM_KEYUP, #WM_KEYDOWN
        topitem = SendMessage_(GadgetID(1),#EM_GETFIRSTVISIBLELINE,0,0)
        currentitem = SendMessage_(GadgetID(0),#EM_GETFIRSTVISIBLELINE,0,0)
        If topitem-currentitem
          SendMessage_(GadgetID(1),#EM_LINESCROLL,0,0) ;Just for alignment!
          SendMessage_(GadgetID(0),#EM_LINESCROLL,0,topitem-currentitem)
        EndIf
    EndSelect
  ProcedureReturn Result
EndProcedure


If OpenWindow(0, 0, 0, 322, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
    ContainerGadget(2,5,5,50,133) 
      EditorGadget(0, 5, 5, 65, 133) 
    CloseGadgetList() 
    EditorGadget(1, 60, 10, 250, 133) 
    For a = 0 To 200 
      AddGadgetItem(0, a, Str(a)) 
      AddGadgetItem(1, a, "Line "+Str(a)) 
    Next 
    oldproc=SetWindowLong_(GadgetID(1), #GWL_WNDPROC, @WindowCallback())
    Repeat
    ev=WaitWindowEvent()
    Until ev = #PB_Event_CloseWindow 
EndIf 
Incidentally, Sparkie posted some code which automatically placed line numbers in an editor gadget. That is, you do not need a second editor gadget etc.
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Dammit Srod!! where you buying your holster oil? [edit] Ha - tweaked my code to be 4 lines shorter than yours! :twisted:

Code: Select all

Procedure Callback(hwnd, msg, wparam, lparam) 
  result = #PB_ProcessPureBasicEvents 
  If msg=#WM_COMMAND 
    If IsGadget(1) 
      If lparam = GadgetID(1) 
        If wparam >> 16 = 1024 ; EN_UPDATE 
          SendMessage_(GadgetID(1), #EM_GETSCROLLPOS, 0, @pt.point) 
          SendMessage_(GadgetID(0), #EM_SETSCROLLPOS, 0, @pt) 
        EndIf 
      EndIf 
    EndIf 
    result = 0 
  EndIf 
  ProcedureReturn result 
EndProcedure 

If OpenWindow(0, 0, 0, 322, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  SetWindowCallback(@Callback()) 
   ContainerGadget(2,5,5,50,133) 
      EditorGadget(0, 5, 5, 65, 133) 
   CloseGadgetList() 
   EditorGadget(1, 60, 10, 250, 133) 
   For a = 0 To 20 
      AddGadgetItem(0, a, Str(a)) 
      AddGadgetItem(1, a, "Line "+Str(a)) 
   Next 
   Repeat : Until WaitWindowEvent()=#WM_CLOSE 
EndIf 
End
Last edited by netmaestro on Wed Aug 09, 2006 12:33 am, edited 2 times in total.
BERESHEIT
Xombie
Addict
Addict
Posts: 898
Joined: Thu Jul 01, 2004 2:51 am
Location: Tacoma, WA
Contact:

Post by Xombie »

chen wrote:Ok...
Im testing your code and I see this:

If you scroll down line by line the line number are sincronized with the data
But?
If you advance by page there are no one-one relation.... for example

65 point to line 66

Code: Select all

< snip snip >
DO I need to consider something else...?

Anyway Im going to try by myself.... thanks indeed...
It's checking the first visible line item and including anything that's even partially visible. Using a callback and checking for the scroll message rather than watching the line number of the edit control is much better - a la srod's code. That way they match exactly and you aren't constrained by PB's limitation of not providing events while moving the little scrollbar itself.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I like your code netmaestro. Pretty slick! :)

Which notification message corresponds to 1024?
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Gotcha srod - my code works with the mousewheel and yours doesnt :D :D :D
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Pah, who needs a mousewheel? :lol:
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

1024 is #EN_UPDATE:
MSDN wrote:The EN_UPDATE notification message is sent when an edit control is about to redraw itself.
Sorry, I really should have used the constant instead of the value, it would've been easier to read. I'm bad for that. :oops:
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Yep, your's is definitely the best way. Very nice.
I may look like a mule, but I'm not a complete ass.
chen
Enthusiast
Enthusiast
Posts: 338
Joined: Fri Dec 23, 2005 2:20 pm
Location: Quebec, Canada
Contact:

Post by chen »

Battle at the top :wink:

Help a lot thanks.....
RegisLG
New User
New User
Posts: 3
Joined: Mon Jul 04, 2005 4:16 pm
Location: France

Post by RegisLG »

In my program i have the EnableExplicit activated.
I wanted to use netmastro's code, but i need to know the variable declation i must write in the procedure.

Can someone help me please ?
Post Reply