Setting wordwrap to auto in editor gadget

Mac OSX specific forum
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Setting wordwrap to auto in editor gadget

Post by Shardik »

This is a working solution for enabling word wrap (Mac OS X Snow Leopard and PB 4.50):

Code: Select all

ImportC ""
  GetControlProperty(Control, PropertyCreator, PropertyTag, BufferSize, *ActualSize, *PropertyBuffer)
  TXNSetTXNObjectControls(TXNObject, ClearAll, ControlCount, ControlTags, ControlData)
EndImport

#noErr = 0

Dim ControlTag.L(0)
Dim ControlData.L(0)

OpenWindow(0, 50, 100, 450, 100, "MacOS X Word Wrap Test", #PB_Window_SystemMenu)
EditorGadget(0, 10, 10, 430, 80)

Result = GetControlProperty(GadgetID(0), 'PURE', 'TXOB', 4, 0, @TXNObject)

If Result = #noErr
  ControlTag(0) = 'wwrs' ; kTXNWordWrapStateTag
  ControlData(0) = 0     ; kTXNAutoWrap
  TXNSetTXNObjectControls(TXNObject, #False, 1, @ControlTag(0), @ControlData(0))
EndIf

For i = 1 To 5
  Text$ = Text$ + "This is a word wrap test - "
Next i

SetGadgetText(0, Text$)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
jamirokwai
Enthusiast
Enthusiast
Posts: 796
Joined: Tue May 20, 2008 2:12 am
Location: Cologne, Germany
Contact:

Re: Setting wordwrap to auto in editor gadget

Post by jamirokwai »

Hiya,

as the snippet above is not Unicode-safe, I added a compiler-directive:
This is my WordWrap-Enabling-Procedure (TM) :-) The 'wwrs' e.g. are simply converted to numbers.
You may probably use the code only, where the 'PURE'-things are converted to integers.

Thanks to localhero, Shardik and the others!
Procedure Editor_Word_Wrap(Gadget)
#noErr = 0
Dim ControlTag.l(0)
Dim ControlData.l(0)
CompilerIf #PB_Compiler_Unicode = 0
Result = GetControlProperty(GadgetID(Gadget), 'PURE', 'TXOB', 4, 0, @TXNObject)
If Result = #noErr
ControlTag(0) = 'wwrs' ; kTXNWordWrapStateTag
ControlData(0) = 0 ; kTXNAutoWrap
TXNSetTXNObjectControls(TXNObject, #False, 1, @ControlTag(0), @ControlData(0))
EndIf
CompilerElse
Result = GetControlProperty(GadgetID(Gadget), 1347768901, 1415073602, 4, 0, @TXNObject)
If Result = #noErr
ControlTag(0) = 2004316787 ; kTXNWordWrapStateTag
ControlData(0) = 0 ; kTXNAutoWrap
TXNSetTXNObjectControls(TXNObject, #False, 1, @ControlTag(0), @ControlData(0))
EndIf
CompilerEndIf

EndProcedure
Regards,
JamiroKwai
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Setting wordwrap to auto in editor gadget

Post by Shardik »

jamirokwai wrote:as the snippet above is not Unicode-safe, I added a compiler-directive:
You are right: my code example above does not work if you compile a
Unicode program by selecting "Compiler/Compiler Options..." in the IDE
menu and enable "Create unicode executable". The explanation is simple:
The tags are always 4 characters which are stored in ASCII mode as a long
integer (4 Bytes). Due to the little-endian format in which Intel processors
store values in memory, the characters are stored in reversed order:

Code: Select all

PropertyCreator.L = 'PURE'
Debug PeekS(@PropertyCreator, 4) ; Displays "ERUP"
When trying to compile the above code (or my previous code example) with
the option "Create unicode executable" you obtain this error message:
PureBasic wrote:Line 1: Overflow error: a 'long' value (.l) must be between
-2147483648 and +4294967295.
In unicode mode each character takes two bytes, so 4x2 are 8 bytes which
don't fit into a long integer (4 bytes). If you declare PropertyCreator as a
quad value (PropertyCreator.Q) then the above code snippet will again work
correctly. But the utilized API functions await long integers, so this is no
solution. Therefore jamirokwai's approach is the correct one if you need
code that has to work in ASCII and Unicode mode: instead of using a string
of 4 characters simply use the resulting long integer value. And you even
don't need to work with CompilerIf because the usage of a long integer
works in ASCII and Unicode mode.

I therefore adapted my previous code example in this way and as a further
goodie added the possibility to switch the current word wrap mode during
runtime:

Code: Select all

; ----- Works in ASCII and Unicode mode!

ImportC ""
  GetControlProperty(ControlRef, PropertyCreator, PropertyTag, BufferSize, *ActualSize, *PropertyBuffer)
  TXNGetTXNObjectControls(TXNObject, ArrayItemCount, ControlTagsArray, ControlDataArray)
  TXNSetTXNObjectControls(TXNObject, ClearAll, ArrayItemCount, ControlTagsArray, ControlDataArray)
EndImport

#kTXNWordWrapStateTag = 2004316787 ; 'wwrs'

Procedure ToggleWordWrapMode(EditorGadgetID)
  Protected ControlRef
  Protected TXNObject
  Protected PropertyCreator = 1347768901 ; 'PURE'
  Protected PropertyTag     = 1415073602 ; 'TXOB'

  Dim ControlTag(0)
  Dim ControlData(0)

  ControlRef = GadgetID(EditorGadgetID)
  ControlTag(0)  = #kTXNWordWrapStateTag 

  If GetControlProperty(GadgetID(EditorGadgetID), PropertyCreator, PropertyTag, 4, 0, @TXNObject) = 0
    If TXNGetTXNObjectControls(TXNObject, 1, @ControlTag(0), @ControlData(0)) = 0
      ControlData(0) ! 1
      TXNSetTXNObjectControls(TXNObject, #False, 1, @ControlTag(0), @ControlData(0))
    EndIf
 EndIf
EndProcedure

OpenWindow(0, 200, 100, 450, 100, "MacOS X Word Wrap Test", #PB_Window_SystemMenu)
EditorGadget(0, 10, 10, 430, 55)
ButtonGadget(1, 160, 70, 140, 20, "Toggle Word Wrap")

For i = 1 To 5
  Text$ = Text$ + "This is a word wrap test - "
Next i

SetGadgetText(0, Text$)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 1
        ToggleWordWrapMode(0)
      EndIf
  EndSelect
ForEver
For those using jamirokwai's above posted procedure in his previous posting:
The procedure won't work until you insert the following import statements
into your code

Code: Select all

ImportC ""
  GetControlProperty(Control, PropertyCreator, PropertyTag, BufferSize, *ActualSize, *PropertyBuffer)
  TXNSetTXNObjectControls(TXNObject, ClearAll, ControlCount, ControlTags, ControlData)
EndImport
Post Reply