Get number of lines in EditorGadget (cross-platform)
Posted: Sun Dec 21, 2014 12:42 pm
The following example demonstrates how to get the number of lines currently contained in an EditorGadget (works also with flag #PB_Editor_WordWrap set and counts even the lines in a currently invisible part of the EditorGadget which need moving the scroll bar to become visible). In Windows it's quite easy by simply using
But in Linux and MacOS it's much more difficult needing a bunch of API functions, so that I have put together the following true cross-platform example:
Code: Select all
CountGadgetItems(EditorGadgetID)
Code: Select all
EnableExplicit
#Text = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam " +
"nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, " +
"sed diam voluptua. At vero eos et accusam et justo duo dolores et ea " +
"rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum " +
"dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, " +
"sed diam nonumy eirmod tempor invidunt ut labor."
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Procedure.I GetLineHeight(EditorGadgetID.I)
Protected Dictionary.I
Protected Font.I
Protected i.I
Protected KeyArray.I
Protected KeyName.I
Protected LineHeight.CGFloat
Dictionary = CocoaMessage(0, GadgetID(EditorGadgetID), "typingAttributes")
KeyArray = CocoaMessage(0, Dictionary, "allKeys")
For i = 0 To CocoaMessage(0, KeyArray, "count") - 1
KeyName = CocoaMessage(0, KeyArray, "objectAtIndex:", i)
If PeekS(CocoaMessage(0, KeyName, "UTF8String"), -1, #PB_UTF8) = "NSFont"
Font = CocoaMessage(0, Dictionary, "objectForKey:", KeyName)
If Font
CocoaMessage(@LineHeight, CocoaMessage(0, GadgetID(EditorGadgetID),
"layoutManager"), "defaultLineHeightForFont:", Font)
EndIf
Break
EndIf
Next i
ProcedureReturn Int(LineHeight)
EndProcedure
CompilerEndIf
Procedure.I GetLineCount(WindowID.I, EditorGadgetID.I)
Protected LineCount.I
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
Protected LineHeight.I
Protected TextBlockHeight.I
Protected TextIter.GtkTextIter
Protected TextView.I = GadgetID(EditorGadgetID)
Protected y.I
; ----- Get height of a single text line for font used in EditorGadget
If StartDrawing(WindowOutput(WindowID))
DrawingFont(GetGadgetFont(EditorGadgetID))
LineHeight = TextHeight("Test")
StopDrawing()
EndIf
; ----- Get height of complete wrapped text block in EditorGadget
gtk_text_view_get_line_at_y_(TextView, @TextIter, GadgetY(EditorGadgetID), 0)
gtk_text_view_get_line_yrange_(TextView, @TextIter, @y, @TextBlockHeight)
; ----- Calculate number of lines (also invisible ones)
LineCount = TextBlockHeight / LineHeight
CompilerCase #PB_OS_MacOS
Protected LineHeight.I
Protected Rect.NSRect
Protected TextBlockHeight.I
; ----- Get height of complete wrapped text block in EditorGadget
CocoaMessage(@Rect, CocoaMessage(0, GadgetID(EditorGadgetID),
"layoutManager"), "usedRectForTextContainer:", CocoaMessage(0,
GadgetID(EditorGadgetID), "textContainer"))
; ----- Calculate number of lines (also invisible ones)
LineCount = Int(Rect\size\height) / GetLineHeight(EditorGadgetID)
CompilerCase #PB_OS_Windows
LineCount = CountGadgetItems(EditorGadgetID)
CompilerEndSelect
ProcedureReturn LineCount
EndProcedure
OpenWindow(0, 200, 100, 300, 400, "EditorGadget")
EditorGadget(0, 5, 5, WindowWidth(0) - 10, WindowHeight(0) - 10,
#PB_Editor_WordWrap)
; ----- Workaround for Linux bug in flag #PB_Editor_WordWrap
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
gtk_text_view_set_wrap_mode_(GadgetID(0), #GTK_WRAP_WORD)
CompilerEndIf
SetGadgetFont(0, LoadFont(0, "Arial", 15))
SetGadgetText(0, #Text)
; ----- Wait until text is displayed (Necessary on Linux and MacOS!)
While WindowEvent() : Wend
MessageRequester("Info", "Number of lines in EditorGadget: " + GetLineCount(0, 0))
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow