Hi guys! Is there any way to turn off the scroll bars in the EditorGadget? The inactive bars are displayed even when the text does not exceed the viewable window?
Thanks!
EditorGadget
Re: EditorGadget
Unfortunately it is not possible to turn off the scrollbars in the EditorGadget.coder14 wrote:Hi guys! Is there any way to turn off the scroll bars in the EditorGadget? The inactive bars are displayed even when the text does not exceed the viewable window?
The EditorGadget on the Mac is realized by embedding a TXN object in a
UserPane. Using the MLTE (Multilingual Text Engine Reference) function
TXNCreateObject() you have to specify at creation of the TXN object whether
you want to have vertical and/or horizontal scrollbars. PureBasic internally
seems to demand a vertical and horizontal scrollbar always as a default and
it is not possible to change this setting afterwards. But if you create the TXN
object yourself it is well possible to create an editor-like gadget with or
without scrollbars. The only drawback is that you can't use PB's Gadget
functions anymore to access your customized EditorGadget. You will have
to use API functions instead of the PB functions.
A simple example:
Code: Select all
ImportC ""
TXNAttachObjectToWindowRef(TXNObject.L, WindowRef.L)
TXNCreateObject(*FrameRect, FrameOptions.L, *TXNObject)
TXNFocus(TXNObject.L, BecomingFocused.L)
TXNSetData(TXNObject.L, DataType.L, *DataPtr, DataSize.L, StartOffset.L, EndOffset.L)
EndImport
#kTXNTextData = 'TEXT'
#kTXNWantHScrollBarBit = 2
#kTXNWantVScrollBarBit = 3
#kTXNWantHScrollBarMask = 1 << #kTXNWantHScrollBarBit
#kTXNWantVScrollBarMask = 1 << #kTXNWantVScrollBarBit
Define Text.S
For i = 1 To 5
Text + "Line " + Str(i) + #CR$
Next i
Procedure OpenEditorWindow(WindowID.L, TitleText.S, Text.S, x.L, y.L, Flags.L)
OpenWindow(WindowID, x, y, 270, 76, TitleText, #PB_Window_SystemMenu)
TXNCreateObject(0, Flags, @TXNObject)
TXNAttachObjectToWindowRef(TXNObject, WindowID(WindowID))
TXNSetData(TXNObject, #kTXNTextData, @Text, Len(Text) - 1, 0, 0)
ProcedureReturn TXNObject
EndProcedure
Editor0 = OpenEditorWindow(0, "Editor without scrollbars", Text, 100, 100, 0)
Editor1 = OpenEditorWindow(1, "Editor with horizontal scrollbar", Text, 200, 200, #kTXNWantHScrollBarMask)
Editor2 = OpenEditorWindow(2, "Editor with vertical scrollbar", Text, 300, 300, #kTXNWantVScrollBarMask)
TXNFocus(Editor2, #True)
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: EditorGadget
Clearly, you're the man! Thank you - just what I needed.Shardik wrote:But if you create the TXN object yourself it is well possible to create an editor-like gadget with or without scrollbars.
Re: EditorGadget
This is a workaround which demonstrates how to get text from an
EditorGadget created with API functions (without scrollbars) which
was selected by the user or how to obtain the whole text:
An alternative solution for an editor-like control without scrollbars
would be to use the simpler EditUnicodeTextControl:
EditorGadget created with API functions (without scrollbars) which
was selected by the user or how to obtain the whole text:
Code: Select all
EnableExplicit
ImportC ""
TXNAttachObjectToWindowRef(TXNObject.L, WindowRef.L)
TXNClear(TXNObject.L)
TXNCopy(TXNObject.L)
TXNCreateObject(*FrameRect, FrameOptions.L, *TXNObject)
TXNFocus(TXNObject.L, BecomingFocused.L)
TXNGetSelection(TXNObject.L, *StartOffset, *EndOffset)
TXNSelectAll(TXNObject.L)
TXNSetData(TXNObject.L, DataType.L, *DataPtr, DataSize.L, StartOffset.L, EndOffset.L)
TXNSetFrameBounds(TXNObject.L, Top.L, Left.L, Bottom.L, Right.L, FrameID.L)
TXNUpdate(TXNObject.L)
EndImport
#kTXNTextData = 'TEXT'
Structure HIRect
x.F
y.F
Width.F
Height.F
EndStructure
Procedure.S GetEditorText(TXNObject.L, SelectAll.L = #True)
Protected DataHandle.L
Protected EndOffset.L
Protected StartOffset.L
Protected Text.S
If SelectAll
TXNSelectAll(TXNObject)
EndIf
TXNGetSelection(TXNObject, @StartOffset, @EndOffset)
If StartOffset < EndOffset
TXNCopy(TXNObject)
Text = GetClipboardText()
EndIf
ProcedureReturn Text
EndProcedure
Define Bounds.HIRect
Define i.L
Define Text.S
Define TXNObject.L
For i = 1 To 5
Text + "Line " + Str(i) + #CR$
Next i
OpenWindow(0, 200, 100, 280, 140, "EditorGadget without scrollbars", #PB_Window_SystemMenu)
ButtonGadget(0, (WindowWidth(0) - 140) / 2, WindowHeight(0) - 50, 140, 20, "Display whole text")
ButtonGadget(1, (WindowWidth(0) - 150) / 2, WindowHeight(0) - 25, 150, 20, "Display selected text")
While WindowEvent()
Wend
Bounds\x = 5
Bounds\y = 5
Bounds\Width = WindowWidth(0) - 10
Bounds\Height = 80
TXNCreateObject(@Bounds, 0, @TXNObject)
TXNAttachObjectToWindowRef(TXNObject, WindowID(0))
TXNSetData(TXNObject, #kTXNTextData, @Text, Len(Text) - 1, 0, 0)
TXNSetFrameBounds(TXNObject, 5, 5, 80, WindowWidth(0) - 10, 0)
TXNUpdate(TXNObject)
TXNFocus(TXNObject, #True)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
If EventType() = #PB_EventType_LeftClick
Select EventGadget()
Case 0
Debug "Whole text: " + #DQUOTE$ + GetEditorText(TXNObject, #True) + #DQUOTE$
Case 1
Debug "Selected text: " + #DQUOTE$ + GetEditorText(TXNObject, #False) + #DQUOTE$
EndSelect
EndIf
EndSelect
ForEver
would be to use the simpler EditUnicodeTextControl:
Code: Select all
ImportC ""
CFRelease(CFTypeRef.L)
CFStringCreateWithCString(CFAllocatorRef.L, CString, CFStringEncoding.L)
CFStringGetCString(CFStringRef.L, *StringBuffer, BufferSize.L, CFStringEncoding.L)
CFStringGetLength(CFStringRef.L)
CreateEditUnicodeTextControl(WindowRef.L, *BoundsRect, CFStringText.L, IsPassword.L, *FontStyleRec, *ControlRef)
GetControlData(ControlRef.L, ControlPartCode.L, ControlKindTagName.L, BufferSize.L, *Buffer, *ActualSize)
SetControlData(ControlRef.L, ControlPartCode.L, ControlKindTagName.L, BufferSize.L, *Buffer)
SetKeyboardFocus(WindowRef.L, ControlRef.L, FocusPart.L)
EndImport
#kControlEditTextPart = 5
#kControlEditTextInsertCFStringRefTag = 'incf'
#kControlFocusNextPart = -1
Structure Rect
Top.W
Left.W
Bottom.W
Right.W
EndStructure
Procedure.S GetEditorText(EditControlRef)
Protected StringRef.L
Protected SelectedText.S
If GetControlData(EditControlRef, #kControlEditTextPart, #kControlEditTextInsertCFStringRefTag, SizeOf(StringRef), @StringRef, 0) = 0
If StringRef
SelectedText = Space(CFStringGetLength(StringRef) + 1)
CFStringGetCString(StringRef, @SelectedText, Len(SelectedText), 0)
CFRelease(StringRef)
EndIf
EndIf
ProcedureReturn SelectedText
EndProcedure
Procedure.S SetEditorText(EditControlRef, Text.S)
Protected StringRef.L
StringRef = CFStringCreateWithCString(0, @Text, 0)
If StringRef
SetControlData(EditControlRef, #kControlEditTextPart, #kControlEditTextInsertCFStringRefTag, SizeOf(StringRef), @StringRef)
CFRelease(StringRef)
EndIf
EndProcedure
Define Bounds.Rect
OpenWindow(0, 200, 100, 300, 93, "EditUnicodeTextControl", #PB_Window_SystemMenu)
ButtonGadget(0, (WindowWidth(0) - 150) / 2, WindowHeight(0) - 25, 150, 20, "Display selected text")
Bounds\Left = 10
Bounds\Top = 10
Bounds\Right = WindowWidth(0) - 10
Bounds\Bottom = WindowHeight(0) - 35
CreateEditUnicodeTextControl(WindowID(0), @Bounds, 0, #False, 0, @EditControlRef)
SetEditorText(EditControlRef, "Line 1" + #CR$ + "Line 2" + #CR$ + "Line 3")
SetKeyboardFocus(WindowID(0), EditControlRef, #kControlFocusNextPart)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
If EventGadget() = 0
Debug "Selected text: " + #DQUOTE$ + GetEditorText(EditControlRef) + #DQUOTE$
EndIf
EndSelect
ForEver
Re: EditorGadget
Thanks Shardik,
This is a complete solution with the ability to retrieve just the selected text (or all of the text)!
Very nice!
This is a complete solution with the ability to retrieve just the selected text (or all of the text)!
Very nice!
MacBook Pro-M1 (2021), Sonoma 14.4.1, PB 6.10LTS M1
Re: EditorGadget
Couple them with Shardik's earlier event handlers, and you have yourself a real alternative to the EditorGadget. Great work!
Re: EditorGadget
This is another more complicated example of creating an EditorGadget
without scrollbars using solely API functions. It demonstrates how to
change the font of selected text, how to read out the current contents
of the EditorGadget and how to discriminate between the text written in
different fonts. It would also be possible to change font size and style of
selected text in a similar way thus programming an own WYSIWYG editor:
without scrollbars using solely API functions. It demonstrates how to
change the font of selected text, how to read out the current contents
of the EditorGadget and how to discriminate between the text written in
different fonts. It would also be possible to change font size and style of
selected text in a similar way thus programming an own WYSIWYG editor:
Code: Select all
EnableExplicit
ImportC ""
ATSUFindFontFromName(*FontName, FontNameLength.L, FontNameCode.L, FontNamePlatform.L, FontNameScript.L, FontNameLanguage.L, *ATSUIFontID)
TXNAttachObjectToWindowRef(TXNObject.L, WindowRef.L)
TXNCountRunsInRange(TXNObject.L, StartOffset.L, EndOffset.L, *RunCount)
TXNCreateObject(*FrameRect, FrameOptions.L, *TXNObject)
TXNFocus(TXNObject.L, BecomingFocused.L)
TXNGetData(TXNObject.L, StartOffset.L, EndOffset.L, *DataHandle)
TXNGetIndexedRunInfoFromRange(TXNObject.L, RunIndex.L, StartOffset.L, EndOffset.L, *RunStartOffset, *RunEndOffset, *RunDataType, FontAttributeCount.L, *TypeAttributes)
TXNGetSelection(TXNObject.L, *StartOffset, *EndOffset)
TXNSelectAll(TXNObject.L)
TXNSetData(TXNObject.L, DataType.L, *DataPtr, DataSize.L, StartOffset.L, EndOffset.L)
TXNSetFrameBounds(TXNObject.L, Top.L, Left.L, Bottom.L, Right.L, FrameID.L)
TXNSetSelection(TXNObject.L, StartOffset.L, EndOffset.L)
TXNSetTXNObjectControls(TXNObject.L, ClearAll.L, ControlCount.L, ControlTags.L, ControlData.L)
TXNSetTypeAttributes(TXNObject.L, AttributeCount.L, TXNTypeAttributes.L, StartOffset.L, EndOffset.L)
TXNUpdate(TXNObject.L)
EndImport
#kATSUFontTag = 261
#kFontFullName = 4
#kFontNoLanguage = -1
#kFontNoPlatform = -1
#kFontNoScript = -1
#kTXNEndOffset = $7FFFFFFF
#kTXNTextData = 'TEXT'
Structure AttributeData
StructureUnion
DataPtr.L
DataValue.L
ATSUFeatures.L
ATSUVariations.L
URLRef.L
EndStructureUnion
EndStructure
Structure TXNTypeAttributes
TXTNTag.L
TXNAttributeSize.L
TXNAttributeData.AttributeData
EndStructure
Structure HIRect
x.F
y.F
Width.F
Height.F
EndStructure
Procedure.L ChangeFont(TXNObject.L, FontName.S)
Protected EndOffset.L
Protected FontID.L
Protected StartOffset.L
Protected Dim TypeAttributes.TXNTypeAttributes(0)
If ATSUFindFontFromName(@FontName, Len(FontName), #kFontFullName, #kFontNoPlatform, #kFontNoScript, #kFontNoLanguage, @FontID) = 0
; ----- Select "Line 3"
StartOffset = 14
EndOffset = 20
TXNSetSelection(TXNObject, StartOffset, EndOffset)
; ----- Change font of "Line 3"
TypeAttributes(0)\TXTNTag = #kATSUFontTag
TypeAttributes(0)\TXNAttributeSize = SizeOf(FontID)
TypeAttributes(0)\TXNAttributeData\DataValue = FontID
TXNSetTypeAttributes(TXNObject, 1, @TypeAttributes(0), StartOffset, EndOffset)
TXNSetSelection(TXNObject, #kTXNEndOffset, #kTXNEndOffset)
ProcedureReturn FontID
EndIf
EndProcedure
Procedure.S GetEditorText(TXNObject.L, FontID.L)
Protected CustomFontText.S
Protected DataHandle.L
Protected DefaultFontText.S
Protected EndOffset.L
Protected i.L
Protected RunCount.L
Protected RunDataType.L
Protected RunEndOffset.L
Protected RunStartOffset.L
Protected StartOffset.L
Protected Text.S
Protected Dim TypeAttributes.TXNTypeAttributes(0)
TypeAttributes(0)\TXTNTag = #kATSUFontTag
TypeAttributes(0)\TXNAttributeSize = SizeOf(FontID)
TypeAttributes(0)\TXNAttributeData\DataValue = #Null
TXNSelectAll(TXNObject)
TXNGetSelection(TXNObject, @StartOffset, @EndOffset)
If StartOffset < EndOffset
If TXNCountRunsInRange(TXNObject, StartOffset, EndOffset, @RunCount) = 0
For i = 0 To RunCount - 1
If TXNGetIndexedRunInfoFromRange(TXNObject, i, StartOffset, EndOffset, @RunStartOffset, @RunEndOffset, @RunDataType, 1, @TypeAttributes(0)) = 0
If TXNGetData(TXNObject, RunStartOffset, RunEndOffset, @DataHandle) = 0
Text = PeekS(PeekL(DataHandle), RunEndOffset - RunStartOffset, #PB_Unicode)
If TypeAttributes(0)\TXNAttributeData\DataValue = FontID
CustomFontText + Text
Else
DefaultFontText + Text
EndIf
EndIf
EndIf
Next i
EndIf
EndIf
TXNSetSelection(TXNObject, #kTXNEndOffset, #kTXNEndOffset)
Text = "Text in default font:" + #CR$ + DefaultFontText + #CR$ + #CR$
Text + "Text in font Apple Chancery:" + #CR$ + CustomFontText
ProcedureReturn Text
EndProcedure
Define Bounds.HIRect
Define FontID.L
Define i.L
Define Text.S
Define TXNObject.L
For i = 1 To 5
Text + "Line " + Str(i) + #CR$
Next i
OpenWindow(0, 200, 100, 420, 115, "Get text of MLTE TextObject containing different fonts", #PB_Window_SystemMenu)
ButtonGadget(0, (WindowWidth(0) - 370) / 2, WindowHeight(0) - 25, 370, 20, "Change font of 3rd line to Apple Chancery and get text", #PB_Button_MultiLine)
While WindowEvent()
Wend
Bounds\x = 5
Bounds\y = 5
Bounds\Width = WindowWidth(0) - 10
Bounds\Height = 80
TXNCreateObject(@Bounds, 0, @TXNObject)
TXNAttachObjectToWindowRef(TXNObject, WindowID(0))
TXNSetData(TXNObject, #kTXNTextData, @Text, Len(Text) - 1, 0, 0)
TXNSetFrameBounds(TXNObject, 5, 5, 80, WindowWidth(0) - 10, 0)
TXNUpdate(TXNObject)
TXNFocus(TXNObject, #True)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
If EventType() = #PB_EventType_LeftClick
If EventGadget() = 0
DisableGadget(0, #True)
FontID = ChangeFont(TXNObject, "Apple Chancery")
MessageRequester("Editor contents info", GetEditorText(TXNObject, FontID))
EndIf
EndIf
EndSelect
ForEver
Re: EditorGadget
Thanks shardik!
Now that we have some new features in the Editor gadget (by API) I'd like to see them incorporated into PureBasic...
Maybe after the summer break.
Now that we have some new features in the Editor gadget (by API) I'd like to see them incorporated into PureBasic...
Maybe after the summer break.
MacBook Pro-M1 (2021), Sonoma 14.4.1, PB 6.10LTS M1