Scroll to last line - EditorGadget

Mac OSX specific forum
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Scroll to last line - EditorGadget

Post by dhouston »

My application has a large EditorGadget on its main window that reports all inputs/outputs with the embedded device it connects to. The EditorGadget does not scroll automatically to the last line as it does under Windows. I had the same problem under Linux but solved it with a few gtk functions. The Linux fix does not work under OSX - it doesn't recognize the gtk functions. Here's my Linux code...

Code: Select all

Procedure ScrollToEnd(gadget)                          ;scrolls text window to last line
  Protected end_mark,*buffer, end_iter.GtkTextIter
  *buffer=gtk_text_view_get_buffer_(GadgetID(gadget))
  gtk_text_buffer_get_end_iter_(*buffer,@end_iter)
  end_mark=gtk_text_buffer_create_mark_(*buffer,"end_mark",@end_iter,#False)
  gtk_text_view_scroll_mark_onscreen_(GadgetID(gadget),end_mark)
EndProcedure
It is called whenever there is fresh input.

Can anyone suggest a fix for OSX?
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Scroll to last line - EditorGadget

Post by Shardik »

I currently don't know a MacOS API solution, but if you know how many lines are
displayed inside your EditorGadget (for example by means of a counter), you may
simply use

Code: Select all

LastLineContent = GetGadgetItemText(GadgetID, LastLine)
to read the last line and write the last line back unchanged with

Code: Select all

SetGagdetItemText(GadgetID, LastLine, LastLineContent)
to position the last line as the last visible line at the bottom of the EditorGadget.

This approach is not very elegant but should even work crossplatform:

Code: Select all

OpenWindow(0, 0, 0, 310, 170, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
EditorGadget(0, 5, 5, WindowWidth(0) - 10, WindowHeight(0) - 30) 
ButtonGadget(1, (WindowWidth(0) - 150) / 2 , WindowHeight(0) - 25, 150, 20, "Scroll to last line")

For i = 0 To 25 
  AddGadgetItem(0, i, "Line "+Str(i)) 
Next 

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 1
        SetGadgetItemText(0, 25, GetGadgetItemText(0, 25))
      EndIf
  EndSelect
ForEver
Update: Sorry, but the crossplatform assumption was wrong. This approach only works
for MacOS X but not for Windows or Linux.
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Re: Scroll to last line - EditorGadget

Post by dhouston »

Shardik wrote:This approach is not very elegant but should even work crossplatform:
Somehow, I missed this when it was posted. I agree about the lack of elegance but, if it solves my problem, I'm grateful. I already check the number of lines and delete (from the start) to keep it from getting too large and consuming memory. (The embedded device runs 24/7 and the output can become lengthy. There's a user option to log all output to a file.) I'll try this tomorrow and let you know.
Update: Sorry, but the crossplatform assumption was wrong. This approach only works for MacOS X but not for Windows or Linux.
That's OK - I already have solutions for Linux & Windows.
freak
PureBasic Team
PureBasic Team
Posts: 5929
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: Scroll to last line - EditorGadget

Post by freak »

Code: Select all


#noErr = 0

#kTXNScrollUnitsInPixels = 0
#kTXNScrollUnitsInLines = 1
#kTXNScrollUnitsInViewRects = 2

ImportC ""
  GetControlProperty(control, propertyCreator, propertyTag, bufferSize, *actualSize, *propertyBuffer)
  TXNScroll(iTXNObject, iVerticalScrollUnit, iHorizontalScrollUnit, *ioVerticalDelta, *ioHorizontalDelta)
EndImport

Procedure ScrollToEnd(gadget)
  Protected TextObject, h, v
  
  ; This gets the PB internal pointer to the text object. This may break in the future
  ;
  If GetControlProperty(GadgetID(gadget), 'PURE', 'TXOB', 4, #Null, @TextObject) = #noErr 
    ;
    ; Scrolling in amount of lines does not work here, just use a very large pixel value instead
    ;
    v = 999999
    h = -99999 ; scroll back to the beginning, put 0 here to leave horizontal scrolling unchanged
    TXNScroll(TextObject, #kTXNScrollUnitsInPixels, #kTXNScrollUnitsInPixels, @v, @h)
  EndIf
EndProcedure


OpenWindow(0, 0, 0, 310, 170, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
EditorGadget(0, 5, 5, WindowWidth(0) - 10, WindowHeight(0) - 30)
ButtonGadget(1, (WindowWidth(0) - 150) / 2 , WindowHeight(0) - 25, 150, 20, "Scroll to last line")

For i = 0 To 25
  AddGadgetItem(0, i, "Line "+Str(i))
Next

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      ScrollToEnd(0)
  EndSelect
ForEver
quidquid Latine dictum sit altum videtur
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Scroll to last line - EditorGadget

Post by Shardik »

@freak,

Thank you very much for your API solution, Timo. Yesterday I wasted half a day
trying to get GetControlProperty() to work because I didn't embed the tags in single
quotes like 'PURE' but used instead @"PURE" which didn't work. For my first bigger
crossplatform application (Windows, Linux and MacOS X) I need word wrap for the
EditorGadget. Because of your above code example I was able to post a solution:
http://www.purebasic.fr/english/viewtop ... 38&start=3
User avatar
dhouston
Enthusiast
Enthusiast
Posts: 430
Joined: Tue Aug 21, 2007 2:44 pm
Location: USA (Cincinnati)
Contact:

Re: Scroll to last line - EditorGadget

Post by dhouston »

@freak,

That is superb. Thank you.

While I still have a little PB code (as well as some code for the embedded device) and documentation to write and/or update, I now have my app running under Windows, Linux and OSX.

I have tried most of the cross-platform Basic compilers as they became available (beginning with Zedcor's ZBasic in the mid-'80s) and PB is the first that I can recommend to others.

Edit: For those unfamiliar with ZBasic...Ironically, the embedded device I am interfacing with uses the latest reincarnation of ZBasic, a ZX-40P from Elba, Corp. programmed in their ZBasic which is probably a little more sophisticated than Zedcor's original incarnation. Linux first appeared about the time Zedcor sold off the MS-DOS version (1991) so there was no Linux version.
User_Russian
Addict
Addict
Posts: 1443
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: Scroll to last line - EditorGadget

Post by User_Russian »

Doesn't work in 5.73.
GetControlProperty does not return #noErr.
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Scroll to last line - EditorGadget

Post by Shardik »

User_Russian wrote:Doesn't work in 5.73.
GetControlProperty does not return #noErr.
The examples in this thread from 2010 are still for the Carbon framework (GetControlProperty() is a Carbon function). In 2012 PureBasic changed to the Cocoa framework. Therefore you should try this example from wilbert. If you want to display a scrolling list in an EditorGadget and want to always keep the last line visible you may take a look into this example.
User_Russian
Addict
Addict
Posts: 1443
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: Scroll to last line - EditorGadget

Post by User_Russian »

Works great. Thank.
Post Reply